{"id":3235,"date":"2026-08-18T12:02:27","date_gmt":"2026-08-18T12:02:27","guid":{"rendered":"https:\/\/www.bare-digital.com\/ashe\/?page_id=3235"},"modified":"2026-08-18T12:43:28","modified_gmt":"2026-08-18T12:43:28","slug":"as-team-sales-funnel","status":"publish","type":"page","link":"https:\/\/www.bare-digital.com\/ashe\/as-team-sales-funnel\/","title":{"rendered":"AS Team Sales Funnel"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"3235\" class=\"elementor elementor-3235\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6d01574 e-con e-atomic-element e-flexbox-base e-default-div \" data-id=\"6d01574\" data-element_type=\"e-flexbox\" data-e-type=\"e-flexbox\" data-interaction-id=\"6d01574\" data-e-type=\"e-flexbox\" data-id=\"6d01574\">\n    \t\t\t<img fetchpriority=\"high\" decoding=\"async\" class=\"e-image-base e-default-img \" data-interaction-id=\"581e5d3\" data-e-type=\"widget\" data-id=\"581e5d3\" id=\"3237\" src=\"https:\/\/www.bare-digital.com\/ashe\/wp-content\/uploads\/2026\/08\/Sales-Funnel-2-scaled.png\" width=\"2560\" height=\"1280\" srcset=\"https:\/\/www.bare-digital.com\/ashe\/wp-content\/uploads\/2026\/08\/Sales-Funnel-2-scaled.png 2560w, https:\/\/www.bare-digital.com\/ashe\/wp-content\/uploads\/2026\/08\/Sales-Funnel-2-300x150.png 300w, https:\/\/www.bare-digital.com\/ashe\/wp-content\/uploads\/2026\/08\/Sales-Funnel-2-1024x512.png 1024w, https:\/\/www.bare-digital.com\/ashe\/wp-content\/uploads\/2026\/08\/Sales-Funnel-2-768x384.png 768w, https:\/\/www.bare-digital.com\/ashe\/wp-content\/uploads\/2026\/08\/Sales-Funnel-2-1536x768.png 1536w\" alt=\"\"\/>\t\t\n<\/div>\n<div class=\"elementor-element elementor-element-4c6f42d e-flex e-con-boxed e-con e-parent\" data-id=\"4c6f42d\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-b01ddd2 elementor-widget elementor-widget-html\" data-id=\"b01ddd2\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\r\n<!-- ============================================================\r\n     Sales Funnel Priority Tracker \u2014 accountant_she\r\n     Paste this ENTIRE block into a single Elementor \"HTML\" widget.\r\n     Do not wrap it in extra <html>\/<head>\/<body> tags \u2014 Elementor\r\n     already provides those. Requires the \"Sales Funnel Tracker\"\r\n     WordPress plugin to be installed and activated first.\r\n     ============================================================ -->\r\n<style>\r\n  #sft-app-embed, #sft-app-embed *{ box-sizing:border-box; }\r\n  #sft-app-embed{\r\n    --sft-magenta:#FF1A8C;\r\n    --sft-magenta-dark:#D4106F;\r\n    --sft-pink:#FFC2E3;\r\n    --sft-pink-soft:#FFF3F9;\r\n    --sft-plum:#675F6E;\r\n    --sft-text:#2b2630;\r\n    --sft-muted:#8a8391;\r\n    --sft-border:#ecdfe8;\r\n    --sft-status-red:#e0484d;\r\n    --sft-status-red-bg:#fdecec;\r\n    --sft-status-orange:#fe6b07;\r\n    --sft-status-orange-bg:#fff1e6;\r\n    --sft-status-green:#2f9e5b;\r\n    --sft-status-green-bg:#e9f7ee;\r\n    font-family:\"Open Sans\",\"Segoe UI\",Arial,sans-serif;\r\n    color:var(--sft-text);\r\n    max-width:100%;\r\n    width:100%;\r\n    margin:0;\r\n    padding:0;\r\n    text-align:left;\r\n  }\r\n  #sft-app-embed h1, #sft-app-embed h2, #sft-app-embed h3{\r\n    font-family:\"Lora\", Georgia, serif;\r\n    margin:0;\r\n  }\r\n  #sft-app-embed button{ font-family:inherit; cursor:pointer; -webkit-appearance:none; appearance:none; }\r\n  #sft-app-embed input:not([type=\"checkbox\"]), #sft-app-embed select, #sft-app-embed textarea{\r\n    font-family:inherit; -webkit-appearance:none; appearance:none;\r\n  }\r\n  #sft-app-embed p{ margin:0 0 .6em; }\r\n\r\n  #sft-app-embed .sft-top{\r\n    background:var(--sft-plum);\r\n    color:#fff;\r\n    padding:24px clamp(16px,4vw,32px);\r\n    border-radius:14px 14px 0 0;\r\n    position:relative;\r\n  }\r\n  #sft-app-embed .sft-collapse-toggle{\r\n    position:absolute;\r\n    top:20px;\r\n    right:clamp(16px,4vw,32px);\r\n    background:rgba(255,255,255,.15);\r\n    color:#fff;\r\n    border:1px solid rgba(255,255,255,.4);\r\n    padding:7px 14px;\r\n    border-radius:20px;\r\n    font-size:1.5rem;\r\n    font-weight:700;\r\n    cursor:pointer;\r\n    font-family:\"Open Sans\",\"Segoe UI\",Arial,sans-serif;\r\n  }\r\n  #sft-app-embed .sft-collapse-toggle:hover{ background:rgba(255,255,255,.25); }\r\n  #sft-app-embed .sft-signout-link{\r\n    position:absolute;\r\n    top:82px;\r\n    right:clamp(16px,4vw,32px);\r\n    background:none;\r\n    border:none;\r\n    color:#f3e9f0;\r\n    font-size:1.5rem;\r\n    text-decoration:underline;\r\n    cursor:pointer;\r\n    font-family:\"Open Sans\",\"Segoe UI\",Arial,sans-serif;\r\n  }\r\n  #sft-app-embed .sft-signout-link:hover{ color:#fff; }\r\n  #sft-app-embed .sft-logo-banner{\r\n    display:inline-block;\r\n    background:var(--sft-magenta);\r\n    color:#fff;\r\n    font-family:\"Lora\", Georgia, serif;\r\n    font-weight:700;\r\n    letter-spacing:.08em;\r\n    padding:6px 16px;\r\n    border-radius:4px;\r\n    font-size:.9rem;\r\n    margin-bottom:12px;\r\n  }\r\n  #sft-app-embed .sft-top h1{ font-size:1.5rem; color:#fff; }\r\n  #sft-app-embed .sft-top p{ margin:6px 0 0; color:#f3e9f0; font-size:.92rem; max-width:640px; }\r\n\r\n  #sft-app-embed .sft-wrap{ width:100%; padding:22px clamp(16px,4vw,32px) 40px; background:#fff; border-radius:0 0 14px 14px; border:1px solid var(--sft-border); border-top:none; }\r\n\r\n  #sft-app-embed .sft-demo-banner{\r\n    background:#fff4d6; border:1px solid #e8c766; color:#5c4813;\r\n    padding:10px 14px; border-radius:10px; font-size:.85rem; margin-bottom:16px;\r\n  }\r\n  #sft-app-embed .sft-error-banner{\r\n    background:var(--sft-status-red-bg); border:1px solid var(--sft-status-red); color:var(--sft-status-red);\r\n    padding:10px 14px; border-radius:10px; font-size:.85rem; margin-bottom:16px;\r\n  }\r\n\r\n  #sft-app-embed .sft-view-tabs{ display:flex; gap:8px; margin-bottom:18px; flex-wrap:wrap; }\r\n  #sft-app-embed .sft-view-tab{\r\n    border:2px solid var(--sft-border); background:#fff; padding:9px 18px; border-radius:24px;\r\n    font-size:.9rem; font-weight:700; color:var(--sft-plum);\r\n  }\r\n  #sft-app-embed .sft-view-tab.sft-active{ background:var(--sft-plum); border-color:var(--sft-plum); color:#fff; }\r\n\r\n  #sft-app-embed .sft-toolbar{ display:flex; justify-content:space-between; align-items:center; margin-bottom:14px; gap:10px; flex-wrap:wrap; }\r\n  #sft-app-embed .sft-toolbar-left{ display:flex; gap:8px; flex-wrap:wrap; }\r\n\r\n  #sft-app-embed .sft-btn-primary{ background:var(--sft-magenta); color:#fff; border:none; padding:10px 18px; border-radius:8px; font-size:.9rem; font-weight:700; }\r\n  #sft-app-embed .sft-btn-primary:hover{ background:var(--sft-magenta-dark); }\r\n  #sft-app-embed .sft-btn-secondary{ background:var(--sft-plum); color:#fff; border:none; padding:10px 16px; border-radius:8px; font-size:.88rem; font-weight:700; }\r\n  #sft-app-embed .sft-btn-secondary:hover{ background:#544d60; }\r\n  #sft-app-embed .sft-btn-ghost{ background:#fff; border:1px solid var(--sft-border); padding:9px 16px; border-radius:8px; font-size:.88rem; color:var(--sft-text); }\r\n  #sft-app-embed .sft-btn-ghost:hover{ background:var(--sft-pink-soft); }\r\n  #sft-app-embed .sft-icon-btn{ background:none; border:none; padding:4px 6px; font-size:1rem; color:var(--sft-muted); border-radius:6px; }\r\n  #sft-app-embed .sft-icon-btn:hover{ background:var(--sft-pink-soft); color:var(--sft-text); }\r\n\r\n  #sft-app-embed .sft-info-toggle{ font-size:.78rem; color:var(--sft-magenta); text-decoration:underline; background:none; border:none; padding:0; }\r\n  #sft-app-embed .sft-info-box{ font-size:.82rem; color:var(--sft-plum); background:var(--sft-pink-soft); border-radius:8px; padding:12px 14px; margin:10px 0 16px; line-height:1.55; display:none; }\r\n  #sft-app-embed .sft-info-box.sft-open{ display:block; }\r\n\r\n  #sft-app-embed .sft-filters{\r\n    display:flex; flex-wrap:wrap; gap:16px; background:#fff; border:1px solid var(--sft-border);\r\n    border-radius:12px; padding:14px 16px; margin-bottom:18px;\r\n  }\r\n  #sft-app-embed .sft-filter-group{ display:flex; flex-direction:column; gap:6px; }\r\n  #sft-app-embed .sft-filter-label{ font-size:.7rem; text-transform:uppercase; letter-spacing:.05em; color:var(--sft-muted); font-weight:700; }\r\n  #sft-app-embed .sft-chip-row{ display:flex; flex-wrap:wrap; gap:6px; }\r\n  #sft-app-embed .sft-chip{ border:1px solid var(--sft-border); background:#fff; padding:6px 12px; border-radius:20px; font-size:.78rem; color:var(--sft-text); }\r\n  #sft-app-embed .sft-chip.sft-selected{ background:var(--sft-plum); color:#fff; border-color:var(--sft-plum); }\r\n  #sft-app-embed .sft-sort-select{ border:1px solid var(--sft-border); border-radius:8px; padding:7px 10px; font-size:.8rem; background:#fff; }\r\n\r\n  #sft-app-embed .sft-task-list{ display:flex; flex-direction:column; gap:10px; }\r\n  #sft-app-embed .sft-task-card{\r\n    background:#fff; border:1px solid var(--sft-border); border-left:6px solid var(--sft-border);\r\n    border-radius:10px; padding:14px 16px; display:flex; gap:12px; align-items:flex-start;\r\n  }\r\n  #sft-app-embed .sft-task-card.sft-completed{ opacity:.55; }\r\n  #sft-app-embed .sft-task-card.sft-completed .sft-task-title{ text-decoration:line-through; }\r\n  #sft-app-embed .sft-checkbox-wrap{ padding-top:2px; }\r\n  #sft-app-embed .sft-checkbox-wrap input[type=\"checkbox\"]{\r\n    -webkit-appearance:none;\r\n    appearance:none;\r\n    width:20px;\r\n    height:20px;\r\n    margin:0;\r\n    cursor:pointer;\r\n    border:2px solid var(--sft-border);\r\n    border-radius:5px;\r\n    background:#fff;\r\n    position:relative;\r\n    flex-shrink:0;\r\n  }\r\n  #sft-app-embed .sft-checkbox-wrap input[type=\"checkbox\"]:hover{ border-color:var(--sft-plum); }\r\n  #sft-app-embed .sft-checkbox-wrap input[type=\"checkbox\"]:checked{\r\n    background:var(--sft-status-green);\r\n    border-color:var(--sft-status-green);\r\n  }\r\n  #sft-app-embed .sft-checkbox-wrap input[type=\"checkbox\"]:checked::after{\r\n    content:\"\";\r\n    position:absolute;\r\n    left:6px;\r\n    top:2px;\r\n    width:5px;\r\n    height:10px;\r\n    border:solid #fff;\r\n    border-width:0 2px 2px 0;\r\n    transform:rotate(45deg);\r\n  }\r\n  #sft-app-embed .sft-task-main{ flex:1; min-width:0; }\r\n  #sft-app-embed .sft-task-title{ font-weight:700; font-size:.98rem; margin:0 0 3px; font-family:inherit; }\r\n  #sft-app-embed .sft-task-notes{ font-size:.83rem; color:var(--sft-muted); margin:0 0 8px; }\r\n  #sft-app-embed .sft-badge-row{ display:flex; flex-wrap:wrap; gap:6px; align-items:center; }\r\n  #sft-app-embed .sft-badge{ font-size:.72rem; padding:3px 9px; border-radius:12px; font-weight:700; white-space:nowrap; display:inline-flex; align-items:center; gap:4px; }\r\n  #sft-app-embed .sft-badge-on{ background:var(--sft-status-green-bg); color:var(--sft-status-green); }\r\n  #sft-app-embed .sft-badge-off{ background:#f1eef2; color:#aba3ae; }\r\n  #sft-app-embed .sft-badge-effort{ background:var(--sft-pink-soft); color:var(--sft-plum); }\r\n  #sft-app-embed .sft-badge-due{ background:var(--sft-status-red-bg); color:var(--sft-status-red); }\r\n  #sft-app-embed .sft-badge-due.sft-ok{ background:var(--sft-pink-soft); color:var(--sft-plum); }\r\n  #sft-app-embed .sft-badge-owner{ background:var(--sft-plum); color:#fff; padding:2px 10px 2px 2px; }\r\n  #sft-app-embed .sft-badge-added{ background:#f1eef2; color:var(--sft-muted); }\r\n\r\n  #sft-app-embed .sft-avatar{ border-radius:50%; object-fit:cover; display:inline-flex; align-items:center; justify-content:center; font-size:.68rem; color:#fff; font-weight:700; flex-shrink:0; }\r\n\r\n  #sft-app-embed .sft-empty-state{ text-align:center; color:var(--sft-muted); padding:36px 20px; font-size:.9rem; }\r\n  #sft-app-embed #sftCompletedToggle{ font-size:.85rem; color:var(--sft-magenta); background:none; border:none; text-decoration:underline; padding:0; margin:26px 0 10px; display:block; }\r\n  #sft-app-embed #sftCompletedList{ display:none; flex-direction:column; gap:8px; }\r\n  #sft-app-embed #sftCompletedList.sft-open{ display:flex; }\r\n\r\n  #sft-app-embed #sftGate{ background:var(--sft-plum); border-radius:14px; display:flex; align-items:center; justify-content:center; padding:50px 20px; }\r\n  #sft-app-embed #sftGate .sft-box{ background:#fff; padding:32px 30px; border-radius:12px; width:320px; max-width:100%; text-align:center; }\r\n  #sft-app-embed #sftGate h2{ margin:0 0 8px; font-size:1.1rem; color:var(--sft-plum); }\r\n  #sft-app-embed #sftGate p{ font-size:.82rem; color:var(--sft-muted); margin:0 0 16px; }\r\n  #sft-app-embed #sftGate input{ width:100%; padding:10px; border:1px solid var(--sft-border); border-radius:8px; margin-bottom:12px; font-size:.95rem; text-align:center; }\r\n  #sft-app-embed #sftGateError{ color:var(--sft-status-red); font-size:.8rem; height:16px; margin-bottom:6px; }\r\n\r\n  #sft-app-embed .sft-overlay{ position:fixed; inset:0; background:rgba(40,20,35,.55); display:flex; align-items:center; justify-content:center; z-index:99999; padding:20px; }\r\n  #sft-app-embed .sft-modal{ background:#fff; border-radius:14px; padding:30px 28px; width:460px; max-width:100%; position:relative; max-height:88vh; overflow-y:auto; }\r\n  #sft-app-embed .sft-modal-wide{ width:640px; }\r\n  #sft-app-embed .sft-modal-close{ position:absolute; top:14px; right:16px; background:none; border:none; font-size:1.1rem; color:var(--sft-muted); }\r\n  #sft-app-embed .sft-modal-close:hover{ color:var(--sft-text); }\r\n  #sft-app-embed .sft-modal h2{ margin:0 0 16px; font-size:1.1rem; color:var(--sft-plum); }\r\n\r\n  #sft-app-embed .sft-step-progress{ font-size:.72rem; text-transform:uppercase; letter-spacing:.06em; color:var(--sft-muted); font-weight:700; margin-bottom:10px; }\r\n  #sft-app-embed .sft-step-prompt{ font-size:1.15rem; font-weight:700; margin:0 0 20px; color:var(--sft-text); font-family:\"Lora\", Georgia, serif; }\r\n  #sft-app-embed .sft-yn-row{ display:flex; gap:12px; margin-bottom:8px; }\r\n  #sft-app-embed .sft-yn-big{ flex:1; padding:18px 10px; border:2px solid var(--sft-border); border-radius:10px; background:#fff; font-size:1rem; font-weight:700; color:var(--sft-muted); }\r\n  #sft-app-embed .sft-yn-big:hover{ border-color:var(--sft-plum); }\r\n  #sft-app-embed .sft-yn-big.sft-picked-yes{ border-color:var(--sft-status-green); background:var(--sft-status-green-bg); color:var(--sft-status-green); }\r\n  #sft-app-embed .sft-yn-big.sft-picked-no{ border-color:var(--sft-plum); background:#f1eef2; color:var(--sft-plum); }\r\n  #sft-app-embed .sft-choice-col{ display:flex; flex-direction:column; gap:10px; margin-bottom:8px; }\r\n  #sft-app-embed .sft-choice-btn{ padding:14px 16px; border:2px solid var(--sft-border); border-radius:10px; background:#fff; font-size:.94rem; font-weight:600; text-align:left; color:var(--sft-text); }\r\n  #sft-app-embed .sft-choice-btn:hover{ border-color:var(--sft-plum); }\r\n  #sft-app-embed .sft-choice-btn.sft-picked{ border-color:var(--sft-magenta); background:var(--sft-pink-soft); color:var(--sft-magenta-dark); }\r\n  #sft-app-embed .sft-wizard-input{ width:100%; padding:11px 12px; border:1px solid var(--sft-border); border-radius:8px; font-size:.95rem; margin-bottom:8px; background:#fff; color:var(--sft-text); }\r\n  #sft-app-embed .sft-wizard-actions{ display:flex; justify-content:space-between; margin-top:22px; }\r\n  #sft-app-embed .sft-review-row{ display:flex; justify-content:space-between; padding:8px 0; border-bottom:1px solid var(--sft-border); font-size:.88rem; gap:12px; }\r\n  #sft-app-embed .sft-review-row:last-of-type{ border-bottom:none; }\r\n  #sft-app-embed .sft-review-score{ text-align:center; padding:16px; border-radius:10px; margin-bottom:14px; }\r\n  #sft-app-embed .sft-review-score .sft-score-num{ font-size:2.2rem; font-weight:800; font-family:\"Lora\", Georgia, serif; }\r\n  #sft-app-embed .sft-review-score .sft-score-label{ font-size:.85rem; font-weight:700; text-transform:uppercase; letter-spacing:.04em; }\r\n\r\n  #sft-app-embed .sft-team-row{ display:flex; align-items:center; gap:10px; margin-bottom:12px; }\r\n  #sft-app-embed .sft-team-row input{ flex:1; padding:8px 10px; border:1px solid var(--sft-border); border-radius:8px; font-size:.85rem; }\r\n  #sft-app-embed .sft-form-row{ display:flex; gap:8px; margin-top:14px; }\r\n  #sft-app-embed .sft-form-row input{ flex:1; padding:9px 11px; border:1px solid var(--sft-border); border-radius:8px; }\r\n  #sft-app-embed .sft-form-actions{ display:flex; gap:10px; margin-top:16px; flex-wrap:wrap; }\r\n\r\n  #sft-app-embed .sft-diary-owner-block{ margin-bottom:20px; }\r\n  #sft-app-embed .sft-diary-owner-block h3{ margin:0 0 8px; font-size:.95rem; color:var(--sft-plum); }\r\n  #sft-app-embed .sft-diary-item{ font-size:.85rem; padding:8px 0; border-bottom:1px solid var(--sft-border); }\r\n  #sft-app-embed .sft-diary-item:last-child{ border-bottom:none; }\r\n  #sft-app-embed .sft-diary-when{ color:var(--sft-muted); font-size:.8rem; }\r\n\r\n  #sft-app-embed .sft-review-section{ margin-bottom:26px; }\r\n  #sft-app-embed .sft-review-section h3{ font-size:1.02rem; color:var(--sft-plum); margin-bottom:10px; display:flex; align-items:center; gap:8px; }\r\n  #sft-app-embed .sft-review-section .sft-review-sub{ font-size:.78rem; color:var(--sft-muted); font-weight:400; font-family:\"Open Sans\",sans-serif; }\r\n  #sft-app-embed .sft-mini-row{ display:flex; align-items:center; gap:10px; padding:9px 12px; border:1px solid var(--sft-border); border-radius:9px; margin-bottom:6px; background:#fff; }\r\n  #sft-app-embed .sft-mini-row .sft-mini-title{ flex:1; font-size:.88rem; font-weight:600; }\r\n  #sft-app-embed .sft-mini-row .sft-mini-meta{ font-size:.76rem; color:var(--sft-muted); white-space:nowrap; }\r\n\r\n  @media(max-width:640px){\r\n    #sft-app-embed .sft-modal{ width:100%; padding:24px 18px; }\r\n    #sft-app-embed .sft-top, #sft-app-embed .sft-wrap{ padding-left:16px; padding-right:16px; }\r\n  }\r\n<\/style>\r\n\r\n<div id=\"sft-app-embed\">\r\n\r\n  <div id=\"sftGate\">\r\n    <div class=\"sft-box\">\r\n      <h2>\ud83d\udea6 Sales Funnel Priority Tracker<\/h2>\r\n      <p>Enter your personal passcode to continue.<\/p>\r\n      <input id=\"sftGateInput\" type=\"password\" placeholder=\"Your passcode\" \/>\r\n      <div id=\"sftGateError\"><\/div>\r\n      <button class=\"sft-btn-primary\" style=\"width:100%\" onclick=\"sftTryUnlock()\">Enter<\/button>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <div id=\"sftApp\" style=\"display:none;\">\r\n    <header class=\"sft-top\">\r\n      <button type=\"button\" class=\"sft-collapse-toggle\" id=\"sftCollapseToggle\" onclick=\"sftToggleCollapse()\">\u2303 Collapse<\/button>\r\n      <button type=\"button\" class=\"sft-signout-link\" onclick=\"sftSignOut()\">Sign out<\/button>\r\n      <div class=\"sft-logo-banner\">@accountant_she<\/div>\r\n      <h1>\ud83d\udea6 Sales Funnel Priority Tracker<\/h1>\r\n      <p>Every idea for improving the funnel, scored 1\u201310 by impact and urgency, with a diary plan and a Monday morning review.<\/p>\r\n    <\/header>\r\n\r\n    <div class=\"sft-wrap\" id=\"sftWrapBody\">\r\n      <div id=\"sftErrorBanner\" class=\"sft-error-banner\" style=\"display:none;\"><\/div>\r\n\r\n      <div class=\"sft-view-tabs\">\r\n        <button class=\"sft-view-tab sft-active\" id=\"sftTabList\" onclick=\"switchView('list')\">\ud83d\udccb Task List<\/button>\r\n        <button class=\"sft-view-tab\" id=\"sftTabReview\" onclick=\"switchView('review')\">\u2615 Monday Review<\/button>\r\n      <\/div>\r\n\r\n      <div id=\"sftListView\">\r\n        <div class=\"sft-toolbar\">\r\n          <div class=\"sft-toolbar-left\">\r\n            <button class=\"sft-btn-primary\" onclick=\"openWizard()\">+ Add a task<\/button>\r\n            <button class=\"sft-btn-secondary\" onclick=\"openDiaryModal()\">\ud83d\udce4 Diary plan<\/button>\r\n            <button class=\"sft-btn-secondary\" onclick=\"exportAllTasksCsv()\">\u2b07 Export tasks<\/button>\r\n            <button class=\"sft-btn-secondary\" onclick=\"openImportModal()\">\u2b06 Bulk import<\/button>\r\n            <button class=\"sft-btn-ghost\" onclick=\"openTeamModal()\">\ud83d\udc65 Manage team<\/button>\r\n          <\/div>\r\n          <button class=\"sft-info-toggle\" onclick=\"sftToggleInfo()\">How is this scored? \u24d8<\/button>\r\n        <\/div>\r\n\r\n        <div class=\"sft-info-box\" id=\"sftInfoBox\">\r\n          <strong>Score (1\u201310):<\/strong> revenue (weighted low\/medium\/high), plus data value, plus community value, plus how urgent the due date is (if time sensitive), plus a small bonus for quick wins.<br\/>\r\n          <strong>\ud83d\udfe2 1\u20133 Low priority<\/strong> \u00b7 <strong>\ud83d\udfe0 4\u20137 Medium priority<\/strong> \u00b7 <strong>\ud83d\udd34 8\u201310 High priority<\/strong> \u2014 the list is sorted highest priority first.<br\/>\r\n          <strong>Diary plan:<\/strong> High priority \u2192 do within 5 working days. Medium \u2192 5\u201310 working days. Low \u2192 10+ working days. Dates skip weekends automatically.\r\n        <\/div>\r\n\r\n        <div class=\"sft-filters\">\r\n          <div class=\"sft-filter-group\">\r\n            <span class=\"sft-filter-label\">Responsible<\/span>\r\n            <div class=\"sft-chip-row\" id=\"sftOwnerFilters\"><\/div>\r\n          <\/div>\r\n          <div class=\"sft-filter-group\">\r\n            <span class=\"sft-filter-label\">Time I have<\/span>\r\n            <div class=\"sft-chip-row\" id=\"sftEffortFilters\">\r\n              <button class=\"sft-chip sft-selected\" data-val=\"all\" onclick=\"sftSetEffortFilter('all')\">All<\/button>\r\n              <button class=\"sft-chip\" data-val=\"quick\" onclick=\"sftSetEffortFilter('quick')\">\u26a1 Quick (&lt;10 min)<\/button>\r\n              <button class=\"sft-chip\" data-val=\"task\" onclick=\"sftSetEffortFilter('task')\">\ud83d\udd50 Task (&lt;1 hr)<\/button>\r\n              <button class=\"sft-chip\" data-val=\"project\" onclick=\"sftSetEffortFilter('project')\">\ud83d\udcc1 Project (1 hr+)<\/button>\r\n            <\/div>\r\n          <\/div>\r\n          <div class=\"sft-filter-group\">\r\n            <span class=\"sft-filter-label\">Priority<\/span>\r\n            <div class=\"sft-chip-row\" id=\"sftPriorityFilters\">\r\n              <button class=\"sft-chip sft-selected\" data-val=\"all\" onclick=\"sftSetPriorityFilter('all')\">All<\/button>\r\n              <button class=\"sft-chip\" data-val=\"red\" onclick=\"sftSetPriorityFilter('red')\">\ud83d\udd34 High<\/button>\r\n              <button class=\"sft-chip\" data-val=\"orange\" onclick=\"sftSetPriorityFilter('orange')\">\ud83d\udfe0 Medium<\/button>\r\n              <button class=\"sft-chip\" data-val=\"green\" onclick=\"sftSetPriorityFilter('green')\">\ud83d\udfe2 Low<\/button>\r\n            <\/div>\r\n          <\/div>\r\n          <div class=\"sft-filter-group\">\r\n            <span class=\"sft-filter-label\">Revenue impact<\/span>\r\n            <div class=\"sft-chip-row\" id=\"sftRevenueFilters\">\r\n              <button class=\"sft-chip sft-selected\" data-val=\"all\" onclick=\"sftSetRevenueFilter('all')\">All<\/button>\r\n              <button class=\"sft-chip\" data-val=\"high\" onclick=\"sftSetRevenueFilter('high')\">\ud83d\udcb0 High<\/button>\r\n              <button class=\"sft-chip\" data-val=\"medium\" onclick=\"sftSetRevenueFilter('medium')\">\ud83d\udcb0 Medium<\/button>\r\n              <button class=\"sft-chip\" data-val=\"low\" onclick=\"sftSetRevenueFilter('low')\">\ud83d\udcb0 Low<\/button>\r\n              <button class=\"sft-chip\" data-val=\"none\" onclick=\"sftSetRevenueFilter('none')\">No revenue<\/button>\r\n            <\/div>\r\n          <\/div>\r\n          <div class=\"sft-filter-group\">\r\n            <span class=\"sft-filter-label\">Sort by<\/span>\r\n            <select class=\"sft-sort-select\" id=\"sftSortSelect\" onchange=\"sftSetSort(this.value)\">\r\n              <option value=\"priority\">Priority score<\/option>\r\n              <option value=\"revenue\">Revenue potential<\/option>\r\n              <option value=\"due\">Soonest due date<\/option>\r\n            <\/select>\r\n          <\/div>\r\n        <\/div>\r\n\r\n        <div class=\"sft-task-list\" id=\"sftTaskList\"><\/div>\r\n        <div class=\"sft-empty-state\" id=\"sftEmptyState\" style=\"display:none;\">No tasks match these filters yet.<\/div>\r\n\r\n        <button id=\"sftCompletedToggle\" onclick=\"sftToggleCompleted()\">Show completed (<span id=\"sftCompletedCount\">0<\/span>)<\/button>\r\n        <div class=\"sft-task-list\" id=\"sftCompletedList\"><\/div>\r\n      <\/div>\r\n\r\n      <div id=\"sftReviewView\" style=\"display:none;\"><\/div>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <!-- Wizard modal -->\r\n  <div id=\"sftWizardOverlay\" class=\"sft-overlay\" style=\"display:none;\">\r\n    <div class=\"sft-modal\">\r\n      <button class=\"sft-modal-close\" onclick=\"closeWizard()\">\u2715<\/button>\r\n      <div id=\"sftWizardBody\"><\/div>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <!-- Manage team modal -->\r\n  <div id=\"sftTeamOverlay\" class=\"sft-overlay\" style=\"display:none;\">\r\n    <div class=\"sft-modal\">\r\n      <button class=\"sft-modal-close\" onclick=\"closeTeamModal()\">\u2715<\/button>\r\n      <h2>\ud83d\udc65 Manage team<\/h2>\r\n      <p style=\"font-size:.82rem;color:var(--sft-muted);margin-top:-8px;\">Paste a photo URL for each person (upload the photo to your WordPress media library first, then paste its link here) to show a circular photo instead of initials.<\/p>\r\n      <div id=\"sftTeamList\"><\/div>\r\n      <div class=\"sft-form-row\">\r\n        <input type=\"text\" id=\"sftNewMemberName\" placeholder=\"New team member name\" \/>\r\n        <button class=\"sft-btn-primary\" onclick=\"handleAddMember()\">+ Add<\/button>\r\n      <\/div>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <!-- Diary export modal -->\r\n  <div id=\"sftDiaryOverlay\" class=\"sft-overlay\" style=\"display:none;\">\r\n    <div class=\"sft-modal sft-modal-wide\">\r\n      <button class=\"sft-modal-close\" onclick=\"closeDiaryModal()\">\u2715<\/button>\r\n      <h2>\ud83d\udce4 Diary plan<\/h2>\r\n      <div id=\"sftDiaryContent\"><\/div>\r\n      <div class=\"sft-form-actions\">\r\n        <button class=\"sft-btn-primary\" onclick=\"downloadDiaryCsv()\">\u2b07 Download CSV<\/button>\r\n        <button class=\"sft-btn-ghost\" onclick=\"copyDiaryText()\">\ud83d\udccb Copy to clipboard<\/button>\r\n      <\/div>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <!-- Bulk import modal -->\r\n  <div id=\"sftImportOverlay\" class=\"sft-overlay\" style=\"display:none;\">\r\n    <div class=\"sft-modal sft-modal-wide\">\r\n      <button class=\"sft-modal-close\" onclick=\"closeImportModal()\">\u2715<\/button>\r\n      <h2>\u2b06 Bulk import tasks<\/h2>\r\n      <p style=\"font-size:.85rem;color:var(--sft-muted);margin-top:-8px;\">Add several ideas at once from a CSV file. Each row becomes one task, scored exactly the same as if you had added it through the wizard.<\/p>\r\n      <div class=\"sft-form-actions\" style=\"margin-top:0;\">\r\n        <button class=\"sft-btn-ghost\" onclick=\"downloadImportTemplate()\">\u2b07 Download CSV template<\/button>\r\n      <\/div>\r\n      <div style=\"margin:16px 0;\">\r\n        <input type=\"file\" accept=\".csv,text\/csv\" id=\"sftImportFileInput\" onchange=\"handleImportFile(this)\" \/>\r\n        <div id=\"sftImportFileName\" style=\"font-size:.8rem;color:var(--sft-muted);margin-top:6px;\"><\/div>\r\n      <\/div>\r\n      <div id=\"sftImportPreview\" style=\"max-height:280px;overflow-y:auto;\"><\/div>\r\n      <div class=\"sft-form-actions\">\r\n        <button class=\"sft-btn-primary\" id=\"sftImportConfirmBtn\" onclick=\"confirmImport()\" disabled>Import tasks<\/button>\r\n        <button class=\"sft-btn-ghost\" onclick=\"closeImportModal()\">Cancel<\/button>\r\n      <\/div>\r\n    <\/div>\r\n  <\/div>\r\n\r\n<\/div>\r\n\r\n<script>\r\n(function(){\r\n\/* ============================================================\r\n   1. CONFIG \/ API CLIENT\r\n   ============================================================ *\/\r\n\/* The site's REST API can live under a sub-folder (e.g. \/ashe\/wp-json\/...)\r\n   rather than at the domain root, depending on how WordPress is installed.\r\n   WordPress prints a <link rel=\"https:\/\/api.w.org\/\"> tag in every page's\r\n   <head> pointing at its own real API root, so we read that instead of\r\n   assuming the root path. SFT_API_FALLBACK is only used if that tag can't\r\n   be found for some reason; update it if the site's folder ever changes. *\/\r\nvar SFT_API_FALLBACK = '\/ashe\/wp-json\/sft\/v1';\r\nvar SFT_API = (function(){\r\n  try {\r\n    var link = document.querySelector('link[rel=\"https:\/\/api.w.org\/\"]');\r\n    if (link && link.href) {\r\n      return link.href.replace(\/\\\/$\/, '') + '\/sft\/v1';\r\n    }\r\n  } catch (e) {}\r\n  return SFT_API_FALLBACK;\r\n})();\r\nvar SFT_KEY = null;\r\nvar DEFAULT_MEMBERS = [\r\n  { name: \"Rachel\", photoUrl: \"\" },\r\n  { name: \"Rebecca\", photoUrl: \"\" },\r\n  { name: \"Tamzin\", photoUrl: \"\" }\r\n];\r\n\r\nfunction sftHeaders(){\r\n  return { 'Content-Type': 'application\/json', 'X-Sft-Key': SFT_KEY || '' };\r\n}\r\n\/* Some hosting setups strip custom headers like X-Sft-Key before the\r\n   request reaches WordPress. The passcode is also sent as a ?key= query\r\n   parameter (which the plugin's REST API accepts as a fallback), since\r\n   that's what reliably gets through. Headers are left in place too, in\r\n   case a given host handles them fine. *\/\r\nfunction sftUrl(path){\r\n  var sep = path.indexOf('?') === -1 ? '?' : '&';\r\n  return SFT_API + path + sep + 'key=' + encodeURIComponent(SFT_KEY || '');\r\n}\r\nfunction showError(msg){\r\n  var el = document.getElementById('sftErrorBanner');\r\n  if (!el) return;\r\n  el.textContent = msg;\r\n  el.style.display = msg ? 'block' : 'none';\r\n}\r\nfunction apiGetTasks(){\r\n  return fetch(sftUrl('\/tasks'), { headers: sftHeaders() }).then(function(res){\r\n    if (!res.ok) throw new Error('Could not load tasks (status ' + res.status + ')');\r\n    return res.json();\r\n  });\r\n}\r\nfunction apiCreateTask(data){\r\n  return fetch(sftUrl('\/tasks'), { method:'POST', headers: sftHeaders(), body: JSON.stringify(data) }).then(function(res){\r\n    if (!res.ok) throw new Error('Could not save the task');\r\n    return res.json();\r\n  });\r\n}\r\nfunction apiUpdateTask(id, data){\r\n  return fetch(sftUrl('\/tasks\/' + id), { method:'PUT', headers: sftHeaders(), body: JSON.stringify(data) }).then(function(res){\r\n    if (!res.ok) throw new Error('Could not update the task');\r\n    return res.json();\r\n  });\r\n}\r\nfunction apiDeleteTask(id){\r\n  return fetch(sftUrl('\/tasks\/' + id), { method:'DELETE', headers: sftHeaders() }).then(function(res){\r\n    if (!res.ok) throw new Error('Could not delete the task');\r\n    return res.json();\r\n  });\r\n}\r\nfunction apiGetMembers(){\r\n  return fetch(sftUrl('\/members'), { headers: sftHeaders() }).then(function(res){\r\n    if (!res.ok) throw new Error('Could not load team members');\r\n    return res.json();\r\n  });\r\n}\r\nfunction apiSaveMembers(arr){\r\n  return fetch(sftUrl('\/members'), { method:'POST', headers: sftHeaders(), body: JSON.stringify(arr) }).then(function(res){\r\n    if (!res.ok) throw new Error('Could not save team members');\r\n    return res.json();\r\n  });\r\n}\r\n\r\n\/* ============================================================\r\n   2. GATE\r\n   ============================================================ *\/\r\nfunction sftTryUnlock(){\r\n  var val = document.getElementById('sftGateInput').value.trim();\r\n  var errEl = document.getElementById('sftGateError');\r\n  errEl.textContent = 'Checking...';\r\n  SFT_KEY = val;\r\n  fetch(sftUrl('\/tasks'), { headers: sftHeaders() }).then(function(res){\r\n    if (res.ok){\r\n      try { localStorage.setItem('sftKey', val); } catch(e){}\r\n      document.getElementById('sftGate').style.display = 'none';\r\n      document.getElementById('sftApp').style.display = 'block';\r\n      errEl.textContent = '';\r\n      initApp();\r\n    } else {\r\n      errEl.textContent = 'Wrong passcode, try again.';\r\n    }\r\n  }).catch(function(){\r\n    errEl.textContent = 'Could not reach the tracker database. Check the Sales Funnel Tracker plugin is active.';\r\n  });\r\n}\r\ndocument.getElementById('sftGateInput').addEventListener('keydown', function(e){\r\n  if (e.key === 'Enter') sftTryUnlock();\r\n});\r\n\r\n(function tryAutoUnlock(){\r\n  var saved = null;\r\n  try { saved = localStorage.getItem('sftKey'); } catch(e){}\r\n  if (!saved) return;\r\n  SFT_KEY = saved;\r\n  fetch(sftUrl('\/tasks'), { headers: sftHeaders() }).then(function(res){\r\n    if (res.ok){\r\n      document.getElementById('sftGate').style.display = 'none';\r\n      document.getElementById('sftApp').style.display = 'block';\r\n      initApp();\r\n    }\r\n  }).catch(function(){ \/* stay on gate *\/ });\r\n})();\r\n\r\n\/* ============================================================\r\n   3. APP STATE\r\n   ============================================================ *\/\r\nvar allTasks = [];\r\nvar members = DEFAULT_MEMBERS.slice();\r\nvar ownerFilter = 'all';\r\nvar effortFilter = 'all';\r\nvar priorityFilter = 'all';\r\nvar revenueFilter = 'all';\r\nvar sortMode = 'priority';\r\nvar completedOpen = false;\r\nvar currentView = 'list';\r\nvar pollTimer = null;\r\n\r\nfunction initApp(){\r\n  refreshAll();\r\n  if (pollTimer) clearInterval(pollTimer);\r\n  pollTimer = setInterval(refreshAll, 8000);\r\n}\r\n\r\nfunction refreshAll(){\r\n  Promise.all([apiGetTasks(), apiGetMembers()]).then(function(results){\r\n    allTasks = results[0] || [];\r\n    members = (results[1] && results[1].length) ? results[1] : DEFAULT_MEMBERS.slice();\r\n    showError('');\r\n    renderOwnerFilters();\r\n    if (currentView === 'list') { renderAll(); } else { renderMondayReview(); }\r\n  }).catch(function(err){\r\n    showError('Could not refresh from the tracker database: ' + err.message);\r\n  });\r\n}\r\n\r\nfunction switchView(view){\r\n  currentView = view;\r\n  document.getElementById('sftTabList').classList.toggle('sft-active', view === 'list');\r\n  document.getElementById('sftTabReview').classList.toggle('sft-active', view === 'review');\r\n  document.getElementById('sftListView').style.display = view === 'list' ? 'block' : 'none';\r\n  document.getElementById('sftReviewView').style.display = view === 'review' ? 'block' : 'none';\r\n  if (view === 'list') renderAll(); else renderMondayReview();\r\n}\r\n\r\n\/* ============================================================\r\n   4. WORKING DAYS\r\n   ============================================================ *\/\r\nfunction isWeekend(d){ var day = d.getDay(); return day === 0 || day === 6; }\r\nfunction addWorkingDays(startDate, n){\r\n  var d = new Date(startDate); var count = 0;\r\n  while (count < n){ d.setDate(d.getDate() + 1); if (!isWeekend(d)) count++; }\r\n  return d;\r\n}\r\nfunction workingDaysUntil(dueDateStr){\r\n  var due = new Date(dueDateStr + 'T00:00:00');\r\n  var today = new Date(new Date().toDateString());\r\n  if (due.getTime() === today.getTime()) return 0;\r\n  var sign = due > today ? 1 : -1;\r\n  var d = new Date(today); var count = 0; var guard = 0;\r\n  while (d.toDateString() !== due.toDateString() && guard < 3650){\r\n    d.setDate(d.getDate() + sign);\r\n    if (!isWeekend(d)) count += sign;\r\n    guard++;\r\n  }\r\n  return count;\r\n}\r\nfunction fmtDate(d){ return d.toLocaleDateString('en-GB', { weekday: 'short', day: 'numeric', month: 'short' }); }\r\n\r\n\/* ============================================================\r\n   5. SCORING\r\n   ============================================================ *\/\r\nfunction computeScore(t){\r\n  var revenuePoints = !t.revenue ? 0 : (t.revenueWeight === 'high' ? 3 : t.revenueWeight === 'medium' ? 2 : 1);\r\n  var dataPoints = t.data ? 1 : 0;\r\n  var communityPoints = t.community ? 1 : 0;\r\n  var impact = revenuePoints + dataPoints + communityPoints;\r\n  var urgency = 0;\r\n  if (t.timeSensitive && t.dueDate){\r\n    var wd = workingDaysUntil(t.dueDate);\r\n    if (wd <= 5) urgency = 3; else if (wd <= 10) urgency = 2; else urgency = 1;\r\n  }\r\n  var effortPoints = t.effort === 'quick' ? 2 : t.effort === 'task' ? 1 : 0;\r\n  var raw = impact + urgency + effortPoints;\r\n  var score = raw === 0 ? 1 : Math.min(raw, 10);\r\n  return { score: score, impact: impact, urgency: urgency, effortPoints: effortPoints, revenuePoints: revenuePoints };\r\n}\r\nfunction getBand(score){\r\n  if (score <= 3) return { label: 'Low priority', color: 'green', hex: 'var(--sft-status-green)', bg: 'var(--sft-status-green-bg)', dot: '\ud83d\udfe2' };\r\n  if (score <= 7) return { label: 'Medium priority', color: 'orange', hex: 'var(--sft-status-orange)', bg: 'var(--sft-status-orange-bg)', dot: '\ud83d\udfe0' };\r\n  return { label: 'High priority', color: 'red', hex: 'var(--sft-status-red)', bg: 'var(--sft-status-red-bg)', dot: '\ud83d\udd34' };\r\n}\r\nfunction bandRank(color){ return color === 'red' ? 0 : color === 'orange' ? 1 : 2; }\r\nfunction diaryTiming(score){\r\n  var band = getBand(score);\r\n  var today = new Date(new Date().toDateString());\r\n  if (band.color === 'green'){\r\n    var target = addWorkingDays(today, 5);\r\n    return { text: 'Add to diary by ' + fmtDate(target) + ' (within 5 working days)', sortDate: target };\r\n  } else if (band.color === 'orange'){\r\n    var start = addWorkingDays(today, 5);\r\n    var end = addWorkingDays(today, 10);\r\n    return { text: 'Add to diary between ' + fmtDate(start) + ' and ' + fmtDate(end) + ' (5\u201310 working days)', sortDate: start };\r\n  } else {\r\n    var start2 = addWorkingDays(today, 10);\r\n    return { text: 'Add to diary any time from ' + fmtDate(start2) + ' onward (10+ working days)', sortDate: start2 };\r\n  }\r\n}\r\n\r\n\/* ============================================================\r\n   6. AVATARS\r\n   ============================================================ *\/\r\nvar AVATAR_PALETTE = ['#FF1A8C', '#675F6E', '#01aeef', '#fe6b07', '#545ca9'];\r\nfunction initials(name){ return (name || '?').split(' ').map(function(w){ return w[0]; }).slice(0,2).join('').toUpperCase(); }\r\nfunction avatarColor(name){\r\n  var hash = 0;\r\n  for (var i = 0; i < name.length; i++) hash = name.charCodeAt(i) + ((hash << 5) - hash);\r\n  return AVATAR_PALETTE[Math.abs(hash) % AVATAR_PALETTE.length];\r\n}\r\nfunction findMember(name){ return members.filter(function(m){ return m.name === name; })[0]; }\r\nfunction avatarHtml(name, size){\r\n  size = size || 24;\r\n  var m = findMember(name);\r\n  if (m && m.photoUrl){\r\n    return '<img decoding=\"async\" class=\"sft-avatar\" style=\"width:' + size + 'px;height:' + size + 'px\" src=\"' + escapeHtml(m.photoUrl) + '\" alt=\"' + escapeHtml(name) + '\"\/>';\r\n  }\r\n  return '<span class=\"sft-avatar\" style=\"width:' + size + 'px;height:' + size + 'px;background:' + avatarColor(name || '?') + '\">' + initials(name) + '<\/span>';\r\n}\r\n\r\n\/* ============================================================\r\n   7. WIZARD\r\n   ============================================================ *\/\r\nvar wizardState = {};\r\nvar wizardEditingId = null;\r\nvar currentStepKey = 'title';\r\n\r\nfunction resetWizardState(){\r\n  wizardState = {\r\n    title: '', notes: '',\r\n    revenue: null, revenueWeight: null,\r\n    data: null, community: null,\r\n    effort: null,\r\n    timeSensitive: null, dueDate: null,\r\n    owner: members.length ? members[0].name : ''\r\n  };\r\n  wizardEditingId = null;\r\n  currentStepKey = 'title';\r\n}\r\nfunction visibleStepKeys(){\r\n  var keys = ['title', 'intro', 'revenue'];\r\n  if (wizardState.revenue === true) keys.push('revenueWeight');\r\n  keys.push('data', 'community', 'effort', 'timeSensitive');\r\n  if (wizardState.timeSensitive === true) keys.push('dueDate');\r\n  keys.push('owner', 'review');\r\n  return keys;\r\n}\r\nfunction openWizard(){\r\n  resetWizardState();\r\n  document.getElementById('sftWizardOverlay').style.display = 'flex';\r\n  renderWizardStep();\r\n}\r\nfunction closeWizard(){ document.getElementById('sftWizardOverlay').style.display = 'none'; }\r\nfunction isStepValid(key){\r\n  if (key === 'title') return wizardState.title.trim().length > 0;\r\n  if (key === 'revenue') return wizardState.revenue === true || wizardState.revenue === false;\r\n  if (key === 'revenueWeight') return !!wizardState.revenueWeight;\r\n  if (key === 'data') return wizardState.data === true || wizardState.data === false;\r\n  if (key === 'community') return wizardState.community === true || wizardState.community === false;\r\n  if (key === 'effort') return !!wizardState.effort;\r\n  if (key === 'timeSensitive') return wizardState.timeSensitive === true || wizardState.timeSensitive === false;\r\n  if (key === 'dueDate') return !!wizardState.dueDate;\r\n  if (key === 'owner') return !!wizardState.owner;\r\n  return true;\r\n}\r\nfunction goNext(){\r\n  if (!isStepValid(currentStepKey)) return;\r\n  var keys = visibleStepKeys();\r\n  var idx = keys.indexOf(currentStepKey);\r\n  if (idx < keys.length - 1){ currentStepKey = keys[idx + 1]; renderWizardStep(); }\r\n}\r\nfunction goBack(){\r\n  var keys = visibleStepKeys();\r\n  var idx = keys.indexOf(currentStepKey);\r\n  if (idx > 0){ currentStepKey = keys[idx - 1]; renderWizardStep(); }\r\n}\r\nfunction selectYesNo(field, val){ wizardState[field] = val; goNext(); }\r\nfunction selectChoice(field, val){ wizardState[field] = val; goNext(); }\r\nfunction stepIndexLabel(){\r\n  var keys = visibleStepKeys().filter(function(k){ return k !== 'intro' && k !== 'review'; });\r\n  var idx = keys.indexOf(currentStepKey);\r\n  if (idx === -1) return '';\r\n  return 'Question ' + (idx + 1) + ' of ' + keys.length;\r\n}\r\n\r\nfunction renderWizardStep(){\r\n  var body = document.getElementById('sftWizardBody');\r\n  var html = '';\r\n\r\n  if (currentStepKey === 'title'){\r\n    html += '<div class=\"sft-step-progress\">New task<\/div>';\r\n    html += '<p class=\"sft-step-prompt\">Please title your task<\/p>';\r\n    html += '<input type=\"text\" class=\"sft-wizard-input\" id=\"sftInputTitle\" placeholder=\"e.g. Add distinct coupon codes per campaign\" value=\"' + escapeAttr(wizardState.title) + '\" \/>';\r\n    html += '<textarea class=\"sft-wizard-input\" id=\"sftInputNotes\" placeholder=\"Any extra detail (optional)\" style=\"min-height:60px;\">' + escapeHtml(wizardState.notes) + '<\/textarea>';\r\n    html += '<div class=\"sft-wizard-actions\"><span><\/span><button class=\"sft-btn-primary\" onclick=\"handleTitleNext()\">Next<\/button><\/div>';\r\n  } else if (currentStepKey === 'intro'){\r\n    html += '<p class=\"sft-step-prompt\">Before we start, let me ask you a few questions...<\/p>';\r\n    html += '<div class=\"sft-wizard-actions\"><button class=\"sft-btn-ghost\" onclick=\"goBack()\">\u2039 Back<\/button><button class=\"sft-btn-primary\" onclick=\"goNext()\">Let\\'s go<\/button><\/div>';\r\n  } else if (currentStepKey === 'revenue'){\r\n    html += '<div class=\"sft-step-progress\">' + stepIndexLabel() + '<\/div>';\r\n    html += '<p class=\"sft-step-prompt\">Will it increase revenue?<\/p>';\r\n    html += yesNoRow('revenue', wizardState.revenue);\r\n    html += '<div class=\"sft-wizard-actions\"><button class=\"sft-btn-ghost\" onclick=\"goBack()\">\u2039 Back<\/button><span><\/span><\/div>';\r\n  } else if (currentStepKey === 'revenueWeight'){\r\n    html += '<div class=\"sft-step-progress\">' + stepIndexLabel() + '<\/div>';\r\n    html += '<p class=\"sft-step-prompt\">How much extra weighting should this get for revenue? (so we can see what would generate the most revenue)<\/p>';\r\n    html += choiceCol('revenueWeight', [\r\n      { val: 'low', label: 'Low \u2014 a little extra revenue' },\r\n      { val: 'medium', label: 'Medium \u2014 a solid revenue boost' },\r\n      { val: 'high', label: 'High \u2014 a major revenue driver' }\r\n    ], wizardState.revenueWeight);\r\n    html += '<div class=\"sft-wizard-actions\"><button class=\"sft-btn-ghost\" onclick=\"goBack()\">\u2039 Back<\/button><span><\/span><\/div>';\r\n  } else if (currentStepKey === 'data'){\r\n    html += '<div class=\"sft-step-progress\">' + stepIndexLabel() + '<\/div>';\r\n    html += '<p class=\"sft-step-prompt\">Will it give us more data?<\/p>';\r\n    html += yesNoRow('data', wizardState.data);\r\n    html += '<div class=\"sft-wizard-actions\"><button class=\"sft-btn-ghost\" onclick=\"goBack()\">\u2039 Back<\/button><span><\/span><\/div>';\r\n  } else if (currentStepKey === 'community'){\r\n    html += '<div class=\"sft-step-progress\">' + stepIndexLabel() + '<\/div>';\r\n    html += '<p class=\"sft-step-prompt\">Will it add value to the community?<\/p>';\r\n    html += yesNoRow('community', wizardState.community);\r\n    html += '<div class=\"sft-wizard-actions\"><button class=\"sft-btn-ghost\" onclick=\"goBack()\">\u2039 Back<\/button><span><\/span><\/div>';\r\n  } else if (currentStepKey === 'effort'){\r\n    html += '<div class=\"sft-step-progress\">' + stepIndexLabel() + '<\/div>';\r\n    html += '<p class=\"sft-step-prompt\">How long will it take?<\/p>';\r\n    html += choiceCol('effort', [\r\n      { val: 'quick', label: '\u26a1 Quick tick (under 10 minutes)' },\r\n      { val: 'task', label: '\ud83d\udd50 Task (up to 1 hour)' },\r\n      { val: 'project', label: '\ud83d\udcc1 Project (1 hour+)' }\r\n    ], wizardState.effort);\r\n    html += '<div class=\"sft-wizard-actions\"><button class=\"sft-btn-ghost\" onclick=\"goBack()\">\u2039 Back<\/button><span><\/span><\/div>';\r\n  } else if (currentStepKey === 'timeSensitive'){\r\n    html += '<div class=\"sft-step-progress\">' + stepIndexLabel() + '<\/div>';\r\n    html += '<p class=\"sft-step-prompt\">Is it time sensitive?<\/p>';\r\n    html += yesNoRow('timeSensitive', wizardState.timeSensitive);\r\n    html += '<div class=\"sft-wizard-actions\"><button class=\"sft-btn-ghost\" onclick=\"goBack()\">\u2039 Back<\/button><span><\/span><\/div>';\r\n  } else if (currentStepKey === 'dueDate'){\r\n    html += '<div class=\"sft-step-progress\">' + stepIndexLabel() + '<\/div>';\r\n    html += '<p class=\"sft-step-prompt\">What date is it due by?<\/p>';\r\n    html += '<input type=\"date\" class=\"sft-wizard-input\" id=\"sftInputDue\" value=\"' + escapeAttr(wizardState.dueDate || '') + '\" \/>';\r\n    html += '<div class=\"sft-wizard-actions\"><button class=\"sft-btn-ghost\" onclick=\"goBack()\">\u2039 Back<\/button><button class=\"sft-btn-primary\" onclick=\"handleDueNext()\">Next<\/button><\/div>';\r\n  } else if (currentStepKey === 'owner'){\r\n    html += '<div class=\"sft-step-progress\">' + stepIndexLabel() + '<\/div>';\r\n    html += '<p class=\"sft-step-prompt\">Who\\'s responsible for this?<\/p>';\r\n    html += '<div class=\"sft-choice-col\">';\r\n    members.forEach(function(m){\r\n      html += '<button type=\"button\" class=\"sft-choice-btn' + (wizardState.owner === m.name ? ' sft-picked' : '') + '\" onclick=\"selectChoice(\\'owner\\', \\'' + escapeAttr(m.name) + '\\')\">' + escapeHtml(m.name) + '<\/button>';\r\n    });\r\n    html += '<\/div>';\r\n    html += '<div class=\"sft-wizard-actions\"><button class=\"sft-btn-ghost\" onclick=\"goBack()\">\u2039 Back<\/button><span><\/span><\/div>';\r\n  } else if (currentStepKey === 'review'){\r\n    var scoreInfo = computeScore(wizardState);\r\n    var band = getBand(scoreInfo.score);\r\n    html += '<p class=\"sft-step-prompt\">Review &amp; save<\/p>';\r\n    html += '<div class=\"sft-review-score\" style=\"background:' + band.bg + ';color:' + band.hex + ';\">';\r\n    html += '<div class=\"sft-score-num\">' + scoreInfo.score + '\/10<\/div>';\r\n    html += '<div class=\"sft-score-label\">' + band.dot + ' ' + band.label + '<\/div>';\r\n    html += '<\/div>';\r\n    html += '<div class=\"sft-review-row\"><span>Task<\/span><strong>' + escapeHtml(wizardState.title) + '<\/strong><\/div>';\r\n    html += '<div class=\"sft-review-row\"><span>Revenue<\/span><strong>' + (wizardState.revenue ? ('Yes \u2014 ' + capitalize(wizardState.revenueWeight)) : 'No') + '<\/strong><\/div>';\r\n    html += '<div class=\"sft-review-row\"><span>More data<\/span><strong>' + (wizardState.data ? 'Yes' : 'No') + '<\/strong><\/div>';\r\n    html += '<div class=\"sft-review-row\"><span>Community value<\/span><strong>' + (wizardState.community ? 'Yes' : 'No') + '<\/strong><\/div>';\r\n    html += '<div class=\"sft-review-row\"><span>Effort<\/span><strong>' + effortLabel(wizardState.effort) + '<\/strong><\/div>';\r\n    html += '<div class=\"sft-review-row\"><span>Time sensitive<\/span><strong>' + (wizardState.timeSensitive ? ('Yes \u2014 due ' + wizardState.dueDate) : 'No') + '<\/strong><\/div>';\r\n    html += '<div class=\"sft-review-row\"><span>Responsible<\/span><strong>' + escapeHtml(wizardState.owner) + '<\/strong><\/div>';\r\n    html += '<div class=\"sft-wizard-actions\"><button class=\"sft-btn-ghost\" onclick=\"goBack()\">\u2039 Back<\/button><button class=\"sft-btn-primary\" onclick=\"handleWizardSave()\">' + (wizardEditingId ? '\ud83d\udcbe Save changes' : '\u2705 Save task') + '<\/button><\/div>';\r\n  }\r\n\r\n  body.innerHTML = html;\r\n  var titleInput = document.getElementById('sftInputTitle');\r\n  if (titleInput) titleInput.focus();\r\n}\r\n\r\nfunction yesNoRow(field, current){\r\n  return '<div class=\"sft-yn-row\">' +\r\n    '<button type=\"button\" class=\"sft-yn-big' + (current === true ? ' sft-picked-yes' : '') + '\" onclick=\"selectYesNo(\\'' + field + '\\', true)\">Yes<\/button>' +\r\n    '<button type=\"button\" class=\"sft-yn-big' + (current === false ? ' sft-picked-no' : '') + '\" onclick=\"selectYesNo(\\'' + field + '\\', false)\">No<\/button>' +\r\n    '<\/div>';\r\n}\r\nfunction choiceCol(field, options, current){\r\n  var html = '<div class=\"sft-choice-col\">';\r\n  options.forEach(function(o){\r\n    html += '<button type=\"button\" class=\"sft-choice-btn' + (current === o.val ? ' sft-picked' : '') + '\" onclick=\"selectChoice(\\'' + field + '\\', \\'' + o.val + '\\')\">' + o.label + '<\/button>';\r\n  });\r\n  html += '<\/div>';\r\n  return html;\r\n}\r\nfunction effortLabel(effort){\r\n  if (effort === 'quick') return '\u26a1 Quick tick (<10 min)';\r\n  if (effort === 'project') return '\ud83d\udcc1 Project (1hr+)';\r\n  return '\ud83d\udd50 Task (up to 1hr)';\r\n}\r\nfunction effortLabelPlain(effort){\r\n  if (effort === 'quick') return 'Quick tick (under 10 minutes)';\r\n  if (effort === 'project') return 'Project (1 hour+)';\r\n  return 'Task (up to 1 hour)';\r\n}\r\nfunction capitalize(s){ return s ? s.charAt(0).toUpperCase() + s.slice(1) : ''; }\r\n\r\nfunction handleTitleNext(){\r\n  var title = document.getElementById('sftInputTitle').value.trim();\r\n  if (!title){ alert('Please add a task name.'); return; }\r\n  wizardState.title = title;\r\n  wizardState.notes = document.getElementById('sftInputNotes').value.trim();\r\n  goNext();\r\n}\r\nfunction handleDueNext(){\r\n  var val = document.getElementById('sftInputDue').value;\r\n  if (!val){ alert('Please choose a due date.'); return; }\r\n  wizardState.dueDate = val;\r\n  goNext();\r\n}\r\nfunction handleWizardSave(){\r\n  var data = {\r\n    title: wizardState.title,\r\n    notes: wizardState.notes,\r\n    revenue: wizardState.revenue,\r\n    revenueWeight: wizardState.revenue ? wizardState.revenueWeight : null,\r\n    data: wizardState.data,\r\n    community: wizardState.community,\r\n    effort: wizardState.effort,\r\n    timeSensitive: wizardState.timeSensitive,\r\n    dueDate: wizardState.timeSensitive ? wizardState.dueDate : null,\r\n    owner: wizardState.owner\r\n  };\r\n  var op = wizardEditingId ? apiUpdateTask(wizardEditingId, data) : apiCreateTask(data);\r\n  op.then(function(){ refreshAll(); }).catch(function(err){ showError(err.message); });\r\n  closeWizard();\r\n}\r\nfunction handleEdit(id){\r\n  var t = allTasks.filter(function(x){ return String(x.id) === String(id); })[0];\r\n  if (!t) return;\r\n  wizardState = {\r\n    title: t.title || '', notes: t.notes || '',\r\n    revenue: !!t.revenue, revenueWeight: t.revenueWeight || 'medium',\r\n    data: !!t.data, community: !!t.community,\r\n    effort: t.effort || 'task',\r\n    timeSensitive: !!t.timeSensitive, dueDate: t.dueDate || null,\r\n    owner: t.owner || (members.length ? members[0].name : '')\r\n  };\r\n  wizardEditingId = id;\r\n  currentStepKey = 'review';\r\n  document.getElementById('sftWizardOverlay').style.display = 'flex';\r\n  renderWizardStep();\r\n}\r\n\r\n\/* ============================================================\r\n   8. LIST RENDERING\r\n   ============================================================ *\/\r\nfunction renderOwnerFilters(){\r\n  var container = document.getElementById('sftOwnerFilters');\r\n  container.innerHTML = '';\r\n  var allBtn = document.createElement('button');\r\n  allBtn.className = 'sft-chip' + (ownerFilter === 'all' ? ' sft-selected' : '');\r\n  allBtn.textContent = 'All';\r\n  allBtn.onclick = function(){ sftSetOwnerFilter('all'); };\r\n  container.appendChild(allBtn);\r\n  members.forEach(function(m){\r\n    var b = document.createElement('button');\r\n    b.className = 'sft-chip' + (ownerFilter === m.name ? ' sft-selected' : '');\r\n    b.textContent = m.name;\r\n    b.onclick = function(){ sftSetOwnerFilter(m.name); };\r\n    container.appendChild(b);\r\n  });\r\n}\r\nfunction sftSetOwnerFilter(v){ ownerFilter = v; renderOwnerFilters(); renderAll(); }\r\nfunction sftSetEffortFilter(v){\r\n  effortFilter = v;\r\n  document.querySelectorAll('#sftEffortFilters .sft-chip').forEach(function(c){ c.classList.toggle('sft-selected', c.getAttribute('data-val') === v); });\r\n  renderAll();\r\n}\r\nfunction sftSetPriorityFilter(v){\r\n  priorityFilter = v;\r\n  document.querySelectorAll('#sftPriorityFilters .sft-chip').forEach(function(c){ c.classList.toggle('sft-selected', c.getAttribute('data-val') === v); });\r\n  renderAll();\r\n}\r\nfunction sftSetRevenueFilter(v){\r\n  revenueFilter = v;\r\n  document.querySelectorAll('#sftRevenueFilters .sft-chip').forEach(function(c){ c.classList.toggle('sft-selected', c.getAttribute('data-val') === v); });\r\n  renderAll();\r\n}\r\nfunction sftSetSort(v){ sortMode = v; renderAll(); }\r\n\r\nfunction escapeHtml(str){\r\n  var d = document.createElement('div');\r\n  d.textContent = str || '';\r\n  return d.innerHTML;\r\n}\r\nfunction escapeAttr(str){ return escapeHtml(str).replace(\/\"\/g, '&quot;'); }\r\n\r\nfunction fmtDueBadge(dueDate){\r\n  if (!dueDate) return '';\r\n  var wd = workingDaysUntil(dueDate);\r\n  var d = new Date(dueDate + 'T00:00:00');\r\n  var label = d.toLocaleDateString('en-GB', { day: 'numeric', month: 'short' });\r\n  if (wd < 0) return 'Overdue \u2014 was due ' + label;\r\n  if (wd === 0) return 'Due today';\r\n  if (wd === 1) return 'Due tomorrow';\r\n  return 'Due ' + label;\r\n}\r\n\r\nfunction fmtAddedBadge(t){\r\n  var txt = 'Added';\r\n  if (t.createdAt){\r\n    var d = new Date(Number(t.createdAt));\r\n    txt += ' ' + d.toLocaleDateString('en-GB', { day: 'numeric', month: 'short' });\r\n  }\r\n  if (t.addedBy){\r\n    txt += ' by ' + t.addedBy;\r\n  }\r\n  return txt;\r\n}\r\nfunction taskCardHtml(t, s, band){\r\n  var dueTxt = t.timeSensitive ? fmtDueBadge(t.dueDate) : '';\r\n  var dueUrgentClass = (t.timeSensitive && workingDaysUntil(t.dueDate) <= 3) ? '' : ' sft-ok';\r\n  var revBadge = t.revenue\r\n    ? '<span class=\"sft-badge sft-badge-on\">\ud83d\udcb0 Revenue: ' + capitalize(t.revenueWeight) + '<\/span>'\r\n    : '<span class=\"sft-badge sft-badge-off\">\ud83d\udcb0 Revenue: No<\/span>';\r\n  return (\r\n    '<div class=\"sft-task-card' + (t.completed ? ' sft-completed' : '') + '\" style=\"border-left-color:' + band.hex + '\" data-id=\"' + t.id + '\">' +\r\n      '<div class=\"sft-checkbox-wrap\"><input type=\"checkbox\" ' + (t.completed ? 'checked' : '') + ' onchange=\"handleToggleComplete(\\'' + t.id + '\\', this.checked)\"\/><\/div>' +\r\n      '<div class=\"sft-task-main\">' +\r\n        '<p class=\"sft-task-title\">' + escapeHtml(t.title) + '<\/p>' +\r\n        (t.notes ? '<p class=\"sft-task-notes\">' + escapeHtml(t.notes) + '<\/p>' : '') +\r\n        '<div class=\"sft-badge-row\">' +\r\n          '<span class=\"sft-badge\" style=\"background:' + band.bg + ';color:' + band.hex + ';\">' + band.dot + ' ' + s.score + '\/10<\/span>' +\r\n          revBadge +\r\n          '<span class=\"sft-badge ' + (t.data ? 'sft-badge-on' : 'sft-badge-off') + '\">\ud83d\udcca Data<\/span>' +\r\n          '<span class=\"sft-badge ' + (t.community ? 'sft-badge-on' : 'sft-badge-off') + '\">\ud83e\udd1d Community<\/span>' +\r\n          '<span class=\"sft-badge sft-badge-effort\">' + effortLabel(t.effort) + '<\/span>' +\r\n          (dueTxt ? '<span class=\"sft-badge sft-badge-due' + dueUrgentClass + '\">' + dueTxt + '<\/span>' : '') +\r\n          '<span class=\"sft-badge sft-badge-owner\">' + avatarHtml(t.owner, 18) + ' ' + escapeHtml(t.owner || 'Unassigned') + '<\/span>' +\r\n          '<span class=\"sft-badge sft-badge-added\">\\u{1F553} ' + escapeHtml(fmtAddedBadge(t)) + '<\/span>' +\r\n        '<\/div>' +\r\n      '<\/div>' +\r\n      '<div class=\"sft-task-actions\" style=\"display:flex;gap:2px;padding-top:2px;\">' +\r\n        '<button class=\"sft-icon-btn\" title=\"Edit\" onclick=\"handleEdit(\\'' + t.id + '\\')\">\u270f\ufe0f<\/button>' +\r\n        '<button class=\"sft-icon-btn\" title=\"Delete\" onclick=\"handleDelete(\\'' + t.id + '\\')\">\ud83d\uddd1\ufe0f<\/button>' +\r\n      '<\/div>' +\r\n    '<\/div>'\r\n  );\r\n}\r\n\r\nfunction revenueMatchesFilter(t){\r\n  if (revenueFilter === 'all') return true;\r\n  if (revenueFilter === 'none') return !t.revenue;\r\n  return t.revenue && t.revenueWeight === revenueFilter;\r\n}\r\n\r\nfunction renderAll(){\r\n  var active = allTasks.filter(function(t){ return !t.completed; });\r\n  var done = allTasks.filter(function(t){ return t.completed; });\r\n\r\n  var filtered = active.filter(function(t){\r\n    if (ownerFilter !== 'all' && t.owner !== ownerFilter) return false;\r\n    if (effortFilter !== 'all' && t.effort !== effortFilter) return false;\r\n    if (!revenueMatchesFilter(t)) return false;\r\n    var s = computeScore(t);\r\n    var band = getBand(s.score);\r\n    if (priorityFilter !== 'all' && band.color !== priorityFilter) return false;\r\n    return true;\r\n  }).map(function(t){\r\n    var s = computeScore(t);\r\n    return { t: t, s: s, band: getBand(s.score) };\r\n  });\r\n\r\n  if (sortMode === 'revenue'){\r\n    filtered.sort(function(a, b){ return b.s.revenuePoints - a.s.revenuePoints || b.s.score - a.s.score; });\r\n  } else if (sortMode === 'due'){\r\n    filtered.sort(function(a, b){\r\n      var ad = (a.t.timeSensitive && a.t.dueDate) ? new Date(a.t.dueDate) : new Date(8640000000000000);\r\n      var bd = (b.t.timeSensitive && b.t.dueDate) ? new Date(b.t.dueDate) : new Date(8640000000000000);\r\n      return ad - bd;\r\n    });\r\n  } else {\r\n    filtered.sort(function(a, b){\r\n      if (bandRank(a.band.color) !== bandRank(b.band.color)) return bandRank(a.band.color) - bandRank(b.band.color);\r\n      if (b.s.score !== a.s.score) return b.s.score - a.s.score;\r\n      return a.t.createdAt - b.t.createdAt;\r\n    });\r\n  }\r\n\r\n  var listEl = document.getElementById('sftTaskList');\r\n  var emptyEl = document.getElementById('sftEmptyState');\r\n  if (filtered.length === 0){\r\n    listEl.innerHTML = '';\r\n    emptyEl.style.display = 'block';\r\n  } else {\r\n    emptyEl.style.display = 'none';\r\n    listEl.innerHTML = filtered.map(function(x){ return taskCardHtml(x.t, x.s, x.band); }).join('');\r\n  }\r\n\r\n  done.sort(function(a, b){ return (Number(b.completedAt) || 0) - (Number(a.completedAt) || 0); });\r\n  document.getElementById('sftCompletedCount').textContent = done.length;\r\n  document.getElementById('sftCompletedList').innerHTML = done.map(function(t){\r\n    var s = computeScore(t);\r\n    return taskCardHtml(t, s, getBand(s.score));\r\n  }).join('');\r\n}\r\n\r\nfunction sftToggleCompleted(){\r\n  completedOpen = !completedOpen;\r\n  document.getElementById('sftCompletedList').classList.toggle('sft-open', completedOpen);\r\n  document.getElementById('sftCompletedToggle').firstChild.textContent = completedOpen ? 'Hide completed (' : 'Show completed (';\r\n}\r\nfunction sftToggleInfo(){ document.getElementById('sftInfoBox').classList.toggle('sft-open'); }\r\n\r\n\/* ============================================================\r\n   9. ACTIONS\r\n   ============================================================ *\/\r\nfunction handleToggleComplete(id, checked){\r\n  apiUpdateTask(id, { completed: checked, completedAt: checked ? Date.now() : '' })\r\n    .then(function(){ refreshAll(); })\r\n    .catch(function(err){ showError(err.message); });\r\n}\r\nfunction handleDelete(id){\r\n  if (!confirm('Delete this task? This can\\'t be undone.')) return;\r\n  apiDeleteTask(id).then(function(){ refreshAll(); }).catch(function(err){ showError(err.message); });\r\n}\r\n\r\n\/* ============================================================\r\n   10. MANAGE TEAM\r\n   ============================================================ *\/\r\nfunction openTeamModal(){ renderTeamList(); document.getElementById('sftTeamOverlay').style.display = 'flex'; }\r\nfunction closeTeamModal(){ document.getElementById('sftTeamOverlay').style.display = 'none'; }\r\nfunction renderTeamList(){\r\n  var el = document.getElementById('sftTeamList');\r\n  el.innerHTML = members.map(function(m, i){\r\n    return '<div class=\"sft-team-row\">' +\r\n      avatarHtml(m.name, 32) +\r\n      '<span style=\"min-width:80px;font-weight:600;font-size:.85rem;\">' + escapeHtml(m.name) + '<\/span>' +\r\n      '<input type=\"text\" placeholder=\"Photo URL (from WordPress media library)\" value=\"' + escapeAttr(m.photoUrl || '') + '\" onchange=\"handlePhotoChange(' + i + ', this.value)\"\/>' +\r\n      '<button class=\"sft-icon-btn\" title=\"Remove\" onclick=\"handleRemoveMember(' + i + ')\">\ud83d\uddd1\ufe0f<\/button>' +\r\n    '<\/div>';\r\n  }).join('');\r\n}\r\nfunction handlePhotoChange(index, url){\r\n  var newArr = members.map(function(m, i){ return i === index ? Object.assign({}, m, { photoUrl: url.trim() }) : m; });\r\n  apiSaveMembers(newArr).then(function(){ refreshAll(); }).catch(function(err){ showError(err.message); });\r\n}\r\nfunction handleRemoveMember(index){\r\n  if (!confirm('Remove this team member from the list? (Existing tasks assigned to them will keep their name.)')) return;\r\n  var newArr = members.filter(function(m, i){ return i !== index; });\r\n  apiSaveMembers(newArr).then(function(){ refreshAll(); setTimeout(renderTeamList, 300); }).catch(function(err){ showError(err.message); });\r\n}\r\nfunction handleAddMember(){\r\n  var input = document.getElementById('sftNewMemberName');\r\n  var name = input.value.trim();\r\n  if (!name) return;\r\n  if (members.some(function(m){ return m.name.toLowerCase() === name.toLowerCase(); })){ alert('That name is already on the team list.'); return; }\r\n  var newArr = members.concat([{ name: name, photoUrl: '' }]);\r\n  apiSaveMembers(newArr).then(function(){ refreshAll(); input.value=''; setTimeout(renderTeamList, 300); }).catch(function(err){ showError(err.message); });\r\n}\r\n\r\n\/* ============================================================\r\n   11. DIARY EXPORT (per-task scheduling plan)\r\n   ============================================================ *\/\r\nvar lastDiaryRows = [];\r\nfunction openDiaryModal(){\r\n  var active = allTasks.filter(function(t){ return !t.completed; });\r\n  var grouped = {};\r\n  lastDiaryRows = [];\r\n\r\n  active.forEach(function(t){\r\n    var s = computeScore(t);\r\n    var band = getBand(s.score);\r\n    var timing = diaryTiming(s.score);\r\n    var owner = t.owner || 'Unassigned';\r\n    if (!grouped[owner]) grouped[owner] = [];\r\n    grouped[owner].push({ task: t, score: s.score, band: band, timing: timing });\r\n    lastDiaryRows.push({ owner: owner, title: t.title, score: s.score, band: band.label, timing: timing.text, sortDate: timing.sortDate });\r\n  });\r\n  Object.keys(grouped).forEach(function(owner){ grouped[owner].sort(function(a, b){ return a.timing.sortDate - b.timing.sortDate; }); });\r\n\r\n  var html = '';\r\n  if (Object.keys(grouped).length === 0){\r\n    html = '<p style=\"color:var(--sft-muted);font-size:.9rem;\">No open tasks to plan yet \u2014 add some first!<\/p>';\r\n  }\r\n  Object.keys(grouped).sort().forEach(function(owner){\r\n    html += '<div class=\"sft-diary-owner-block\">';\r\n    html += '<h3>' + avatarHtml(owner, 22) + ' ' + escapeHtml(owner) + '<\/h3>';\r\n    grouped[owner].forEach(function(item){\r\n      html += '<div class=\"sft-diary-item\">';\r\n      html += '<strong>' + escapeHtml(item.task.title) + '<\/strong> \u2014 ' + item.band.dot + ' ' + item.score + '\/10 (' + item.band.label + ')<br\/>';\r\n      html += '<span class=\"sft-diary-when\">' + item.timing.text + '<\/span>';\r\n      html += '<\/div>';\r\n    });\r\n    html += '<\/div>';\r\n  });\r\n  document.getElementById('sftDiaryContent').innerHTML = html;\r\n  document.getElementById('sftDiaryOverlay').style.display = 'flex';\r\n}\r\nfunction closeDiaryModal(){ document.getElementById('sftDiaryOverlay').style.display = 'none'; }\r\n\r\nfunction csvEscape(val){\r\n  var s = String(val == null ? '' : val);\r\n  if (\/[\",\\n]\/.test(s)) return '\"' + s.replace(\/\"\/g, '\"\"') + '\"';\r\n  return s;\r\n}\r\nfunction triggerCsvDownload(rows, filenamePrefix){\r\n  try {\r\n    var csv = rows.map(function(r){ return r.map(csvEscape).join(','); }).join('\\n');\r\n    var blob = new Blob([\"\\uFEFF\" + csv], { type: 'text\/csv;charset=utf-8;' });\r\n    var url = URL.createObjectURL(blob);\r\n    var a = document.createElement('a');\r\n    a.href = url;\r\n    a.download = filenamePrefix + '-' + new Date().toISOString().slice(0,10) + '.csv';\r\n    document.body.appendChild(a);\r\n    a.click();\r\n    document.body.removeChild(a);\r\n    URL.revokeObjectURL(url);\r\n  } catch (e) {\r\n    alert('The CSV download did not work: ' + e.message + '. Please try again \u2014 if it keeps happening, let Rebecca know.');\r\n  }\r\n}\r\nfunction downloadDiaryCsv(){\r\n  try {\r\n    var header = ['Owner', 'Task', 'Score (1-10)', 'Priority', 'Diary timing'];\r\n    var rows = lastDiaryRows.map(function(r){ return [r.owner, r.title, r.score, r.band, r.timing]; });\r\n    triggerCsvDownload([header].concat(rows), 'diary-plan');\r\n  } catch (e) {\r\n    alert('The diary CSV download hit a problem: ' + e.message + '. Please tell Rebecca this exact message so it can be fixed.');\r\n  }\r\n}\r\n\/* Exposed here too (not just at the bottom of the file) in case the widget code\r\n   ever gets pasted in a way that cuts off before the end of the script. *\/\r\nwindow.downloadDiaryCsv = downloadDiaryCsv;\r\nfunction copyDiaryText(){\r\n  var grouped = {};\r\n  lastDiaryRows.forEach(function(r){ if (!grouped[r.owner]) grouped[r.owner] = []; grouped[r.owner].push(r); });\r\n  var text = 'Sales Funnel Diary Plan \u2014 ' + new Date().toLocaleDateString('en-GB') + '\\n\\n';\r\n  Object.keys(grouped).sort().forEach(function(owner){\r\n    text += owner + ':\\n';\r\n    grouped[owner].forEach(function(r){ text += '  - ' + r.title + ' [' + r.score + '\/10, ' + r.band + '] \u2014 ' + r.timing + '\\n'; });\r\n    text += '\\n';\r\n  });\r\n  if (navigator.clipboard && navigator.clipboard.writeText){\r\n    navigator.clipboard.writeText(text).then(function(){ alert('Copied to clipboard!'); }, function(){ fallbackCopy(text); });\r\n  } else { fallbackCopy(text); }\r\n}\r\nfunction fallbackCopy(text){\r\n  var ta = document.createElement('textarea');\r\n  ta.value = text;\r\n  document.body.appendChild(ta);\r\n  ta.select();\r\n  try { document.execCommand('copy'); alert('Copied to clipboard!'); } catch (e) { alert('Could not copy automatically \u2014 please select and copy the text manually.'); }\r\n  document.body.removeChild(ta);\r\n}\r\n\r\n\/* ============================================================\r\n   12. GENERAL TASK EXPORT (all tasks, outstanding + completed)\r\n   ============================================================ *\/\r\nfunction exportAllTasksCsv(){\r\n  try {\r\n    var header = ['Responsible', 'Task title', 'Task description', 'Revenue impact', 'Priority score', 'Time to complete', 'Status', 'Added by', 'Date added'];\r\n    var rows = allTasks.map(function(t){\r\n      var s = computeScore(t);\r\n      var band = getBand(s.score);\r\n      var revenueImpact = t.revenue ? (capitalize(t.revenueWeight) + ' revenue impact') : 'No revenue impact';\r\n      var scoreText = s.score + '\/10 (' + band.label + ')';\r\n      var status = t.completed ? 'Completed' : 'Outstanding';\r\n      var dateAdded = t.createdAt ? new Date(Number(t.createdAt)).toLocaleDateString('en-GB') : '';\r\n      return [t.owner || 'Unassigned', t.title, t.notes || '', revenueImpact, scoreText, effortLabelPlain(t.effort), status, t.addedBy || '', dateAdded];\r\n    });\r\n    if (rows.length === 0){ alert('No tasks to export yet.'); return; }\r\n    triggerCsvDownload([header].concat(rows), 'sales-funnel-tasks');\r\n  } catch (e) {\r\n    alert('The export button hit a problem: ' + e.message + '. Please tell Rebecca this exact message so it can be fixed.');\r\n  }\r\n}\r\n\/* Exposed here too (not just at the bottom of the file) in case the widget code\r\n   ever gets pasted in a way that cuts off before the end of the script. *\/\r\nwindow.exportAllTasksCsv = exportAllTasksCsv;\r\n\r\n\/* ============================================================\r\n   13. MONDAY MORNING REVIEW\r\n   ============================================================ *\/\r\nfunction miniRow(t, metaText){\r\n  var s = computeScore(t);\r\n  var band = getBand(s.score);\r\n  return '<div class=\"sft-mini-row\" style=\"border-left:4px solid ' + band.hex + ';\">' +\r\n    '<span>' + band.dot + '<\/span>' +\r\n    '<span class=\"sft-mini-title\">' + escapeHtml(t.title) + '<\/span>' +\r\n    avatarHtml(t.owner, 20) +\r\n    '<span class=\"sft-mini-meta\">' + metaText + '<\/span>' +\r\n    '<\/div>';\r\n}\r\nfunction renderMondayReview(){\r\n  var now = Date.now();\r\n  var sevenDaysAgo = now - 7 * 24 * 60 * 60 * 1000;\r\n  var active = allTasks.filter(function(t){ return !t.completed; });\r\n  var completed = allTasks.filter(function(t){ return t.completed; });\r\n\r\n  var topPriority = active.map(function(t){ return { t: t, s: computeScore(t) }; })\r\n    .filter(function(x){ return getBand(x.s.score).color === 'green'; })\r\n    .sort(function(a, b){ return b.s.score - a.s.score; });\r\n\r\n  var dueSoon = active.filter(function(t){ return t.timeSensitive && t.dueDate; })\r\n    .map(function(t){ return { t: t, wd: workingDaysUntil(t.dueDate) }; })\r\n    .filter(function(x){ return x.wd <= 5; })\r\n    .sort(function(a, b){ return a.wd - b.wd; });\r\n\r\n  var completedLastWeek = completed.filter(function(t){ return t.completedAt && Number(t.completedAt) >= sevenDaysAgo; })\r\n    .sort(function(a, b){ return Number(b.completedAt) - Number(a.completedAt); });\r\n\r\n  var addedLastWeek = allTasks.filter(function(t){ return t.createdAt && Number(t.createdAt) >= sevenDaysAgo; })\r\n    .sort(function(a, b){ return Number(b.createdAt) - Number(a.createdAt); });\r\n\r\n  var html = '<p style=\"color:var(--sft-muted);font-size:.88rem;margin-bottom:20px;\">A quick digest for your Monday morning funnel review \u2014 refreshes automatically from the live task list.<\/p>';\r\n\r\n  html += '<div class=\"sft-review-section\"><h3>\ud83d\udfe2 This week\\'s top priorities <span class=\"sft-review-sub\">(high priority, not yet done)<\/span><\/h3>';\r\n  html += topPriority.length ? topPriority.map(function(x){ return miniRow(x.t, x.s.score + '\/10'); }).join('') : '<p class=\"sft-empty-state\" style=\"padding:14px;\">Nothing high priority outstanding \u2014 nice work.<\/p>';\r\n  html += '<\/div>';\r\n\r\n  html += '<div class=\"sft-review-section\"><h3>\u23f0 Due this week or overdue<\/h3>';\r\n  html += dueSoon.length ? dueSoon.map(function(x){ return miniRow(x.t, fmtDueBadge(x.t.dueDate)); }).join('') : '<p class=\"sft-empty-state\" style=\"padding:14px;\">Nothing due imminently.<\/p>';\r\n  html += '<\/div>';\r\n\r\n  html += '<div class=\"sft-review-section\"><h3>\u2705 Completed last week <span class=\"sft-review-sub\">(' + completedLastWeek.length + ')<\/span><\/h3>';\r\n  html += completedLastWeek.length ? completedLastWeek.map(function(t){ return miniRow(t, 'Done'); }).join('') : '<p class=\"sft-empty-state\" style=\"padding:14px;\">Nothing marked complete in the last 7 days.<\/p>';\r\n  html += '<\/div>';\r\n\r\n  html += '<div class=\"sft-review-section\"><h3>\ud83c\udd95 Added last week <span class=\"sft-review-sub\">(' + addedLastWeek.length + ')<\/span><\/h3>';\r\n  html += addedLastWeek.length ? addedLastWeek.map(function(t){ var status = t.completed ? 'Completed' : 'Outstanding'; return miniRow(t, t.addedBy ? (status + ' \\u00b7 added by ' + t.addedBy) : status); }).join('') : '<p class=\"sft-empty-state\" style=\"padding:14px;\">No new tasks added in the last 7 days.<\/p>';\r\n  html += '<\/div>';\r\n\r\n  document.getElementById('sftReviewView').innerHTML = html;\r\n}\r\n\r\n\/* ============================================================\r\n   14. BULK IMPORT (CSV)\r\n   ============================================================ *\/\r\nfunction parseCsv(text){\r\n  var rows = [];\r\n  var row = [];\r\n  var field = '';\r\n  var inQuotes = false;\r\n  for (var i = 0; i < text.length; i++){\r\n    var c = text[i];\r\n    if (inQuotes){\r\n      if (c === '\"'){\r\n        if (text[i+1] === '\"'){ field += '\"'; i++; }\r\n        else { inQuotes = false; }\r\n      } else {\r\n        field += c;\r\n      }\r\n    } else {\r\n      if (c === '\"'){ inQuotes = true; }\r\n      else if (c === ','){ row.push(field); field = ''; }\r\n      else if (c === '\\r'){ \/* ignore, newline handled below *\/ }\r\n      else if (c === '\\n'){ row.push(field); field = ''; rows.push(row); row = []; }\r\n      else { field += c; }\r\n    }\r\n  }\r\n  if (field.length || row.length){ row.push(field); rows.push(row); }\r\n  return rows.filter(function(r){ return !(r.length === 1 && r[0].trim() === ''); });\r\n}\r\n\r\nfunction findColIndex(headers, mustInclude, mustExclude){\r\n  for (var i = 0; i < headers.length; i++){\r\n    var h = (headers[i] || '').toLowerCase();\r\n    var ok = mustInclude.some(function(k){ return h.indexOf(k) !== -1; });\r\n    var bad = (mustExclude || []).some(function(k){ return h.indexOf(k) !== -1; });\r\n    if (ok && !bad) return i;\r\n  }\r\n  return -1;\r\n}\r\nfunction parseYesNo(val){\r\n  var v = String(val || '').trim().toLowerCase();\r\n  return v === 'yes' || v === 'y' || v === 'true' || v === '1';\r\n}\r\nfunction parseEffortValue(val){\r\n  var v = String(val || '').trim().toLowerCase();\r\n  if (v.indexOf('quick') !== -1) return 'quick';\r\n  if (v.indexOf('project') !== -1) return 'project';\r\n  return 'task';\r\n}\r\nfunction parseRevenueWeightValue(val){\r\n  var v = String(val || '').trim().toLowerCase();\r\n  if (v.indexOf('high') !== -1) return 'high';\r\n  if (v.indexOf('low') !== -1) return 'low';\r\n  return 'medium';\r\n}\r\nfunction parseDateValue(val){\r\n  var v = String(val || '').trim();\r\n  if (!v) return null;\r\n  var m = v.match(\/^(\\d{4})-(\\d{2})-(\\d{2})$\/);\r\n  if (m) return v;\r\n  var m2 = v.match(\/^(\\d{1,2})\\\/(\\d{1,2})\\\/(\\d{4})$\/);\r\n  if (m2){\r\n    var dd = ('0' + m2[1]).slice(-2), mm = ('0' + m2[2]).slice(-2), yyyy = m2[3];\r\n    return yyyy + '-' + mm + '-' + dd;\r\n  }\r\n  return null;\r\n}\r\n\r\nvar importParsedRows = [];\r\n\r\nfunction openImportModal(){\r\n  importParsedRows = [];\r\n  var fileInput = document.getElementById('sftImportFileInput');\r\n  if (fileInput) fileInput.value = '';\r\n  document.getElementById('sftImportFileName').textContent = '';\r\n  document.getElementById('sftImportPreview').innerHTML = '';\r\n  document.getElementById('sftImportConfirmBtn').disabled = true;\r\n  document.getElementById('sftImportConfirmBtn').textContent = 'Import tasks';\r\n  document.getElementById('sftImportOverlay').style.display = 'flex';\r\n}\r\nfunction closeImportModal(){ document.getElementById('sftImportOverlay').style.display = 'none'; }\r\n\r\nfunction downloadImportTemplate(){\r\n  try {\r\n    var header = ['Task title', 'Task description', 'Increases revenue (Yes\/No)', 'Revenue weighting (Low\/Medium\/High)', 'Gives more data (Yes\/No)', 'Adds community value (Yes\/No)', 'Time to complete (Quick\/Task\/Project)', 'Time sensitive (Yes\/No)', 'Due date (YYYY-MM-DD)', 'Responsible'];\r\n    var example1 = ['Add exit-intent popup to checkout page', 'Capture abandoning visitors with a small offer', 'Yes', 'High', 'No', 'No', 'Task', 'Yes', '2026-08-01', 'Rebecca'];\r\n    var example2 = ['Tag Substack subscribers by product interest', 'Helps segment future launch emails', 'No', '', 'Yes', 'No', 'Quick', 'No', '', 'Tamzin'];\r\n    triggerCsvDownload([header, example1, example2], 'bulk-import-template');\r\n  } catch (e) {\r\n    alert('Could not create the template: ' + e.message);\r\n  }\r\n}\r\n\r\nfunction handleImportFile(fileInput){\r\n  var file = fileInput.files && fileInput.files[0];\r\n  if (!file) return;\r\n  document.getElementById('sftImportFileName').textContent = file.name;\r\n  var reader = new FileReader();\r\n  reader.onload = function(e){\r\n    try {\r\n      var text = String(e.target.result || '').replace(\/^\\uFEFF\/, '');\r\n      var allRows = parseCsv(text);\r\n      if (allRows.length < 2){\r\n        document.getElementById('sftImportPreview').innerHTML = '<p style=\"color:var(--sft-status-red);\">That file does not look like it has any data rows below the header.<\/p>';\r\n        document.getElementById('sftImportConfirmBtn').disabled = true;\r\n        return;\r\n      }\r\n      var headers = allRows[0];\r\n      var colTitle = findColIndex(headers, ['title']);\r\n      var colDesc = findColIndex(headers, ['description', 'notes']);\r\n      var colRevenue = findColIndex(headers, ['revenue'], ['weight']);\r\n      var colRevenueWeight = findColIndex(headers, ['weight']);\r\n      var colData = findColIndex(headers, ['data']);\r\n      var colCommunity = findColIndex(headers, ['community']);\r\n      var colEffort = findColIndex(headers, ['time to complete', 'effort']);\r\n      var colTimeSensitive = findColIndex(headers, ['time sensitive']);\r\n      var colDue = findColIndex(headers, ['due']);\r\n      var colOwner = findColIndex(headers, ['responsible', 'owner']);\r\n\r\n      if (colTitle === -1){\r\n        document.getElementById('sftImportPreview').innerHTML = '<p style=\"color:var(--sft-status-red);\">Could not find a \"Task title\" column. Please use the downloadable template and keep its header row.<\/p>';\r\n        document.getElementById('sftImportConfirmBtn').disabled = true;\r\n        return;\r\n      }\r\n\r\n      var memberNames = members.map(function(m){ return m.name.toLowerCase(); });\r\n      var parsed = [];\r\n      for (var i = 1; i < allRows.length; i++){\r\n        var r = allRows[i];\r\n        if (!r || r.every(function(c){ return !c || !c.trim(); })) continue;\r\n        var title = (colTitle > -1 ? (r[colTitle] || '') : '').trim();\r\n        var warnings = [];\r\n        if (!title){ parsed.push({ valid: false, warnings: ['Missing task title'], raw: r }); continue; }\r\n\r\n        var revenue = colRevenue > -1 ? parseYesNo(r[colRevenue]) : false;\r\n        var revenueWeight = revenue ? (colRevenueWeight > -1 ? parseRevenueWeightValue(r[colRevenueWeight]) : 'medium') : null;\r\n        var dataVal = colData > -1 ? parseYesNo(r[colData]) : false;\r\n        var community = colCommunity > -1 ? parseYesNo(r[colCommunity]) : false;\r\n        var effort = colEffort > -1 ? parseEffortValue(r[colEffort]) : 'task';\r\n        var timeSensitive = colTimeSensitive > -1 ? parseYesNo(r[colTimeSensitive]) : false;\r\n        var dueDateRaw = colDue > -1 ? r[colDue] : '';\r\n        var dueDate = parseDateValue(dueDateRaw);\r\n        if (timeSensitive && !dueDate){\r\n          warnings.push('Due date could not be read, imported without one');\r\n          timeSensitive = false;\r\n        }\r\n        var owner = colOwner > -1 ? (r[colOwner] || '').trim() : '';\r\n        if (owner && memberNames.indexOf(owner.toLowerCase()) === -1){\r\n          warnings.push('\"' + owner + '\" is not in Manage team yet, saved as the responsible name anyway');\r\n        }\r\n        if (!owner) owner = members.length ? members[0].name : '';\r\n        var notes = colDesc > -1 ? (r[colDesc] || '').trim() : '';\r\n\r\n        parsed.push({\r\n          valid: true,\r\n          warnings: warnings,\r\n          data: { title: title, notes: notes, revenue: revenue, revenueWeight: revenueWeight, data: dataVal, community: community, effort: effort, timeSensitive: timeSensitive, dueDate: dueDate, owner: owner }\r\n        });\r\n      }\r\n\r\n      importParsedRows = parsed;\r\n      renderImportPreview();\r\n    } catch (err) {\r\n      document.getElementById('sftImportPreview').innerHTML = '<p style=\"color:var(--sft-status-red);\">Could not read that file: ' + escapeHtml(err.message) + '<\/p>';\r\n      document.getElementById('sftImportConfirmBtn').disabled = true;\r\n    }\r\n  };\r\n  reader.readAsText(file);\r\n}\r\n\r\nfunction renderImportPreview(){\r\n  var validCount = importParsedRows.filter(function(r){ return r.valid; }).length;\r\n  var html = '<p style=\"font-size:.85rem;color:var(--sft-muted);\">' + validCount + ' of ' + importParsedRows.length + ' rows ready to import.<\/p>';\r\n  html += importParsedRows.map(function(r){\r\n    if (!r.valid){\r\n      return '<div class=\"sft-mini-row\" style=\"border-left-color:var(--sft-status-red);\"><span>\u26a0\ufe0f<\/span><span class=\"sft-mini-title\">' + escapeHtml((r.raw && r.raw[0]) || '(blank row)') + '<\/span><span class=\"sft-mini-meta\">' + escapeHtml(r.warnings.join('; ')) + '<\/span><\/div>';\r\n    }\r\n    var s = computeScore(r.data);\r\n    var band = getBand(s.score);\r\n    var meta = s.score + '\/10' + (r.warnings.length ? ' \\u00b7 ' + escapeHtml(r.warnings.join('; ')) : '');\r\n    return '<div class=\"sft-mini-row\" style=\"border-left-color:' + band.hex + ';\"><span>' + band.dot + '<\/span><span class=\"sft-mini-title\">' + escapeHtml(r.data.title) + '<\/span><span class=\"sft-mini-meta\">' + meta + '<\/span><\/div>';\r\n  }).join('');\r\n  document.getElementById('sftImportPreview').innerHTML = html;\r\n  document.getElementById('sftImportConfirmBtn').disabled = validCount === 0;\r\n}\r\n\r\nfunction confirmImport(){\r\n  var valid = importParsedRows.filter(function(r){ return r.valid; });\r\n  if (!valid.length) return;\r\n  var btn = document.getElementById('sftImportConfirmBtn');\r\n  btn.disabled = true;\r\n  btn.textContent = 'Importing...';\r\n  var chain = Promise.resolve();\r\n  valid.forEach(function(r){\r\n    chain = chain.then(function(){ return apiCreateTask(r.data); });\r\n  });\r\n  chain.then(function(){\r\n    closeImportModal();\r\n    refreshAll();\r\n    alert('Imported ' + valid.length + ' task' + (valid.length === 1 ? '' : 's') + '.');\r\n  }).catch(function(err){\r\n    alert('Import stopped partway through: ' + err.message + '. Anything already imported is saved, refresh and re-import just the remaining rows if needed.');\r\n    btn.disabled = false;\r\n    btn.textContent = 'Import tasks';\r\n    refreshAll();\r\n  });\r\n}\r\n\/* Exposed here too (not just at the bottom of the file) in case the widget code\r\n   ever gets pasted in a way that cuts off before the end of the script. *\/\r\nwindow.openImportModal = openImportModal;\r\nwindow.closeImportModal = closeImportModal;\r\nwindow.downloadImportTemplate = downloadImportTemplate;\r\nwindow.handleImportFile = handleImportFile;\r\nwindow.confirmImport = confirmImport;\r\n\r\n\/* Expose functions used by inline onclick= handlers on window *\/\r\nwindow.sftTryUnlock = sftTryUnlock;\r\nwindow.switchView = switchView;\r\nwindow.openWizard = openWizard;\r\nwindow.closeWizard = closeWizard;\r\nwindow.goNext = goNext;\r\nwindow.goBack = goBack;\r\nwindow.selectYesNo = selectYesNo;\r\nwindow.selectChoice = selectChoice;\r\nwindow.handleTitleNext = handleTitleNext;\r\nwindow.handleDueNext = handleDueNext;\r\nwindow.handleWizardSave = handleWizardSave;\r\nwindow.handleEdit = handleEdit;\r\nwindow.handleToggleComplete = handleToggleComplete;\r\nwindow.handleDelete = handleDelete;\r\nwindow.sftSetOwnerFilter = sftSetOwnerFilter;\r\nwindow.sftSetEffortFilter = sftSetEffortFilter;\r\nwindow.sftSetPriorityFilter = sftSetPriorityFilter;\r\nwindow.sftSetRevenueFilter = sftSetRevenueFilter;\r\nwindow.sftSetSort = sftSetSort;\r\nwindow.sftToggleCompleted = sftToggleCompleted;\r\nwindow.sftToggleInfo = sftToggleInfo;\r\nwindow.openTeamModal = openTeamModal;\r\nwindow.closeTeamModal = closeTeamModal;\r\nwindow.handlePhotoChange = handlePhotoChange;\r\nwindow.handleRemoveMember = handleRemoveMember;\r\nwindow.handleAddMember = handleAddMember;\r\nwindow.openDiaryModal = openDiaryModal;\r\nwindow.closeDiaryModal = closeDiaryModal;\r\nwindow.downloadDiaryCsv = downloadDiaryCsv;\r\nwindow.copyDiaryText = copyDiaryText;\r\nwindow.exportAllTasksCsv = exportAllTasksCsv;\r\nwindow.openImportModal = openImportModal;\r\nwindow.closeImportModal = closeImportModal;\r\nwindow.downloadImportTemplate = downloadImportTemplate;\r\nwindow.handleImportFile = handleImportFile;\r\nwindow.confirmImport = confirmImport;\r\n\r\nfunction sftToggleCollapse(){\r\n  var wrap = document.getElementById('sftWrapBody');\r\n  var btn = document.getElementById('sftCollapseToggle');\r\n  if (!wrap || !btn) return;\r\n  var collapsingNow = wrap.style.display !== 'none';\r\n  wrap.style.display = collapsingNow ? 'none' : '';\r\n  btn.textContent = collapsingNow ? '\\u2304 Expand' : '\\u2303 Collapse';\r\n  try { localStorage.setItem('sftCollapsed', collapsingNow ? '1' : '0'); } catch(e){}\r\n}\r\n(function restoreCollapseState(){\r\n  var saved = null;\r\n  try { saved = localStorage.getItem('sftCollapsed'); } catch(e){}\r\n  if (saved === '1'){\r\n    var wrap = document.getElementById('sftWrapBody');\r\n    var btn = document.getElementById('sftCollapseToggle');\r\n    if (wrap) wrap.style.display = 'none';\r\n    if (btn) btn.textContent = '\\u2304 Expand';\r\n  }\r\n})();\r\nwindow.sftToggleCollapse = sftToggleCollapse;\r\n\r\nfunction sftSignOut(){\r\n  if (pollTimer) clearInterval(pollTimer);\r\n  SFT_KEY = null;\r\n  try { localStorage.removeItem('sftKey'); } catch(e){}\r\n  document.getElementById('sftApp').style.display = 'none';\r\n  document.getElementById('sftGate').style.display = 'flex';\r\n  var input = document.getElementById('sftGateInput');\r\n  if (input) input.value = '';\r\n  var err = document.getElementById('sftGateError');\r\n  if (err) err.textContent = '';\r\n}\r\nwindow.sftSignOut = sftSignOut;\r\n\r\n})();\r\n<\/script>\r\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-7019bb5 e-flex e-con-boxed e-con e-parent\" data-id=\"7019bb5\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-ee358a3 elementor-widget elementor-widget-html\" data-id=\"ee358a3\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<iframe \r\n  id=\"accountant-she-funnel-section\"\r\n  src=\"https:\/\/www.accountantshe.com\/wp-content\/uploads\/2026\/07\/accountant_she_full_funnel_all_flagships-6-v4.html\" \r\n  style=\"width:100%; height:1600px; border:none; border-radius:12px;\" \r\n  loading=\"lazy\"\r\n  title=\"accountant_she sales funnel map\">\r\n<\/iframe>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-7cc41d9 e-flex e-con-boxed e-con e-parent\" data-id=\"7cc41d9\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-239a532 elementor-widget elementor-widget-html\" data-id=\"239a532\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\r\n<!DOCTYPE html>\r\n<html lang=\"en\">\r\n<head>\r\n<meta charset=\"UTF-8\">\r\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\r\n<meta name=\"robots\" content=\"noindex, nofollow\">\r\n<title>Accountant She \u2014 Launch Plans<\/title>\r\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\r\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Lora:wght@500;600;700&family=League+Spartan:wght@400;500;600;700&display=swap\" rel=\"stylesheet\">\r\n<style>\r\n  :root{\r\n    --bg:#fdf6fa; --card:#ffffff; --ink:#1a1a1a; --ink-soft:#6b5b63; --line:#f6d9e9;\r\n    --pink:#F6267F; --pink-light:#FCC5E2; --black:#000000;\r\n  }\r\n  *{box-sizing:border-box}\r\n  body{margin:0;background:var(--bg);color:var(--ink);font-family:'League Spartan',sans-serif;}\r\n  header{padding:20px 28px 14px;border-bottom:1px solid var(--line);background:var(--card);position:sticky;top:0;z-index:30;}\r\n  h1{font-family:'Lora',Georgia,serif;font-size:19px;font-weight:600;margin:0 0 4px;}\r\n  .sub{font-size:13px;color:var(--ink-soft);margin:0 0 14px;max-width:900px;line-height:1.5;}\r\n  .tabs{display:flex;gap:8px;padding:10px 28px;background:var(--card);border-bottom:1px solid var(--line);position:sticky;top:82px;z-index:29;flex-wrap:wrap;}\r\n  .tabbtn{padding:8px 16px;border:1px solid var(--line);border-radius:8px;background:#fff;font-size:13px;cursor:pointer;font-weight:600;color:var(--ink-soft);font-family:'League Spartan',sans-serif;}\r\n  .tabbtn.active{background:var(--black);color:#fff;border-color:var(--black);}\r\n  main{padding:24px 28px 60px;max-width:1100px;margin:0 auto;}\r\n  .tabpanel{display:none;}\r\n  .tabpanel.active{display:block;}\r\n\r\n  \/* Summary cards *\/\r\n  .launch-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:16px;}\r\n  .launch-card{border:1.5px solid var(--line);border-radius:12px;padding:18px;background:var(--card);cursor:pointer;transition:box-shadow .15s, transform .15s;}\r\n  .launch-card:hover{box-shadow:0 6px 18px rgba(246,38,127,.12);transform:translateY(-2px);}\r\n  .launch-card.placeholder{opacity:.6;border-style:dashed;}\r\n  .launch-card h3{font-family:'Lora',Georgia,serif;font-size:15px;margin:0 0 8px;}\r\n  .status-pill{display:inline-block;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.03em;padding:3px 8px;border-radius:5px;margin-bottom:10px;}\r\n  .status-pill.complete{background:#e3f4e9;color:#1f8a4c;}\r\n  .status-pill.placeholder{background:#f0f0f0;color:#888;}\r\n  .card-meta{font-size:12.5px;color:var(--ink-soft);line-height:1.6;}\r\n\r\n  \/* Detail panel (slide-over) *\/\r\n  #detailOverlay{position:fixed;inset:0;background:rgba(0,0,0,.35);z-index:50;display:none;}\r\n  #detailPanel{position:fixed;right:0;top:0;height:100vh;width:min(720px,92vw);background:#fff;z-index:51;\r\n    box-shadow:-10px 0 30px rgba(0,0,0,.15);transform:translateX(100%);transition:transform .25s ease;overflow-y:auto;padding:26px;}\r\n  #detailPanel.open{transform:translateX(0);}\r\n  #detailOverlay.open{display:block;}\r\n  .close-btn{position:absolute;top:18px;right:18px;background:none;border:none;font-size:20px;cursor:pointer;color:var(--ink-soft);}\r\n  .detail-title{font-family:'Lora',Georgia,serif;font-size:20px;margin:0 0 6px;padding-right:30px;}\r\n  .detail-sub{font-size:13px;color:var(--ink-soft);margin-bottom:20px;}\r\n  .detail-tabs{display:flex;gap:6px;margin-bottom:16px;flex-wrap:wrap;}\r\n  .dtab{padding:6px 12px;border:1px solid var(--line);border-radius:7px;background:#fff;font-size:12.5px;cursor:pointer;font-family:'League Spartan',sans-serif;}\r\n  .dtab.active{background:var(--pink);color:#fff;border-color:var(--pink);}\r\n  .dpanel{display:none;}\r\n  .dpanel.active{display:block;}\r\n\r\n  \/* Email cards *\/\r\n  .email-card{border:1px solid var(--line);border-radius:10px;padding:14px 16px;margin-bottom:12px;background:#fffafc;}\r\n  .email-card .email-num{display:inline-block;width:22px;height:22px;border-radius:50%;background:var(--pink);color:#fff;\r\n    font-size:11px;font-weight:700;text-align:center;line-height:22px;margin-right:8px;}\r\n  .email-card h4{font-family:'Lora',Georgia,serif;font-size:14.5px;margin:6px 0 4px;display:inline;}\r\n  .email-meta{font-size:11.5px;color:var(--ink-soft);margin:6px 0 10px;line-height:1.7;}\r\n  .email-meta b{color:var(--ink);}\r\n  .video-tag{display:inline-block;background:var(--pink-light);color:#a3105a;font-size:10px;font-weight:700;\r\n    padding:2px 7px;border-radius:5px;margin-left:6px;text-transform:uppercase;}\r\n  .email-body{white-space:pre-wrap;font-size:12.5px;line-height:1.65;background:#fff;border:1px solid var(--line);\r\n    border-radius:8px;padding:12px 14px;display:none;margin-top:8px;}\r\n  .email-body.open{display:block;}\r\n  .toggle-body{font-size:12px;color:var(--pink);cursor:pointer;font-weight:600;background:none;border:none;padding:0;}\r\n\r\n  \/* PLV \/ prelaunch cards \u2014 deliberately distinct from cart-phase emails: no pitch, no CTA-to-buy *\/\r\n  .plv-card{border:1px solid #d6d0f0;border-left:4px solid #3c3489;border-radius:10px;padding:14px 16px;margin-bottom:12px;background:#f9f8ff;}\r\n  .plv-card .plv-num{display:inline-block;width:22px;height:22px;border-radius:50%;background:#3c3489;color:#fff;\r\n    font-size:11px;font-weight:700;text-align:center;line-height:22px;margin-right:8px;}\r\n  .plv-card h4{font-family:'Lora',Georgia,serif;font-size:14.5px;margin:6px 0 4px;display:inline;}\r\n  .plv-label{display:inline-block;background:#e4e1f7;color:#3c3489;font-size:10px;font-weight:700;\r\n    padding:2px 7px;border-radius:5px;margin-left:6px;text-transform:uppercase;}\r\n  .plv-meta{font-size:11.5px;color:var(--ink-soft);margin:6px 0 10px;line-height:1.7;}\r\n  .plv-meta b{color:var(--ink);}\r\n  .plv-missing{border:1.5px dashed #d6d0f0;border-radius:10px;padding:16px;background:#f9f8ff;font-size:12.5px;color:#3c3489;line-height:1.6;}\r\n\r\n  \/* Video scripts tracker *\/\r\n  .vs-row{display:flex;gap:12px;padding:12px 14px;border-bottom:1px solid var(--line);font-size:13px;align-items:flex-start;background:var(--card);}\r\n  .vs-row:last-child{border-bottom:none;}\r\n  .vs-launch{width:170px;flex-shrink:0;font-family:'Lora',Georgia,serif;font-weight:600;font-size:12.5px;color:var(--ink);}\r\n  .vs-stage{width:150px;flex-shrink:0;font-size:10.5px;text-transform:uppercase;letter-spacing:.02em;color:#3c3489;font-weight:700;}\r\n  .vs-title{flex:1;font-size:12.5px;}\r\n  .vs-filmedby{width:90px;flex-shrink:0;font-size:11.5px;font-weight:700;text-align:center;padding:3px 6px;border-radius:5px;background:var(--pink-light);color:#a3105a;}\r\n  .vs-length{width:70px;flex-shrink:0;font-size:11px;color:var(--ink-soft);text-align:right;}\r\n  .vs-status{width:130px;flex-shrink:0;font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.02em;color:#c0392b;text-align:right;}\r\n\r\n  \/* Social cards *\/\r\n  .social-card{border:1px solid var(--line);border-radius:10px;padding:14px 16px;margin-bottom:12px;background:#fffafc;}\r\n  .social-card h4{font-family:'Lora',Georgia,serif;font-size:14px;margin:0 0 4px;}\r\n  .platform-tags{margin:4px 0 8px;}\r\n  .ptag{display:inline-block;background:var(--pink-light);color:#a3105a;font-size:10px;font-weight:700;\r\n    padding:2px 7px;border-radius:5px;margin-right:5px;}\r\n  .social-body{font-size:12.5px;line-height:1.6;white-space:pre-wrap;}\r\n  .slide-list{margin:0;padding-left:18px;font-size:12.5px;line-height:1.7;}\r\n\r\n  \/* Dates tab *\/\r\n  .date-row{display:flex;gap:14px;padding:10px 14px;border-bottom:1px solid var(--line);font-size:13px;align-items:center;}\r\n  .date-row:last-child{border-bottom:none;}\r\n  .date-badge{font-family:'Lora',Georgia,serif;font-weight:600;font-size:13px;color:var(--pink);width:110px;flex-shrink:0;}\r\n  .date-type{width:130px;flex-shrink:0;font-size:11px;text-transform:uppercase;letter-spacing:.02em;color:var(--ink-soft);font-weight:700;}\r\n  .date-launch{width:170px;flex-shrink:0;font-size:12px;color:var(--ink-soft);}\r\n  .date-desc{flex:1;font-size:13px;}\r\n  .date-group{border:1px solid var(--line);border-radius:10px;margin-bottom:14px;overflow:hidden;background:var(--card);}\r\n  .date-group-head{background:var(--pink-light);padding:8px 14px;font-family:'Lora',Georgia,serif;font-weight:600;font-size:13px;}\r\n\r\n  .empty-note{font-size:13px;color:var(--ink-soft);padding:30px;text-align:center;border:1.5px dashed var(--line);border-radius:12px;}\r\n  .month-divider{font-family:'Lora',Georgia,serif;font-weight:600;font-size:14px;background:var(--black);color:#fff;\r\n    padding:7px 14px;border-radius:7px;margin:20px 0 8px;}\r\n  .month-divider:first-child{margin-top:0;}\r\n  .timeline-row{display:flex;gap:12px;padding:9px 14px;border-bottom:1px solid var(--line);font-size:13px;align-items:flex-start;background:var(--card);}\r\n  .timeline-row:last-child{border-bottom:none;}\r\n  .tl-date{font-family:'Lora',Georgia,serif;font-weight:600;font-size:12.5px;color:var(--ink);width:76px;flex-shrink:0;}\r\n  .tl-launch-tag{display:inline-block;font-size:10px;font-weight:700;padding:2px 7px;border-radius:5px;margin-right:8px;\r\n    white-space:nowrap;flex-shrink:0;width:150px;overflow:hidden;text-overflow:ellipsis;}\r\n  .tl-type{width:110px;flex-shrink:0;font-size:10.5px;text-transform:uppercase;letter-spacing:.02em;color:var(--ink-soft);font-weight:700;}\r\n  .tl-desc{flex:1;font-size:12.5px;}\r\n<\/style>\r\n<\/head>\r\n<body>\r\n\r\n<header>\r\n  <h1>Accountant She \u2014 Launch Plans<\/h1>\r\n  <p class=\"sub\">One place for every launch: dates, email sequence, and social plan. Click any launch to see its full breakdown, or use the tabs above to see everything of one kind across every launch at once.<\/p>\r\n  <div style=\"background:#fff4f9;border:1.5px solid var(--pink);border-radius:10px;padding:12px 16px;margin-top:2px;font-size:12.5px;line-height:1.6;color:var(--ink);\">\r\n    <b style=\"color:var(--pink);text-transform:uppercase;letter-spacing:.02em;font-size:11px;\">Rachel's launch standards \u2014 non-negotiable, going forward<\/b><br>\r\n    <b>1. No AI externally.<\/b> Nothing AI-drafted goes out to subscribers as written. Every email\/social piece drafted here is a starting draft only \u2014 Rachel or Rebecca rewrites in her own voice before anything sends. This tracker exists to save time on structure and sequencing, not to auto-publish copy.<br>\r\n    <b>2. Video in every launch.<\/b> Each email sequence needs at least one genuine video moment (Loom\/selfie-style, not polished production) \u2014 see the <i>video gap<\/i> note on each launch card below.<br>\r\n    <b>3. Diary time to test &amp; compare.<\/b> Every launch gets a scheduled review slot ~7 days after cart close to compare it against every other launch we've run \u2014 see the <b>Testing &amp; Retro<\/b> tab.\r\n  <\/div>\r\n<\/header>\r\n\r\n<div class=\"tabs\">\r\n  <button class=\"tabbtn active\" onclick=\"showMainTab('summary')\">Summary<\/button>\r\n  <button class=\"tabbtn\" onclick=\"showMainTab('timeline')\">Full Timeline<\/button>\r\n  <button class=\"tabbtn\" onclick=\"showMainTab('dates')\">All Dates<\/button>\r\n  <button class=\"tabbtn\" onclick=\"showMainTab('socials')\">All Socials<\/button>\r\n  <button class=\"tabbtn\" onclick=\"showMainTab('emails')\">All Emails<\/button>\r\n  <button class=\"tabbtn\" onclick=\"showMainTab('retro')\">Testing &amp; Retro<\/button>\r\n  <button class=\"tabbtn\" onclick=\"showMainTab('videoscripts')\">Video Scripts<\/button>\r\n<\/div>\r\n\r\n<main>\r\n  <div id=\"tab-summary\" class=\"tabpanel active\">\r\n    <div class=\"launch-grid\" id=\"launchGrid\"><\/div>\r\n  <\/div>\r\n\r\n  <div id=\"tab-timeline\" class=\"tabpanel\">\r\n    <p style=\"font-size:13px;color:var(--ink-soft);margin-bottom:14px;\">Every email and social post across every launch, interleaved in true date order \u2014 use this to spot clashes and busy weeks before anything goes live.<\/p>\r\n    <div id=\"timelineContent\"><\/div>\r\n  <\/div>\r\n\r\n  <div id=\"tab-dates\" class=\"tabpanel\">\r\n    <div id=\"datesContent\"><\/div>\r\n  <\/div>\r\n\r\n  <div id=\"tab-socials\" class=\"tabpanel\">\r\n    <div id=\"socialsContent\"><\/div>\r\n  <\/div>\r\n\r\n  <div id=\"tab-emails\" class=\"tabpanel\">\r\n    <div id=\"emailsContent\"><\/div>\r\n  <\/div>\r\n\r\n  <div id=\"tab-retro\" class=\"tabpanel\">\r\n    <p style=\"font-size:13px;color:var(--ink-soft);margin-bottom:14px;\">Per Rachel's standard: every launch gets a diary slot ~7 days after cart close (or ~7 days after the first promotional push, for evergreen products) to compare it against every launch that ran before it \u2014 open\/click rates from Flodesk, Teachable conversion, revenue vs. the Mid scenario in the Revenue Recovery Plan, and video engagement. Book these slots as soon as a launch's dates are confirmed, not after the fact.<\/p>\r\n    <div id=\"retroContent\"><\/div>\r\n  <\/div>\r\n\r\n  <div id=\"tab-videoscripts\" class=\"tabpanel\">\r\n    <p style=\"font-size:13px;color:var(--ink-soft);margin-bottom:14px;\">Every video needed across every launch, in one list \u2014 use this to track script-writing separately from this tracker. Each row shows who's filming (per Rachel's voice \u2014 see note below), the target length, and a script status. Scripts themselves are written elsewhere; this is just the checklist.<\/p>\r\n    <div style=\"background:#f9f8ff;border:1px solid #d6d0f0;border-radius:10px;padding:12px 16px;margin-bottom:16px;font-size:12.5px;line-height:1.6;color:#3c3489;\">\r\n      <b>Why almost everything says \"Rachel\":<\/b> every email in this entire tracker is written and signed in Rachel's first-person voice (\"Rach X\") \u2014 every story, prompt, and mistake described is hers. For the video to match the email it sits inside, the same person needs to be on camera. Rebecca's role here is production (filming, editing, briefing), not on-screen \u2014 unless a piece is deliberately reframed as Rebecca's own voice, in which case flag it and the matching email copy needs to change too, not just the filmedBy tag.\r\n    <\/div>\r\n    <div id=\"videoScriptsContent\"><\/div>\r\n  <\/div>\r\n<\/main>\r\n\r\n<div id=\"detailOverlay\" onclick=\"closeDetail()\"><\/div>\r\n<div id=\"detailPanel\">\r\n  <button class=\"close-btn\" onclick=\"closeDetail()\">&times;<\/button>\r\n  <div id=\"detailContent\"><\/div>\r\n<\/div>\r\n\r\n<script>\r\nconst launches = [\r\n  {\r\n    id: 'mgmt-accounts',\r\n    name: 'Management Accounts',\r\n    status: 'complete',\r\n    price: '\u00a31,200 + VAT (or 3-month plan)',\r\n    salesUrl: 'https:\/\/accountantshe.com\/management-accounts (PLACEHOLDER \u2014 confirm real URL)',\r\n    cartOpen: '2026-10-09',\r\n    cartClose: '2026-10-30',\r\n    courseStart: '2026-10-31',\r\n    earlyBird: { discount: '\u00a3100 off', standardPrice: '\u00a31,200 + VAT', earlyBirdPrice: '\u00a31,100 + VAT', endDate: '2026-10-16', rule: '>\u00a3500 ex-VAT' },\r\n    milestones: [\r\n      { date: '2026-10-01', label: 'PLV1 \u2014 belief-shift piece goes out' },\r\n      { date: '2026-10-04', label: 'PLV2 \u2014 proof\/technique piece goes out' },\r\n      { date: '2026-10-07', label: 'PLV3 \u2014 transformation + big reveal goes out' },\r\n      { date: '2026-10-09', label: 'Cart opens \u2014 early bird pricing live' },\r\n      { date: '2026-10-16', label: 'Early bird ends \u2014 price rises to \u00a31,200+VAT' },\r\n      { date: '2026-10-30', label: 'Cart closes' },\r\n      { date: '2026-10-31', label: 'Course opens' }\r\n    ],\r\n    theme: \"You're already doing 80% of management accounts for every client \u2014 you just don't charge for it, and you've never named it as its own service.\",\r\n    outcome: \"By the end of the campaign, readers can see management accounts as a repackaging of data they already hold, not a brand-new skill \u2014 and feel confident pricing and delivering it without it eating another full day per client.\",\r\n    prelaunch: [\r\n      {\r\n        n: 1, date: '2026-10-01', time: '8:00am',\r\n        stage: 'PLV1 \u2014 Belief shift',\r\n        segment: 'Full list',\r\n        title: \"The service you're already doing for free\",\r\n        preheader: \"No pitch in this one \u2014 just something worth 3 minutes\",\r\n        purpose: \"Collapse the belief that management accounts = a new skill to learn. Pure value, no offer mentioned.\",\r\n        cta: 'Reply and tell me \u2014 do you already do this?',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: \"60-90 sec direct-to-camera, Rachel \u2014 the 'so how's the business doing' moment, no slides\",\r\n        body: `Can I ask you something?\r\n\r\nWhen was the last time a client asked you \"so how's the business actually doing this year\" \u2014 and you answered off the top of your head, from memory, because you didn't have anything current to show them?\r\n\r\nI used to do this constantly. Client calls, I'd glance at the P&L from three months ago, do some mental maths, and give them a vague answer that sounded confident but wasn't really based on anything.\r\n\r\nThat's the gap management accounts fills. Not the annual accounts \u2014 the bit in between. The number a business owner actually needs to make a decision this month, not eleven months after the year ends.\r\n\r\nHere's the bit that matters: most of you are already halfway there. You've got the bookkeeping. You've got the software access. You understand the client's business better than anyone else they pay. The only thing missing is naming it.\r\n\r\nI recorded a short video on exactly how to spot which of your clients are already asking these mid-year questions, whether they realise it or not. No pitch attached \u2014 just wanted you to see it.\r\n\r\n[Watch \u2014 90 seconds \u2192]\r\n\r\nCurious \u2014 does the \"how's the business doing\" moment sound familiar? Hit reply, I read every one.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 2, date: '2026-10-04', time: '8:00am',\r\n        stage: 'PLV2 \u2014 Proof & technique',\r\n        segment: 'Full list',\r\n        title: \"The report that changed how one client saw us\",\r\n        preheader: \"A true story, and the actual report \u2014 screen recording inside\",\r\n        purpose: \"Real case study + a genuinely usable technique (the report structure) they can take and use even if they never buy anything.\",\r\n        cta: 'Watch the full walkthrough',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: 'Screen-recording walkthrough of the actual management accounts report \u2014 3-4 min, Rachel narrating',\r\n        body: `I want to tell you about one specific client, because it's the moment I actually understood what this service was worth.\r\n\r\nShe ran a small events business. Good client, always paid on time, never any drama. Every year I filed her accounts, she said thanks, and that was that.\r\n\r\nThen one quarter I started sending her a simple management accounts report \u2014 nothing fancy, just revenue by event type, a rough cashflow picture, and one line flagging that her biggest client made up nearly 40% of her income.\r\n\r\nShe called me the day she got it. Not to complain. She said nobody had ever shown her that before, and it changed a decision she was about to make about turning down other work to focus entirely on that one client.\r\n\r\nThat call is the reason this became its own service in my practice. So I recorded a proper walkthrough of that exact report, start to finish, so you can see what I mean rather than just take my word for it \u2014 the layout, what I chose to flag and why, all of it.\r\n\r\n[Watch the walkthrough \u2192]\r\n\r\nThis one's free to take and use regardless of anything else \u2014 steal the structure if it's useful.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 3, date: '2026-10-07', time: '8:00am',\r\n        stage: 'PLV3 \u2014 Transformation, objections & the reveal',\r\n        segment: 'Full list',\r\n        title: \"This time next year, what does your fee list look like?\",\r\n        preheader: \"Same clients, one new line \u2014 plus what's coming Monday\",\r\n        purpose: \"Future-pace the transformation, handle the two live objections head-on, then reveal cart opens Monday with early bird pricing.\",\r\n        cta: 'Watch: is my client base too small?',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: \"Short direct-to-camera answering the 'my clients are too small' objection \u2014 90 sec\",\r\n        body: `Picture your client list a year from now.\r\n\r\nSame clients, mostly. Maybe a couple more. But next to each name there's a second line \u2014 a recurring management accounts fee, sitting quietly alongside the compliance work you're already doing for them anyway.\r\n\r\nI know the two things you're probably weighing up, so let me answer them directly:\r\n\r\n\"I don't have capacity for another service.\" You already have the data \u2014 this isn't a new deliverable from scratch, it's a repackaging of information you're mostly already holding.\r\n\r\n\"My clients are too small for this.\" I made a short video answering this one directly, because it's the question I get asked the most \u2014 and the honest answer might surprise you.\r\n\r\n[Watch: is my client base too small? \u2192]\r\n\r\nNow \u2014 the bit I've been building towards all week. I've turned everything from this week (the framework, the report template, the pricing scripts) into a proper course: Management Accounts. It opens this Monday, 9 October, with early bird pricing for the first week.\r\n\r\nMore on that Monday. Just wanted you to hear it here first.\r\n\r\nRach X`\r\n      }\r\n    ],\r\n    emails: [\r\n      {\r\n        n: 1, date: '2026-10-08\/09', time: '8:00am',\r\n        segment: 'Boardroom members 8 Oct (day ahead) \u2192 full list 9 Oct',\r\n        subject: \"It's open \u2014 Management Accounts (early bird ends 16 Oct)\",\r\n        preheader: \"Everything from the last week, turned into a course \u2014 \u00a3100 off this week only\",\r\n        purpose: 'Cart open \/ full offer reveal \u2014 the ask, now that PLV1-3 have done the belief-shift work',\r\n        cta: 'Join Management Accounts',\r\n        video: false,\r\n        body: `It's open.\r\n\r\nOver the last week I've walked you through the mid-year \"how's the business doing\" gap, shown you the actual report that changed how one client saw us, and answered the two objections I hear most about this service. If you've been following along, you've already got a genuine head start \u2014 this is where it becomes a proper, repeatable service in your practice.\r\n\r\nManagement Accounts walks you through exactly how I built this service line into my own practice \u2014 from the first client conversation through to the report they actually look forward to receiving.\r\n\r\nWhat's inside:\r\n\u2014 The management accounts framework I use with clients, start to finish\r\n\u2014 Pricing scripts \u2014 how to introduce it without it sounding like an upsell\r\n\u2014 The report template itself, ready to adapt to your practice\r\n\u2014 How to deliver it without it becoming another full day of unpaid admin\r\n\u2014 Client conversation scripts for the ones who've never had this before\r\n\r\nEarly bird this week only: \u00a31,100 + VAT instead of \u00a31,200, ends 16 October. One payment, or spread it over 3 months if that works better for you.\r\n\r\nDoors close 30 October at midnight.\r\n\r\n[Join Management Accounts \u2192]\r\n\r\nAny questions, just reply \u2014 I read every one of these.\r\n\r\nRach X\r\n\r\nP.S. Not for you? No problem, click here and I'll leave you out of the rest of my emails about this one.`\r\n      },\r\n      {\r\n        n: 2, date: '2026-10-15', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"Early bird ends tomorrow (\u00a3100 off, then it's gone)\",\r\n        preheader: \"Last day at \u00a31,100 + VAT \u2014 standard price from 16 October\",\r\n        purpose: 'Price-increase alert \u2014 early bird closing, cost-framed',\r\n        cta: 'Lock in the early bird price today',\r\n        video: false,\r\n        body: `Quick one today.\r\n\r\nThe early bird price on Management Accounts ends tomorrow. From 16 October it goes back to the standard \u00a31,200 + VAT \u2014 today and tomorrow are the last chance at \u00a31,100 + VAT.\r\n\r\nIf you've got even three clients who'd genuinely benefit from monthly or quarterly management accounts \u2014 and most practices have more than three \u2014 and you priced that service at even \u00a3150 a month each, that's \u00a35,400 a year you're currently leaving on the table. Per three clients.\r\n\r\nThe thing that stops most of us isn't the accounting \u2014 you already know how to read a set of numbers. It's not having a template, a process, or the confidence to price it properly.\r\n\r\n[Lock in the early bird price \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 3, date: '2026-10-19', time: '9:00am',\r\n        segment: 'Full list',\r\n        subject: \"What's actually in Management Accounts (module by module)\",\r\n        preheader: \"For anyone who's opened this and wanted the detail before deciding\",\r\n        purpose: 'Mid-cart curriculum deep-dive \u2014 for warm-but-undecided readers who want specifics before committing',\r\n        cta: 'See the full breakdown',\r\n        video: false,\r\n        body: `A few of you have replied asking for more detail on what's actually inside, so here it is properly.\r\n\r\nManagement Accounts is four modules:\r\n1. The framework \u2014 what goes in a report and why, mapped to what different client types actually care about\r\n2. Pricing it \u2014 the scripts I use to introduce this as a paid service without it landing as an upsell\r\n3. The template \u2014 the actual report structure, ready to adapt, not built from scratch\r\n4. Delivering it \u2014 how to run this monthly or quarterly without it eating a full extra day per client\r\n\r\n11 days left at \u00a31,200 + VAT (early bird has now closed), one payment or spread over 3 months.\r\n\r\n[See the full breakdown \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 4, date: '2026-10-22', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"\\\"I wish I'd done this years ago\\\"\",\r\n        preheader: \"What early joiners are already saying \u2014 8 days left\",\r\n        purpose: 'Social proof \u2014 genuine reaction from early-bird buyers, addresses \"is this actually worth it\" doubt',\r\n        cta: 'Join Management Accounts',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: \"Short screen-recording of 2-3 real early-buyer replies\/DMs (with permission), Rachel reading them out \u2014 90 sec\",\r\n        body: `Since doors opened, a few of the early joiners have messaged back, and I wanted to share a couple (with permission):\r\n\r\n\"I've been doing this for free for three clients for years and just never named it. This is going to change my fee list.\"\r\n\r\n\"The pricing script alone was worth it \u2014 I've been putting off having that conversation for months.\"\r\n\r\nI recorded a short video reading a couple of these out properly, because it says more than I can in a paragraph.\r\n\r\n[Watch \u2192]\r\n\r\n8 days left at \u00a31,200 + VAT.\r\n\r\n[Join Management Accounts \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 5, date: '2026-10-27', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"Your questions about Management Accounts, answered\",\r\n        preheader: \"Capacity, small clients, refunds \u2014 the honest answers\",\r\n        purpose: 'FAQ\/objection roundup \u2014 distinct from PLV3, addresses questions that have actually come in via replies since cart open',\r\n        cta: 'Join before doors close',\r\n        video: false,\r\n        body: `A round-up of what's actually been asked this week, so nobody's sitting on a question that's stopping them from joining.\r\n\r\n\"I don't have capacity for another service.\" You already hold the data \u2014 this is a repackaging exercise, not a new deliverable from scratch. Module 4 covers exactly how to deliver it without it eating a full extra day per client.\r\n\r\n\"My clients are too small for this.\" Covered this properly in a video earlier in the week \u2014 short answer, size matters far less than you'd think. [Watch it here \u2192] if you missed it.\r\n\r\n\"What if I start and it's not for me?\" 14-day money-back, no questions.\r\n\r\n\"Can I split the payment?\" Yes \u2014 3-month plan available at checkout, same total price.\r\n\r\nDoors close Friday at midnight.\r\n\r\n[Join before doors close \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 6, date: '2026-10-30', time: '5:00pm (resend 9:30pm to non-openers)',\r\n        segment: 'Full list, then non-openers only for resend',\r\n        subject: \"Closes tonight \u2014 Management Accounts\",\r\n        resendSubject: \"Last call (genuinely, midnight)\",\r\n        preheader: \"Midnight, then it's gone until the next cohort\",\r\n        purpose: 'Final close \u2014 deadline, what is lost after, non-opener resend',\r\n        cta: 'Join before midnight',\r\n        video: false,\r\n        body: `Doors close tonight.\r\n\r\nAfter midnight, Management Accounts closes and I don't have a confirmed date for the next cohort \u2014 it might be a while.\r\n\r\nIf you've been on the fence, here's the honest version: nothing about this gets easier by waiting. The clients who'd benefit from this service are sitting in your client list right now, today, whether or not you do anything about it.\r\n\r\n[Join before midnight \u2192]\r\n\r\nThank you to everyone who's already joined \u2014 properly excited to get started with you.\r\n\r\nRach X\r\n\r\nP.S. If you're getting this and you've already joined, ignore me, and thank you.\r\n\r\n---\r\nRESEND (non-openers only, 9:30pm):\r\nQuick one - doors close in a couple of hours and I know inboxes are chaos, so in case this got buried: [Join before midnight \u2192]. No hard feelings if it's a no, just didn't want you to miss the deadline by accident.`\r\n      }\r\n    ],\r\n    socials: [\r\n      {\r\n        type: 'Reframe post 1', date: '2026-10-12', platforms: ['Instagram','LinkedIn'],\r\n        angle: \"A set of annual accounts is a photograph. Management accounts is the video.\",\r\n        ig: \"A set of annual accounts is a photograph. Management accounts is the video.\\n\\nOne shows you where you were. The other shows you what's actually happening, while there's still time to do something about it.\\n\\nMost practices only ever sell the photograph.\",\r\n        linkedin: \"A set of annual accounts is a photograph \u2014 a single moment, already months old by the time the client sees it.\\n\\nManagement accounts is the video. Ongoing, current, useful for an actual decision rather than a historical record.\\n\\nMost practices have built their entire service offering around the photograph. Which means most practices are leaving the far more valuable, far more frequent service completely on the table.\\n\\nIf you already hold the data (and you do \u2014 it's sitting in the same bookkeeping file), the only thing missing is naming it, packaging it, and charging for it separately.\"\r\n      },\r\n      {\r\n        type: 'Reframe post 2', date: '2026-10-15', platforms: ['Instagram','LinkedIn'],\r\n        angle: \"We don't undercharge for management accounts. We never charge for it at all.\",\r\n        ig: \"We don't undercharge for management accounts.\\n\\nWe just never name it as a separate thing \u2014 so it quietly becomes 'a bit of extra bookkeeping' instead of the service it actually is.\",\r\n        linkedin: \"Ask most practice owners if they undercharge for management accounts, and they'll say no \u2014 they don't offer management accounts.\\n\\nAsk them if they ever pull together a P&L summary, flag a cashflow issue, or answer 'how's the business doing' mid-year for a client, and most will say yes, regularly.\\n\\nThat's the same service. It's just never been named, packaged, or priced as its own line \u2014 so it happens for free, buried inside compliance work, instead of becoming the highest-margin recurring service in the practice.\"\r\n      },\r\n      {\r\n        type: 'Carousel', date: '2026-10-19', platforms: ['Instagram'],\r\n        title: \"5 signs a client is ready for management accounts (and doesn't know it yet)\",\r\n        slides: [\r\n          \"HOOK: 5 signs a client is ready for management accounts (and doesn't know it yet)\",\r\n          \"1. They ask 'how are we doing?' between year-ends \u2014 that's a management accounts question, not small talk.\",\r\n          \"2. They've mentioned a big decision coming up (hiring, a lease, a new product) \u2014 they need current numbers, not last year's.\",\r\n          \"3. One client or product dominates their revenue and they've never had it flagged.\",\r\n          \"4. They chase you for numbers instead of you sending them proactively.\",\r\n          \"TENSION: Every one of these is a service gap right now, not a future opportunity. It's costing you fee revenue every month it stays unfilled.\",\r\n          \"CTA: Management Accounts opens Monday \u2014 link in bio.\"\r\n        ]\r\n      },\r\n      {\r\n        type: 'Short-form video 1', date: '2026-10-14', platforms: ['TikTok','YouTube Shorts'],\r\n        hook: \"The client who nearly left because we never showed them this number...\",\r\n        pivot: \"Reveal: it was margin by product line \u2014 she didn't know one service was actively losing her money until we finally showed her.\",\r\n        consequence: \"Without visibility like this, you're one bad quarter away from losing a client and never finding out why.\",\r\n        close: \"Management Accounts opens Monday \u2014 link in bio.\"\r\n      },\r\n      {\r\n        type: 'Short-form video 2', date: '2026-10-23', platforms: ['TikTok','YouTube Shorts'],\r\n        hook: \"Two accountants. Same size client list. \u00a340k fee gap. Here's the one service that explains it.\",\r\n        pivot: \"One offers management accounts as a recurring line. The other does the identical work for free, buried inside compliance.\",\r\n        consequence: \"Same hours worked, a third of the revenue, for the accountant giving it away.\",\r\n        close: \"Doors close 30 October \u2014 link in bio.\"\r\n      }\r\n    ]\r\n  },\r\n  {\r\n    id: 'boardroom-jan27',\r\n    name: \"Accountants Boardroom & Marketing Boardroom (new cohorts)\",\r\n    status: 'complete',\r\n    price: '\u00a31,000 + VAT\/month \u00d7 6, or pay upfront (\u00a37,200 gross total per seat)',\r\n    salesUrl: 'https:\/\/accountantshe.com\/boardroom (PLACEHOLDER \u2014 confirm real URL)',\r\n    cartOpen: '2027-01-04',\r\n    cartClose: '2027-01-22',\r\n    earlyBird: { discount: '\u00a3100 off total package', standardPrice: '\u00a36,000 total ex-VAT (\u00a31,000+VAT\/month x6)', earlyBirdPrice: '\u00a35,900 total ex-VAT (~\u00a3983.33+VAT\/month)', endDate: '2027-01-08', rule: '>\u00a3500 ex-VAT' },\r\n    milestones: [\r\n      { date: '2026-12-28', label: 'PLV1 \u2014 belief-shift piece goes out' },\r\n      { date: '2026-12-31', label: 'PLV2 \u2014 proof\/technique piece goes out' },\r\n      { date: '2027-01-03', label: 'PLV3 \u2014 transformation + big reveal goes out' },\r\n      { date: '2027-01-04', label: 'Cart opens \u2014 early bird pricing live (both rooms)' },\r\n      { date: '2027-01-08', label: 'Early bird ends \u2014 price rises to standard \u00a36,000 ex-VAT' },\r\n      { date: '2027-01-22', label: 'Cart closes \/ rooms lock' }\r\n    ],\r\n    theme: \"Most masterminds are big enough to hide in. This is ten seats \u2014 everyone gets asked directly what they're stuck on, every time.\",\r\n    outcome: \"By the end of the campaign, readers know which room fits them (Accountants vs Marketing Boardroom), understand the cap is genuinely ten seats each with no waitlist, and feel the accountability of a small room is worth more than the content of any single session.\",\r\n    prelaunch: [\r\n      {\r\n        n: 1, date: '2026-12-28', time: '8:00am',\r\n        stage: 'PLV1 \u2014 Belief shift',\r\n        segment: 'Full list',\r\n        title: \"You don't have a knowledge problem\",\r\n        preheader: \"Something worth thinking about before the January noise starts\",\r\n        purpose: \"Collapse the belief that another course\/resource fixes stalled progress \u2014 the real gap is accountability, not information.\",\r\n        cta: 'Reply and tell me \u2014 what did you not finish this year?',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: \"60-90 sec direct-to-camera, Rachel \u2014 why more content isn't the fix\",\r\n        body: `Before the \"new year, new plan\" emails start flooding in from everyone (including probably me), I wanted to say something a bit different.\r\n\r\nAlmost nobody keeps a resolution past February. Not because the plan was wrong \u2014 because nobody's checking. You know exactly what you should be doing in your practice right now. You've probably known for months. The thing missing isn't another course explaining it to you again.\r\n\r\nI filmed a quick one on this \u2014 it took me running group programmes for a while to actually see it: the people who change something aren't the ones who learn the most, they're the ones who have to answer to someone.\r\n\r\n[Watch \u2014 90 seconds \u2192]\r\n\r\nWhat's the thing you didn't get to this year? Hit reply, genuinely curious.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 2, date: '2026-12-31', time: '8:00am',\r\n        stage: 'PLV2 \u2014 Proof & technique',\r\n        segment: 'Full list',\r\n        title: \"I shrank a group from 20 people to 10. Here's exactly what changed.\",\r\n        preheader: \"New Year's Eve \u2014 a real story about why most groups don't work\",\r\n        purpose: \"Genuine case study\/technique \u2014 the real reasoning behind small-group accountability, usable even without joining anything.\",\r\n        cta: 'Watch the full explanation',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: 'Rachel to camera explaining the 20-person vs 10-person group experience \u2014 3 min',\r\n        body: `Fitting day for this one.\r\n\r\nI ran a group coaching thing a while back \u2014 twenty people, one big call a month. It was fine. Nobody complained. But I noticed the same handful of people talked every single call, and most of the rest mostly listened, took notes, and never actually got unstuck on their specific problem.\r\n\r\nTwenty is enough to hide in. I recorded a proper explanation of what changed when I shrank it right down \u2014 the honest, slightly uncomfortable truth about why bigger groups let people coast, and what actually has to be true for a room to create real accountability.\r\n\r\n[Watch the full explanation \u2192]\r\n\r\nThis one's free to think about regardless of anything else \u2014 if you run any kind of group yourself, worth considering for your own.\r\n\r\nIf you want your own version of this kind of accountability for the year ahead, keep an eye on your inbox \u2014 more in a couple of days.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 3, date: '2027-01-03', time: '8:00am',\r\n        stage: 'PLV3 \u2014 Transformation, objections & the reveal',\r\n        segment: 'Full list',\r\n        title: \"Six months from now, with someone actually checking in\",\r\n        preheader: \"Plus what's opening tomorrow\",\r\n        purpose: \"Future-pace the transformation, handle the 'I've tried group things and hated them' objection, then reveal cart opens tomorrow.\",\r\n        cta: 'Nothing to click yet \u2014 more tomorrow',\r\n        video: false,\r\n        body: `Picture this time next year. Not a resolution \u2014 an actual six months where you weren't figuring it out alone.\r\n\r\nI know some of you have tried group coaching before and it didn't land \u2014 too big, too generic, or the accountability never actually materialised. Fair. Most of it is built that way, for scale, not for you individually.\r\n\r\nSo here's what I'm opening tomorrow: two small rooms, ten seats each \u2014 Accountants Boardroom and Marketing Boardroom. Six months, six sessions, actual access to me, and nine other people who'll notice if you show up having not done the thing.\r\n\r\nEarly bird pricing for the first few days. More tomorrow.\r\n\r\nRach X`\r\n      }\r\n    ],\r\n    emails: [\r\n      {\r\n        n: 1, date: '2027-01-04\/05', time: '8:00am',\r\n        segment: 'Existing Boardroom members 4 Jan (day ahead) \u2192 full list 5 Jan',\r\n        subject: \"Ten seats. That's it. (both rooms open)\",\r\n        preheader: \"As mentioned this week \u2014 two rooms, ten seats each, early bird live\",\r\n        purpose: 'Cart open \/ full offer reveal \u2014 the ask, now that PLV1-3 have done the belief-shift work',\r\n        cta: 'Claim the early bird price before 8 January',\r\n        video: false,\r\n        body: `Happy new year \u2014 and as promised, it's open.\r\n\r\nTwo rooms. Accountants Boardroom, for anyone whose actual bottleneck is the practice itself \u2014 team, systems, pricing, capacity. And Marketing Boardroom, for anyone building an audience or content business alongside the compliance work.\r\n\r\nBoth capped at ten. Both six months, six sessions, and actual access to me \u2014 not a template, not a replay.\r\n\r\nBoth rooms have early bird pricing right now \u2014 \u00a3100 off the total, ending 8 January. After that it's back to full price.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 2, date: '2027-01-07', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"Early bird ends tomorrow \u2014 plus, which room is right for you?\",\r\n        preheader: \"\u00a3100 off, gone from tomorrow \u2014 here's the honest breakdown of each room\",\r\n        purpose: 'Price-increase alert + reminder \u2014 help reader self-select track',\r\n        cta: \"Claim the early bird price before it ends tomorrow\",\r\n        video: false,\r\n        body: `Quick one today \u2014 two things.\r\n\r\nFirst: the early bird price on both Boardrooms ends tomorrow. From 8 January it's back to full price.\r\n\r\nSecond, I got a few replies asking which room is actually for who.\r\n\r\nAccountants Boardroom is for you if the thing keeping you up at night is the practice itself \u2014 team, systems, pricing, capacity, the stuff that makes running the business harder than doing the accounting.\r\n\r\nMarketing Boardroom is for you if you're already building something alongside the compliance work \u2014 content, an audience, a personal brand \u2014 and you want six months of real feedback instead of guessing in a vacuum.\r\n\r\nBoth rooms: ten seats, six months, six sessions. Both close the moment they're full \u2014 I mean that literally, not as a sales tactic. There's no version of this with a seventh seat.\r\n\r\nDoors open Monday.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 3, date: '2027-01-11', time: '9:00am',\r\n        segment: 'Full list',\r\n        subject: \"Both rooms are open (6 seats each)\",\r\n        preheader: \"\u00a31,000+VAT\/month x6, or pay upfront \u2014 closes when full, not by date\",\r\n        purpose: 'Launch day \/ doors open \u2014 full offer detail',\r\n        cta: 'Claim your seat',\r\n        video: false,\r\n        body: `Both rooms are open.\r\n\r\nAccountants Boardroom and Marketing Boardroom \u2014 ten seats each, six sessions, running through the first half of the year.\r\n\r\nWhat's inside either room:\r\n\u2014 Six live sessions, small enough that everyone actually gets airtime\r\n\u2014 Direct access to me between sessions, not just during them\r\n\u2014 Nine other people at a genuinely similar stage \u2014 no beginners drowning out advanced conversations, no advanced members bored by basics\r\n\u2014 A structure built around accountability, not just content \u2014 you'll be expected to show up having done the thing you said you'd do\r\n\r\n\u00a31,000 + VAT per month for six months, or pay the full amount upfront if you'd rather. Either way, you're committing to all six sessions \u2014 this isn't pay-as-you-go.\r\n\r\nTen seats each. When they're gone, they're gone \u2014 I'm not opening a waitlist for a \"maybe next time,\" because there might not be a next time this year.\r\n\r\n[Claim your seat \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 4, date: '2027-01-14', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"What existing Boardroom members actually say\",\r\n        preheader: \"Real feedback from the current room \u2014 8 days left at early bird\",\r\n        purpose: 'Social proof \u2014 genuine reaction from existing members, addresses \"is this actually different\" doubt',\r\n        cta: 'Claim your seat',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: \"Short screen-recording of 2-3 real existing-member quotes (with permission), Rachel reading them out \u2014 90 sec\",\r\n        body: `A few existing Boardroom members have said things recently I wanted to pass on (with permission):\r\n\r\n\"I've been in bigger groups before. This is the first one where I actually did the thing between sessions, because I knew I'd have to say so.\"\r\n\r\n\"Worth it for the access alone \u2014 I've messaged Rachel between sessions more than I expected to and always got a real answer.\"\r\n\r\nI recorded a short video reading a couple of these properly.\r\n\r\n[Watch \u2192]\r\n\r\nBoth rooms filling. [Claim your seat \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 5, date: '2027-01-19', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"Your questions about the Boardroom, answered\",\r\n        preheader: \"Payment, which room, seat counts \u2014 the honest answers\",\r\n        purpose: 'FAQ\/objection roundup \u2014 distinct from PLV3, addresses real reader questions since cart open',\r\n        cta: 'Claim your seat',\r\n        video: false,\r\n        body: `What's actually been asked this week, so nobody's stuck on a question:\r\n\r\n\"Can I switch rooms after joining?\" Once, in the first two weeks, if it's genuinely not the right fit \u2014 after that you're committed to that room's cohort.\r\n\r\n\"What if I can't make a session live?\" Sessions are recorded, but the accountability model works best live \u2014 this isn't built as an on-demand product.\r\n\r\n\"Monthly or upfront \u2014 does it matter which?\" No difference in what you get, just cashflow preference.\r\n\r\nSeats update: [CONFIRM REAL COUNT] left in Accountants Boardroom, [CONFIRM REAL COUNT] left in Marketing Boardroom.\r\n\r\n[Claim your seat \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 6, date: '2027-01-22', time: '5:00pm (resend 9:30pm to non-openers)',\r\n        segment: 'Full list, then non-openers only for resend',\r\n        subject: \"Last few seats \u2014 both rooms\",\r\n        resendSubject: \"Genuinely down to the wire\",\r\n        preheader: \"After this, both rooms are locked for the year\",\r\n        purpose: 'Final close \u2014 deadline, what is lost after, non-opener resend',\r\n        cta: \"Claim your seat before it's gone\",\r\n        video: false,\r\n        body: `This is the last email about the Boardrooms.\r\n\r\nBoth rooms are close to full. Once the tenth seat goes in either one, that's it \u2014 no waitlist, no \"let me know if a spot opens up,\" just locked until (if) I run this again.\r\n\r\nIf you've been sat on the fence, the honest push is this: the version of you six months from now with nine people checking in on your actual progress is meaningfully different from the version who kept meaning to figure it out alone.\r\n\r\n[Claim your seat before it's gone \u2192]\r\n\r\nThank you to everyone who's already grabbed a seat \u2014 genuinely excited for both rooms.\r\n\r\nRach X\r\n\r\nP.S. If you've already joined, ignore this, and thank you.\r\n\r\n---\r\nRESEND (non-openers only, 9:30pm):\r\nGenuinely down to the wire \u2014 [CONFIRM REAL COUNT] seats left combined across both rooms as of right now. If you've been meaning to, this is the moment. [Claim your seat \u2192]`\r\n      }\r\n    ],\r\n    socials: [\r\n      {\r\n        type: 'Reframe post 1', date: '2027-01-05', platforms: ['Instagram','LinkedIn'],\r\n        angle: \"Most masterminds are a big room where you can hide. This one has ten seats.\",\r\n        ig: \"Most masterminds are a big room where you can hide.\\n\\nThis one has ten seats. Nobody hides. Everyone gets asked directly what they're stuck on, every session.\",\r\n        linkedin: \"Most group coaching programmes are built to scale \u2014 bigger rooms, more revenue per call, less airtime per person.\\n\\nI built this one the opposite way. Ten seats, full stop. Not because smaller sounds more premium, but because I ran a twenty-person version of this once and watched the same handful of people talk every time while most of the rest took notes and never got unstuck.\\n\\nTen is still small enough that nobody gets to coast. Two rooms opening 11 January \u2014 Accountants Boardroom and Marketing Boardroom, ten seats each.\"\r\n      },\r\n      {\r\n        type: 'Reframe post 2', date: '2027-01-10', platforms: ['Instagram','LinkedIn'],\r\n        angle: \"You don't need more content. You need nine people asking what happened since last time.\",\r\n        ig: \"You don't need more content.\\n\\nYou need nine people asking what happened since last time you said you'd fix it.\",\r\n        linkedin: \"Most of us don't have a knowledge problem. We know what we should be doing.\\n\\nWhat's actually missing is the accountability \u2014 someone checking in on the thing you said you'd do, on a schedule you can't quietly ignore.\\n\\nThat's the entire premise behind the Boardroom. Ten seats, six sessions, six months of someone actually asking.\"\r\n      },\r\n      {\r\n        type: 'Carousel', date: '2027-01-11', platforms: ['Instagram'],\r\n        title: \"Is the Boardroom right for you? 5 questions to ask yourself\",\r\n        slides: [\r\n          \"HOOK: Is the Boardroom right for you? 5 questions to ask yourself\",\r\n          \"1. Do you already know what you should be doing, but keep not doing it?\",\r\n          \"2. Have you tried a bigger group programme and felt like you disappeared into it?\",\r\n          \"3. Is the thing you're stuck on about the practice itself (team, systems, capacity) \u2014 or about building an audience\/content alongside it?\",\r\n          \"4. Would you actually show up if nine other people were expecting you to?\",\r\n          \"TENSION: If you answered yes to the first two, more content won't fix it. A smaller room might.\",\r\n          \"CTA: Two rooms, ten seats each. Doors open now \u2014 link in bio.\"\r\n        ]\r\n      },\r\n      {\r\n        type: 'Short-form video 1', date: '2027-01-07', platforms: ['TikTok','YouTube Shorts'],\r\n        hook: \"I shrank this from 20 people to 10. Here's what changed.\",\r\n        pivot: \"With 20, the same handful of people talked every call. With 10, everyone gets asked directly \u2014 there's nowhere to hide.\",\r\n        consequence: \"A big room lets you pay for accountability and never actually experience any.\",\r\n        close: \"Two rooms opening 11 January, ten seats each \u2014 link in bio.\"\r\n      },\r\n      {\r\n        type: 'Short-form video 2', date: '2027-01-15', platforms: ['TikTok','YouTube Shorts'],\r\n        hook: \"The real reason most masterminds don't work (it's not the content).\",\r\n        pivot: \"It's room size. Past a certain number, nobody's individually accountable to anyone.\",\r\n        consequence: \"You can sit in a 200-person group for a year and still be exactly where you started.\",\r\n        close: \"Ten seats left across both rooms \u2014 link in bio.\"\r\n      }\r\n    ]\r\n  },\r\n  {\r\n    id: 'ltdco-relaunch',\r\n    name: 'Ltd Co Accounts & Corporation Tax \u2014 relaunch',\r\n    status: 'complete',\r\n    price: '\u00a31,500 + VAT',\r\n    salesUrl: 'https:\/\/accountantshe.com\/ltd-co-accounts (PLACEHOLDER \u2014 confirm real URL)',\r\n    cartOpen: '2026-11-25',\r\n    cartClose: '2026-12-16',\r\n    earlyBird: { discount: '\u00a3100 off', standardPrice: '\u00a31,500 + VAT', earlyBirdPrice: '\u00a31,400 + VAT', endDate: '2026-12-02', rule: '>\u00a3500 ex-VAT' },\r\n    milestones: [\r\n      { date: '2026-11-18', label: 'PLV1 \u2014 belief-shift piece goes out' },\r\n      { date: '2026-11-21', label: 'PLV2 \u2014 proof\/technique piece goes out' },\r\n      { date: '2026-11-23', label: 'PLV3 \u2014 transformation + big reveal goes out' },\r\n      { date: '2026-11-25', label: 'Cart opens \u2014 early bird pricing live' },\r\n      { date: '2026-12-02', label: 'Early bird ends \u2014 price rises to \u00a31,500+VAT' },\r\n      { date: '2026-12-16', label: 'Cart closes' }\r\n    ],\r\n    theme: \"This isn't a new course needing a new pitch \u2014 it's the flagship everyone already trusts, that just stopped being in front of people. Most of the list has grown since they last saw it.\",\r\n    outcome: \"By the end of the campaign, readers who've been putting off taking on Ltd Co work feel the course is the fastest, most proven route in, and past-cohort students feel confident referring colleagues rather than treating it as old news.\",\r\n    prelaunch: [\r\n      {\r\n        n: 1, date: '2026-11-18', time: '8:00am',\r\n        stage: 'PLV1 \u2014 Belief shift',\r\n        segment: 'Full list',\r\n        title: \"You don't have a skills gap. You have a process gap.\",\r\n        preheader: \"The real reason most of you turn down Ltd Co work\",\r\n        purpose: \"Collapse the belief that hesitancy around Ltd Co work is a technical-ability problem \u2014 it's almost always a missing tested process.\",\r\n        cta: 'Reply and tell me \u2014 have you referred away a Ltd Co client?',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: \"60-90 sec direct-to-camera, Rachel \u2014 skills gap vs process gap\",\r\n        body: `Something worth naming before I say anything about a course.\r\n\r\nMost of you already understand Ltd Co accounts in theory \u2014 bigger numbers, same underlying principles as sole trader work. So why does it still feel like a leap?\r\n\r\nIt's not a skills gap. It's a process gap \u2014 you're missing a tested working-papers file, not the technical ability to use one.\r\n\r\nThere's a specific moment I realised this myself that changed how I think about the whole thing \u2014 easier to show you than explain it in text, so I put it in a short video.\r\n\r\n[Watch \u2014 90 seconds \u2192]\r\n\r\nHave you ever referred a sole trader client elsewhere once they incorporated? Curious how common that actually is \u2014 hit reply.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 2, date: '2026-11-21', time: '8:00am',\r\n        stage: 'PLV2 \u2014 Proof & technique',\r\n        segment: 'Full list',\r\n        title: \"The first Ltd Co job I nearly got badly wrong\",\r\n        preheader: \"A real mistake, and the check that would have caught it\",\r\n        purpose: \"Real case study + a usable technique (the specific director's loan account check) they can take regardless of buying.\",\r\n        cta: 'Watch the full story',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: 'Rachel to camera, the specific working-papers mistake and what it cost \u2014 3-4 min',\r\n        body: `I want to tell you about the first limited company set of accounts I ever did solo, because I very nearly got something badly wrong.\r\n\r\nI'd done sole trader work for years by that point and assumed the transition would be straightforward \u2014 bigger numbers, same principles. It mostly was, except for one thing I hadn't properly understood about director's loan accounts, and I only caught it because a second reviewer happened to glance at my working papers before it went out.\r\n\r\nI recorded the full story, including the specific check that would have caught it earlier \u2014 steal it for your own working papers regardless of anything else.\r\n\r\n[Watch the full story \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 3, date: '2026-11-23', time: '8:00am',\r\n        stage: 'PLV3 \u2014 Transformation, objections & the reveal',\r\n        segment: 'Full list',\r\n        title: \"\\\"I've never done a Ltd Co set before\\\" \u2014 the honest answer\",\r\n        preheader: \"Plus what's opening Wednesday\",\r\n        purpose: \"Handle the top beginner objection directly, then reveal cart opens 25 Nov with early bird.\",\r\n        cta: 'Watch: is this for beginners too?',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: \"Short direct-to-camera addressing complete-beginner concerns \u2014 90 sec\",\r\n        body: `The question I get most on this topic: \"I've never done a limited company set before \u2014 is this actually for me, or for people already doing it who want to get better?\"\r\n\r\nBoth, honestly. I made a short video on exactly why.\r\n\r\n[Watch: is this for beginners too? \u2192]\r\n\r\nEverything from the last week \u2014 the process-gap reframe, the working papers, the checklist \u2014 is going into a proper course. Ltd Co Accounts & Corporation Tax opens Wednesday, 25 November, with early bird pricing.\r\n\r\nRach X`\r\n      }\r\n    ],\r\n    emails: [\r\n      {\r\n        n: 1, date: '2026-11-24\/25', time: '8:00am',\r\n        segment: 'Past SA\/CIS\/VAT students 24 Nov (day ahead) \u2192 full list 25 Nov',\r\n        subject: \"It's open \u2014 Ltd Co Accounts & Corporation Tax\",\r\n        preheader: \"As mentioned this week \u2014 early bird \u00a31,400+VAT until 2 December\",\r\n        purpose: 'Cart open \/ full offer reveal',\r\n        cta: 'Claim the early bird price before 2 December',\r\n        video: false,\r\n        body: `As promised this week, it's open.\r\n\r\nLtd Co Accounts & Corporation Tax is the one that turned \"I do Self Assessment\" into \"I run a proper practice\" for a huge number of you. We've been quiet about it lately \u2014 not because it stopped working, just because once something's been around a while, we all quietly assume everyone's already seen it.\r\n\r\nHalf the list today wasn't on it when we last talked about this properly.\r\n\r\nEarly bird price: \u00a31,400 + VAT (down from \u00a31,500) until 2 December.\r\n\r\nRach X\r\n\r\nP.S. Not for you? No problem, click here and I'll leave you out of the rest of these.`\r\n      },\r\n      {\r\n        n: 2, date: '2026-12-01', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"Early bird ends tomorrow (\u00a3100 off, then it's gone)\",\r\n        preheader: \"Last day at \u00a31,400 + VAT \u2014 standard price from 2 December\",\r\n        purpose: 'Price-increase alert \u2014 early bird closing, cost-framed',\r\n        cta: 'Lock in the early bird price today',\r\n        video: false,\r\n        body: `Quick one today.\r\n\r\nThe early bird price on Ltd Co Accounts & Corporation Tax ends tomorrow. From 2 December it's back to the standard \u00a31,500 + VAT.\r\n\r\nEvery sole trader client who incorporates and you don't feel ready to follow them into \u2014 that's not just one piece of work lost. That's the relationship, and everything that client refers afterwards, going to whoever picked up where you left off.\r\n\r\n[Lock in the early bird price \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 3, date: '2026-12-05', time: '9:00am',\r\n        segment: 'Full list',\r\n        subject: \"Ltd Co Accounts & Corporation Tax is open\",\r\n        preheader: \"\u00a31,500, doors close 16 December\",\r\n        purpose: 'Launch day \/ cart open \u2014 full offer detail',\r\n        cta: 'Join Ltd Co Accounts',\r\n        video: false,\r\n        body: `It's open.\r\n\r\nEverything you need to take on limited company accounts and corporation tax with actual confidence \u2014 not just the mechanics, but the client conversations, the pricing, and the review process that catches problems before they leave your desk.\r\n\r\nWhat's inside:\r\n\u2014 The full working papers file I use on every Ltd Co job\r\n\u2014 Pre-submission checklist, six sections, nothing skipped\r\n\u2014 Client email templates for the whole workflow\r\n\u2014 Pricing guidance for taking on your first (or fiftieth) limited company client\r\n\r\n\u00a31,500 + VAT. Doors close 16 December.\r\n\r\n[Join Ltd Co Accounts & Corporation Tax \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 4, date: '2026-12-08', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"What past Ltd Co Accounts students say now\",\r\n        preheader: \"Real feedback from people already using this on real jobs\",\r\n        purpose: 'Social proof \u2014 genuine reaction from past students, addresses \"does this actually hold up on real jobs\" doubt',\r\n        cta: 'Join Ltd Co Accounts',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: \"Short screen-recording of 2-3 real past-student quotes (with permission), Rachel reading them out \u2014 90 sec\",\r\n        body: `A few past students have said things I wanted to pass on (with permission):\r\n\r\n\"Took on my first Ltd Co client within a month of finishing this \u2014 the checklist alone gave me the confidence to quote properly.\"\r\n\r\n\"Wish I'd had this years ago instead of muddling through my first few sets.\"\r\n\r\nI recorded a short video reading a couple of these out properly.\r\n\r\n[Watch \u2192]\r\n\r\nDoors close in 8 days.\r\n\r\n[Join Ltd Co Accounts & Corporation Tax \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 5, date: '2026-12-13', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"Your questions about Ltd Co Accounts, answered\",\r\n        preheader: \"Refunds, payment plans, what's actually included\",\r\n        purpose: 'FAQ\/objection roundup \u2014 distinct from PLV3, addresses questions since cart open',\r\n        cta: 'Join before doors close',\r\n        video: false,\r\n        body: `What's actually been asked this week:\r\n\r\n\"Is the working papers file editable?\" Yes, fully \u2014 it's a template built to adapt to your own practice, not a locked PDF.\r\n\r\n\"Does this cover corporation tax filing itself, or just the accounts?\" Both \u2014 the course covers the full workflow end to end.\r\n\r\n\"What if I start and it's not for me?\" 14-day money-back, no questions.\r\n\r\nDoors close Friday at midnight.\r\n\r\n[Join before doors close \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 6, date: '2026-12-16', time: '5:00pm (resend 9:30pm to non-openers)',\r\n        segment: 'Full list, then non-openers only for resend',\r\n        subject: \"Closes tonight \u2014 Ltd Co Accounts\",\r\n        resendSubject: \"Last call (genuinely, midnight)\",\r\n        preheader: \"Midnight, then it's gone until the next relaunch\",\r\n        purpose: 'Final close \u2014 deadline, what is lost after, non-opener resend',\r\n        cta: 'Join before midnight',\r\n        video: false,\r\n        body: `Doors close tonight.\r\n\r\nIf you've got a sole trader client who's mentioned incorporating, or you've quietly been turning down limited company work because you didn't feel ready \u2014 this is the moment that stops being true.\r\n\r\n[Join before midnight \u2192]\r\n\r\nThank you to everyone who's already joined.\r\n\r\nRach X\r\n\r\n---\r\nRESEND (non-openers only, 9:30pm):\r\nQuick one - doors close in a couple of hours. In case this got buried: [Join before midnight \u2192]. No hard feelings if it's a no.`\r\n      }\r\n    ],\r\n    socials: [\r\n      {\r\n        type: 'Reframe post 1', date: '2026-11-28', platforms: ['Instagram','LinkedIn'],\r\n        angle: \"Turning down Ltd Co work doesn't just lose you one job \u2014 it loses you the relationship.\",\r\n        ig: \"Turning down a client's Ltd Co work doesn't just lose you one job.\\n\\nIt loses you the relationship, and everything they'd have referred you afterwards.\",\r\n        linkedin: \"When a sole trader client incorporates and you're not confident taking their limited company accounts on, the instinct is to think of it as losing one job.\\n\\nIt's rarely just one job. It's the relationship, and every referral that client would have sent your way once they trusted you with the bigger, more complex work.\\n\\nLtd Co Accounts & Corporation Tax is back open \u2014 built to close exactly this gap.\"\r\n      },\r\n      {\r\n        type: 'Reframe post 2', date: '2026-12-02', platforms: ['Instagram','LinkedIn'],\r\n        angle: \"It's not a new skill. It's the same principles, at a size that finally matters to your fee list.\",\r\n        ig: \"Limited company accounts aren't a different skill to sole trader work.\\n\\nSame principles, bigger numbers, and a fee list that finally reflects the complexity you're already capable of.\",\r\n        linkedin: \"The accountants who hesitate on limited company work usually aren't missing the technical ability \u2014 they're missing a process that's been proven end to end.\\n\\nThat's the actual gap this course closes: not new knowledge, a tested working-papers file and pre-submission checklist that catches what a first attempt usually misses.\"\r\n      },\r\n      {\r\n        type: 'Carousel', date: '2026-12-05', platforms: ['Instagram'],\r\n        title: \"5 signs you're ready to take on Ltd Co work (and probably already are)\",\r\n        slides: [\r\n          \"HOOK: 5 signs you're ready to take on Ltd Co work\",\r\n          \"1. You've referred a sole trader client elsewhere once they incorporated.\",\r\n          \"2. You already understand director's loan accounts in theory, just never applied it live.\",\r\n          \"3. You're confident with Self Assessment but nervous about the bigger numbers.\",\r\n          \"4. A client has asked outright and you gave a vague answer.\",\r\n          \"TENSION: Every one of these is a client you're one working-papers file away from keeping.\",\r\n          \"CTA: Ltd Co Accounts & Corporation Tax opens today \u2014 link in bio.\"\r\n        ]\r\n      },\r\n      {\r\n        type: 'Short-form video 1', date: '2026-11-30', platforms: ['TikTok','YouTube Shorts'],\r\n        hook: \"The client I referred away because I wasn't confident with Ltd Co accounts...\",\r\n        pivot: \"Reveal: it wasn't a skills gap, it was a process gap \u2014 no tested working papers to lean on.\",\r\n        consequence: \"That client, and everyone they'd have referred, went to someone else instead.\",\r\n        close: \"Ltd Co Accounts opens Monday \u2014 link in bio.\"\r\n      },\r\n      {\r\n        type: 'Short-form video 2', date: '2026-12-09', platforms: ['TikTok','YouTube Shorts'],\r\n        hook: \"Sole trader accountant vs Ltd Co accountant \u2014 same skills, very different fee list.\",\r\n        pivot: \"The technical leap is smaller than it feels. The confidence gap is the real barrier.\",\r\n        consequence: \"Every client who incorporates without you is a fee increase going to someone else.\",\r\n        close: \"Doors close 16 December \u2014 link in bio.\"\r\n      }\r\n    ]\r\n  },\r\n  {\r\n    id: 'cpd-bundle',\r\n    name: 'CPD Bundle (LCA, SA, VAT, CIS) \u2014 \"Back to School\"',\r\n    status: 'complete',\r\n    price: '\u00a33,318 (10% off the combined \u00a33,687 individual price)',\r\n    salesUrl: 'https:\/\/accountantshe.com\/cpd-bundle (PLACEHOLDER \u2014 confirm real URL)',\r\n    cartOpen: '2026-10-01',\r\n    cartClose: '2026-10-22',\r\n    dateFlag: \"\u26a0 PLACEHOLDER DATE \u2014 moved here to sit inside the Back to School window per Rebecca's instruction. Confirm with Rachel before this is finalised, since it now overlaps Management Accounts and Ltd Co relaunch (see collision note).\",\r\n    earlyBird: { discount: '\u00a3100 off', standardPrice: '\u00a33,318 + VAT', earlyBirdPrice: '\u00a33,218 + VAT', endDate: '2026-10-08', rule: '>\u00a3500 ex-VAT' },\r\n    milestones: [\r\n      { date: '2026-09-24', label: 'PLV1 \u2014 belief-shift piece goes out' },\r\n      { date: '2026-09-27', label: 'PLV2 \u2014 proof\/technique piece goes out' },\r\n      { date: '2026-09-30', label: 'PLV3 \u2014 transformation + big reveal goes out' },\r\n      { date: '2026-10-01', label: 'Cart opens \u2014 early bird pricing live (Back to School)' },\r\n      { date: '2026-10-08', label: 'Early bird ends \u2014 price rises to \u00a33,318+VAT' },\r\n      { date: '2026-10-22', label: 'Cart closes' }\r\n    ],\r\n    theme: \"Back to School: you're going to need all four of these eventually \u2014 this is the same content, bundled, at a genuine discount, once, rather than four separate full-price purchases spread across the year.\",\r\n    outcome: \"By the end of the campaign, readers who own 1-2 of the four courses already see the bundle as the obvious way to complete their CPD coverage, and readers who own none see it as the fastest route to full compliance coverage in one go.\",\r\n    prelaunch: [\r\n      {\r\n        n: 1, date: '2026-09-24', time: '8:00am',\r\n        stage: 'PLV1 \u2014 Belief shift',\r\n        segment: 'Full list',\r\n        title: \"The real cost of buying CPD \\\"just in time\\\"\",\r\n        preheader: \"It's not just the price \u2014 it's the client you turn down meanwhile\",\r\n        purpose: \"Collapse the belief that waiting until a client need arises to buy CPD is a neutral, cost-free choice.\",\r\n        cta: 'Reply \u2014 which of these four do you not have yet?',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: \"60-90 sec direct-to-camera, Rachel \u2014 the hidden cost of buying CPD reactively\",\r\n        body: `Something worth thinking about before I mention anything for sale.\r\n\r\nMost of us buy CPD reactively \u2014 a client needs CIS work, so we scramble to learn CIS that week. It feels efficient. It isn't, quite.\r\n\r\nThe actual cost isn't just paying full price under time pressure. It's the client you turned down, or nearly got wrong, in the gap before you'd covered it.\r\n\r\nPut together a short video on this \u2014 it's a pattern that only became obvious once I looked across a whole year instead of one client at a time.\r\n\r\n[Watch \u2014 90 seconds \u2192]\r\n\r\nCurious \u2014 which of Ltd Co, Self Assessment, VAT, or CIS are you missing right now? Hit reply.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 2, date: '2026-09-27', time: '8:00am',\r\n        stage: 'PLV2 \u2014 Proof & technique',\r\n        segment: 'Full list',\r\n        title: \"The 4-question audit for full-practice coverage\",\r\n        preheader: \"A genuinely useful self-check, whether or not you buy anything\",\r\n        purpose: \"Real, usable technique \u2014 a coverage self-audit \u2014 plus the logic for why these four specifically make up full-practice CPD.\",\r\n        cta: 'Watch the full breakdown',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: 'Rachel walking through why these 4 specifically form full-practice CPD coverage, and how to self-audit \u2014 3 min',\r\n        body: `Between Ltd Co Accounts, Self Assessment, VAT, and CIS, you've got compliance coverage for basically every client type a general practice sees \u2014 sole traders, limited companies, VAT-registered businesses, and construction industry work.\r\n\r\nI recorded a proper walkthrough of how these four fit together, plus a quick 4-question self-audit you can run against your own client list right now to see exactly where your coverage gaps actually are.\r\n\r\n[Watch the full breakdown \u2192]\r\n\r\nFree to run regardless of anything else \u2014 worth doing even if you're not buying.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 3, date: '2026-09-30', time: '8:00am',\r\n        stage: 'PLV3 \u2014 Transformation, objections & the reveal',\r\n        segment: 'Full list',\r\n        title: \"\\\"I only need two of these\\\" \u2014 the honest answer\",\r\n        preheader: \"Plus what's opening tomorrow\",\r\n        purpose: \"Handle the top objection honestly (bundle isn't always right), then reveal cart opens tomorrow with early bird.\",\r\n        cta: 'Watch: do I actually need all four?',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: \"Short direct-to-camera on when a bundle is and isn't the right call \u2014 90 sec\",\r\n        body: `Fair question I get a lot: \"I genuinely only need two of these right now \u2014 would a bundle even make sense for me?\"\r\n\r\nHonest answer: sometimes no. I made a short video on when it does and doesn't, because I'd rather you buy the right thing than the bigger thing.\r\n\r\n[Watch: do I actually need all four? \u2192]\r\n\r\nTomorrow, everything from this week \u2014 the coverage audit, the full breakdown \u2014 becomes the CPD Bundle: all four courses, one price, early bird pricing for the first week.\r\n\r\nRach X`\r\n      }\r\n    ],\r\n    emails: [\r\n      {\r\n        n: 1, date: '2026-09-30\/01', time: '8:00am',\r\n        segment: 'Owners of 1-2 individual CPD courses 30 Sep (day ahead) \u2192 full list 1 Oct',\r\n        subject: \"It's open \u2014 the CPD Bundle\",\r\n        preheader: \"As mentioned this week \u2014 early bird \u00a33,218+VAT, ends 8 October\",\r\n        purpose: 'Cart open \/ full offer reveal',\r\n        cta: 'Claim the early bird price before 8 October',\r\n        video: false,\r\n        body: `As promised, it's open.\r\n\r\nLtd Co Accounts, Self Assessment, VAT Confidence Boost, and CIS Returns \u2014 if you're running a general practice, you're going to need all four eventually. Not maybe. Eventually.\r\n\r\nMost people buy them one at a time, full price, whenever the gap becomes urgent enough to finally deal with. This is a genuine discount for buying the complete set in one go instead.\r\n\r\nEarly bird takes it to \u00a33,218 + VAT (down from \u00a33,318) until 8 October.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 2, date: '2026-10-07', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"Early bird ends tomorrow \u2014 the full maths\",\r\n        preheader: \"\u00a33,687 four times over, or \u00a33,218 once, ending tomorrow\",\r\n        purpose: 'Price-increase alert \u2014 early bird closing, cost-framed',\r\n        cta: 'Claim the early bird price today',\r\n        video: false,\r\n        body: `Quick one today.\r\n\r\nThe early bird price on the CPD Bundle ends tomorrow. From 8 October it's \u00a33,318 + VAT \u2014 today's the last day at \u00a33,218 + VAT.\r\n\r\nBought separately, full price, all four CPD courses come to \u00a33,687. Bundled, it's \u00a33,318 \u2014 not a huge gimmick discount, just a genuine one for buying the complete set in one go instead of four separate purchases spread across the year.\r\n\r\nIf you're missing more than one of these, the maths works out in your favour almost immediately.\r\n\r\nBundle opens Monday.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 3, date: '2026-10-11', time: '9:00am',\r\n        segment: 'Full list',\r\n        subject: \"The CPD Bundle is open\",\r\n        preheader: \"All four courses, \u00a33,318, closes 22 October\",\r\n        purpose: 'Launch day \/ cart open \u2014 full offer detail',\r\n        cta: 'Get the bundle',\r\n        video: false,\r\n        body: `It's open.\r\n\r\nLtd Co Accounts & Corporation Tax, Self-Assessment Tax Returns, VAT Confidence Boost, and CIS Returns \u2014 all four, one price.\r\n\r\n\u00a33,318 total (against \u00a33,687 bought separately). Doors close 22 October.\r\n\r\nIf you already own one or two of these individually, reply and I'll make sure you're not paying twice for anything you've already got.\r\n\r\n[Get the CPD Bundle \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 4, date: '2026-10-14', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"How many of you already own at least one of these\",\r\n        preheader: \"The numbers so far, and what they mean for you\",\r\n        purpose: \"Curiosity\/social proof \u2014 real uptake numbers, distinct from PLV2's self-audit\",\r\n        cta: 'Get the bundle',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: \"Short screen-recording of the actual uptake numbers on screen, Rachel talking through what they mean \u2014 90 sec\",\r\n        body: `A few numbers worth sharing.\r\n\r\nI recorded a quick screen-share of the actual figures rather than just quoting them at you.\r\n\r\n[Watch the numbers \u2192]\r\n\r\n[CONFIRM REAL FIGURE]% of people who've joined the bundle so far already owned at least one of the four courses individually \u2014 they weren't starting from zero, they were closing the last gap or two.\r\n\r\nIf that's you, reply and I'll make sure you're not paying twice for anything you already own.\r\n\r\nDoors close in 8 days.\r\n\r\n[Get the CPD Bundle \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 5, date: '2026-10-19', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"Your questions about the CPD Bundle, answered\",\r\n        preheader: \"Overlap, refunds, what happens to individual pricing after\",\r\n        purpose: 'FAQ\/objection roundup \u2014 distinct from PLV3, addresses questions since cart open',\r\n        cta: 'Get the bundle before doors close',\r\n        video: false,\r\n        body: `What's actually been asked this week:\r\n\r\n\"I own two already, can I get a partial-bundle price?\" No, but reply and I'll walk you through whether the maths still works for your specific two gaps.\r\n\r\n\"Does the discount apply if I've bought one recently?\" On a case-by-case basis \u2014 just reply with what you've got.\r\n\r\n\"What if I start and it's not for me?\" 14-day money-back on the bundle as a whole, no questions.\r\n\r\nDoors close Friday at midnight.\r\n\r\n[Get the bundle before midnight \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 6, date: '2026-10-22', time: '5:00pm (resend 9:30pm to non-openers)',\r\n        segment: 'Full list, then non-openers only for resend',\r\n        subject: \"Closes tonight \u2014 the CPD Bundle\",\r\n        resendSubject: \"Last call (genuinely, midnight)\",\r\n        preheader: \"After tonight, back to buying these one at a time\",\r\n        purpose: 'Final close',\r\n        cta: 'Get the bundle before midnight',\r\n        video: false,\r\n        body: `Doors close tonight.\r\n\r\nAfter midnight, it's back to buying these one at a time, full price, whenever the gap gets urgent enough.\r\n\r\n[Get the bundle before midnight \u2192]\r\n\r\nThank you to everyone who's already joined.\r\n\r\nRach X\r\n\r\n---\r\nRESEND (non-openers only, 9:30pm):\r\nQuick one - doors close in a couple of hours. [Get the bundle before midnight \u2192]. No hard feelings if it's a no.`\r\n      }\r\n    ],\r\n    socials: [\r\n      {\r\n        type: 'Reframe post 1', date: '2026-10-04', platforms: ['Instagram','LinkedIn'],\r\n        angle: \"You're going to buy all four eventually. This is just not paying full price four times.\",\r\n        ig: \"Ltd Co, Self Assessment, VAT, CIS \u2014 if you run a general practice, you need all four eventually.\\n\\nThis is just not paying full price for each one, separately, whenever the gap finally gets urgent.\",\r\n        linkedin: \"Most practice owners end up owning all four of these compliance courses eventually \u2014 it's just a question of whether that happens gradually, at full price each time, or once, at a genuine discount for buying the complete set.\\n\\nThe CPD Bundle is open for a limited window: all four courses, \u00a33,318 against \u00a33,687 bought separately.\"\r\n      },\r\n      {\r\n        type: 'Reframe post 2', date: '2026-10-08', platforms: ['Instagram','LinkedIn'],\r\n        angle: \"It's not a beginner bundle. It's full-practice coverage in one go.\",\r\n        ig: \"This isn't a beginner bundle.\\n\\nIt's every compliance area a general practice actually needs, covered in one purchase instead of four separate decisions.\",\r\n        linkedin: \"Bundles get a reputation as the 'starter' option, but this one is the opposite \u2014 it's full-practice CPD coverage across every client type a general practice sees, bought once rather than pieced together over years.\"\r\n      },\r\n      {\r\n        type: 'Carousel', date: '2026-10-11', platforms: ['Instagram'],\r\n        title: \"Do you actually need the full CPD Bundle? A quick gut check\",\r\n        slides: [\r\n          \"HOOK: Do you actually need the full CPD Bundle?\",\r\n          \"1. Do you take on sole trader AND limited company clients?\",\r\n          \"2. Do any of your clients need VAT registration or CIS work, even occasionally?\",\r\n          \"3. Have you ever turned down a client because it fell outside what you're confident with?\",\r\n          \"TENSION: If you answered yes twice or more, you're going to need most of these eventually \u2014 the only question is whether you pay for them one at a time or once, at a discount.\",\r\n          \"CTA: The CPD Bundle is open now \u2014 link in bio.\"\r\n        ]\r\n      },\r\n      {\r\n        type: 'Short-form video 1', date: '2026-10-06', platforms: ['TikTok','YouTube Shorts'],\r\n        hook: \"\u00a33,687 bought one at a time, or \u00a33,318 bought once. Here's the maths.\",\r\n        pivot: \"Same four courses, same content \u2014 the only difference is buying decisions spread across years vs one bundle.\",\r\n        consequence: \"Most practices end up owning all four anyway, just later and more expensively.\",\r\n        close: \"CPD Bundle opens Monday \u2014 link in bio.\"\r\n      },\r\n      {\r\n        type: 'Short-form video 2', date: '2026-10-15', platforms: ['TikTok','YouTube Shorts'],\r\n        hook: \"Ltd Co, SA, VAT, CIS \u2014 why these four specifically make up full-practice CPD coverage.\",\r\n        pivot: \"Between them, they cover every client type a general practice sees.\",\r\n        consequence: \"Miss one and you're either turning down that client type or winging it without the working papers to back you up.\",\r\n        close: \"Doors close 22 October \u2014 link in bio.\"\r\n      }\r\n    ]\r\n  },\r\n  {\r\n    id: 'ai-sessions',\r\n    name: 'AI Sessions \u2014 live course + paid cohort',\r\n    status: 'complete',\r\n    price: 'Live session price TBC (historical run reported ~\u00a310k total revenue \u2014 confirm real per-seat price before using these numbers). Paid 6-week cohort: \u00a3700\/head.',\r\n    salesUrl: 'https:\/\/accountantshe.com\/ai-sessions (PLACEHOLDER \u2014 confirm real URL)',\r\n    cartOpen: '2026-10-15',\r\n    cartClose: '2026-10-23',\r\n    earlyBird: { notApplicable: true, reason: \"Live single-day session with an 8-day window doesn't fit a 'discount ends 2 weeks before close' mechanic. If early bird is wanted here, it would sit on the 6-week PAID COHORT instead (\u00a3700, >\u00a3500 ex-VAT \u2192 \u00a3100 off = \u00a3600 early bird) \u2014 but the cohort's own sales window isn't separately dated in this campaign yet. Flag back if you want that built out properly.\" },\r\n    milestones: [\r\n      { date: '2026-10-08', label: 'PLV1 \u2014 belief-shift piece goes out' },\r\n      { date: '2026-10-11', label: 'PLV2 \u2014 proof\/technique piece goes out' },\r\n      { date: '2026-10-14', label: 'PLV3 \u2014 transformation + big reveal goes out' },\r\n      { date: '2026-10-15', label: 'Tickets open' },\r\n      { date: '2026-10-23', label: 'Live session' }\r\n    ],\r\n    theme: \"AI in practice isn't about replacing judgement, it's about not doing the same manual task for the fortieth time this year. This is a template for a repeatable format \u2014 same shape, new date, each time it runs (first instance fiscal week 24; the AI Sessions tab in the recovery plan has it repeating roughly every 6-8 weeks through the fiscal year).\",\r\n    outcome: \"By the live date, readers see at least one concrete task they can hand to AI this week, and warm attendees know the 6-week paid cohort exists as the next step for ongoing support.\",\r\n    prelaunch: [\r\n      {\r\n        n: 1, date: '2026-10-08', time: '8:00am',\r\n        stage: 'PLV1 \u2014 Belief shift',\r\n        segment: 'Full list',\r\n        title: \"You don't need to be technical to use AI well\",\r\n        preheader: \"The belief that's actually stopping most of you\",\r\n        purpose: \"Collapse the belief that using AI well requires technical skill \u2014 it's mostly about knowing which repetitive tasks to hand off.\",\r\n        cta: 'Reply \u2014 what task eats the most of your week?',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: \"60-90 sec direct-to-camera, Rachel \u2014 the technical-skill myth\",\r\n        body: `Something I hear a lot: \"I'm just not technical enough for the AI stuff.\"\r\n\r\nHonestly, neither am I, not in the way people imagine. Using AI well in practice isn't a coding skill \u2014 it's knowing which repetitive task to hand off first, and roughly how to check the output before it goes anywhere near a client.\r\n\r\nRecorded a short video on the specific belief that's actually holding most people back, because it's rarely the tool itself.\r\n\r\n[Watch \u2014 90 seconds \u2192]\r\n\r\nWhat's the task eating the most of your week right now? Hit reply, genuinely curious.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 2, date: '2026-10-11', time: '8:00am',\r\n        stage: 'PLV2 \u2014 Proof & technique',\r\n        segment: 'Full list',\r\n        title: \"The exact prompt I use for client emails\",\r\n        preheader: \"A real, usable technique \u2014 no pitch, just take it\",\r\n        purpose: \"Genuine standalone technique \u2014 a real prompt they can copy and use today, regardless of the live session.\",\r\n        cta: 'Get the prompt',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: 'Screen recording showing the actual prompt and output for a first-draft client email \u2014 2 min',\r\n        body: `Since a few of you replied about client emails specifically, here's the exact prompt I use.\r\n\r\nI recorded a short screen recording showing it in action \u2014 what I type in, what comes back, and the one edit I almost always make before sending.\r\n\r\n[Get the prompt \u2192]\r\n\r\nFree to use regardless of anything else \u2014 steal it.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 3, date: '2026-10-14', time: '8:00am',\r\n        stage: 'PLV3 \u2014 Transformation & the reveal',\r\n        segment: 'Full list',\r\n        title: \"An hour a week back, every week\",\r\n        preheader: \"Plus something live tomorrow\",\r\n        purpose: \"Future-pace the time saved, then reveal tickets open tomorrow for the live session.\",\r\n        cta: 'Nothing to click yet \u2014 more tomorrow',\r\n        video: false,\r\n        body: `If the email prompt saved you even ten minutes, that's the smallest version of what's possible once this becomes a proper habit rather than a one-off.\r\n\r\nTomorrow I'm opening tickets for a live session \u2014 an hour, screen shared, walking through exactly how I actually use AI across a working week. Real prompts, real workflows, no buzzword slides.\r\n\r\nRach X`\r\n      }\r\n    ],\r\n    emails: [\r\n      {\r\n        n: 1, date: '2026-10-15', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"An hour with me, live: AI Sessions (23 October)\",\r\n        preheader: \"Not a sales pitch. An actual working session \u2014 tickets open now.\",\r\n        purpose: 'Invite\/teaser \u2014 cart open, now that PLV1-3 have done the belief-shift and given away a real technique',\r\n        cta: 'Get your ticket',\r\n        video: false,\r\n        body: `As promised \u2014 tickets are open.\r\n\r\nI'm running a live session on 23 October walking through exactly how I actually use AI in my own practice \u2014 not the theory, the real prompts and workflows I use on real client work, building on what you've had this week already.\r\n\r\nNo slides full of buzzwords. I'll share my screen and show you what I actually type in, what comes back, and where it saves genuine time versus where it just creates more editing work.\r\n\r\nTickets are open now \u2014 [confirm price] to join live.\r\n\r\n[Get your ticket \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 2, date: '2026-10-18', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"3 days until AI Sessions \u2014 are these familiar?\",\r\n        preheader: \"The three tasks I'll be showing you how to hand off\",\r\n        purpose: 'Reminder \u2014 reintroduce hooks fresh',\r\n        cta: 'Get your ticket',\r\n        video: false,\r\n        body: `Three days out.\r\n\r\nIf any of these sound familiar \u2014 drafting the first version of a client email, summarising a long HMRC letter into plain English, or turning rough notes into a proper working paper \u2014 those are exactly what I'll be walking through live.\r\n\r\n[Get your ticket \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 3, date: '2026-10-22', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"Tomorrow: AI Sessions live\",\r\n        preheader: \"One more sleep \u2014 bring a real task if you can\",\r\n        purpose: 'Day-before reminder',\r\n        cta: 'Add to calendar',\r\n        video: false,\r\n        body: `Tomorrow, 23 October.\r\n\r\nIf you can, bring an actual task you're stuck on \u2014 a client email you're avoiding, a summary you keep putting off. I'll try to work through a couple live if there's time.\r\n\r\n[Add to calendar \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 4, date: '2026-10-23', time: '9:00am',\r\n        segment: 'Full list',\r\n        subject: \"Today: AI Sessions (starts at [TIME])\",\r\n        preheader: \"See you shortly \u2014 link is below\",\r\n        purpose: 'Day-of \/ launch',\r\n        cta: 'Join now',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: 'Live session itself \u2014 this is the \"video\" for this campaign, delivered live rather than pre-recorded',\r\n        body: `Today's the day.\r\n\r\n[Join now \u2192]\r\n\r\nIf you can't make it live, I'll send the replay tomorrow \u2014 but live is genuinely better for this one since I'll be taking questions as I go.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 5, date: '2026-10-24', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"You missed it... but here's the replay\",\r\n        preheader: \"Full session, plus how the 6-week cohort works if you want ongoing support\",\r\n        purpose: 'Replay + future-pacing toward the paid cohort',\r\n        cta: 'Watch the replay',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: 'Replay of the full live session',\r\n        body: `If you missed yesterday, here's the full replay.\r\n\r\n[Watch the replay \u2192]\r\n\r\nA few of you asked about going deeper than a single session \u2014 that's exactly what the 6-week paid cohort is for. Small group, ongoing support as you actually implement this in your practice rather than just watching once and forgetting by Friday.\r\n\r\n\u00a3700 for the six weeks. Reply if you want details.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 6, date: '2026-10-26', time: '8:00am',\r\n        segment: 'Engaged\/replay-watchers',\r\n        subject: \"Last chance \u2014 the 6-week AI cohort\",\r\n        preheader: \"Small group, starts soon, closing this window\",\r\n        purpose: 'Final close on the cohort upsell',\r\n        cta: 'Join the cohort',\r\n        video: false,\r\n        body: `Closing this window on the 6-week cohort shortly.\r\n\r\nIf watching the session made you want ongoing support actually implementing this rather than just knowing the theory, this is that.\r\n\r\n[Join the cohort \u2192]\r\n\r\nRach X`\r\n      }\r\n    ],\r\n    socials: [\r\n      {\r\n        type: 'Reframe post 1', date: '2026-10-15', platforms: ['Instagram','LinkedIn'],\r\n        angle: \"AI in practice isn't about replacing judgement. It's about not doing the same manual task the fortieth time.\",\r\n        ig: \"AI in your practice isn't about replacing judgement.\\n\\nIt's about not manually doing the same repetitive task for the fortieth time this year.\",\r\n        linkedin: \"There's a lot of noise about AI 'replacing' accountants. The actual, boring, useful version is much smaller than that: not manually drafting the same type of client email or summary for the fortieth time this year.\\n\\nLive session on 23 October \u2014 real prompts, real workflows, screen-shared, no buzzword slides.\"\r\n      },\r\n      {\r\n        type: 'Reframe post 2', date: '2026-10-19', platforms: ['Instagram','LinkedIn'],\r\n        angle: \"It's not the tool. It's not having a repeatable workflow around it.\",\r\n        ig: \"It's not the AI tool that's the problem.\\n\\nIt's not having a repeatable workflow around it \u2014 so it stays a novelty instead of becoming a habit.\",\r\n        linkedin: \"Most people who try AI once and give up haven't hit a capability limit \u2014 they've hit a workflow gap. No repeatable process, so it stays a one-off experiment instead of becoming part of how they actually work.\"\r\n      },\r\n      {\r\n        type: 'Carousel', date: '2026-10-22', platforms: ['Instagram'],\r\n        title: \"3 tasks I actually hand to AI every week\",\r\n        slides: [\r\n          \"HOOK: 3 tasks I actually hand to AI every week\",\r\n          \"1. First-draft client emails \u2014 I edit, I don't write from scratch anymore.\",\r\n          \"2. Summarising long HMRC letters into plain English before I call the client.\",\r\n          \"3. Turning rough working notes into a properly formatted working paper.\",\r\n          \"TENSION: None of these replace judgement. All of them used to eat an hour I don't get back.\",\r\n          \"CTA: Live session tomorrow, 23 October \u2014 link in bio.\"\r\n        ]\r\n      },\r\n      {\r\n        type: 'Short-form video 1', date: '2026-10-17', platforms: ['TikTok','YouTube Shorts'],\r\n        hook: \"I stopped writing client emails from scratch. Here's what changed.\",\r\n        pivot: \"First draft goes to AI, I edit and send \u2014 same email, a fraction of the time.\",\r\n        consequence: \"The time I got back went straight into actual client work, not admin.\",\r\n        close: \"Live session, 23 October \u2014 link in bio.\"\r\n      },\r\n      {\r\n        type: 'Short-form video 2', date: '2026-10-24', platforms: ['TikTok','YouTube Shorts'],\r\n        hook: \"The replay is up if you missed yesterday's live AI session.\",\r\n        pivot: \"Full walkthrough, real prompts, real client scenarios.\",\r\n        consequence: \"If you're still doing this manually every time, that's the exact thing this fixes.\",\r\n        close: \"Replay link in bio \u2014 6-week cohort details also there for ongoing support.\"\r\n      }\r\n    ]\r\n  },\r\n  {\r\n    id: 'micro-entity',\r\n    name: 'Micro Entity Workshop',\r\n    status: 'complete',\r\n    price: 'Live online \u00a3247, on-demand replay \u00a3147 (London dropped \u2014 0% survey support)',\r\n    salesUrl: 'https:\/\/accountantshe.com\/micro-entity-workshop (PLACEHOLDER \u2014 confirm real URL)',\r\n    cartOpen: '2026-11-02',\r\n    cartClose: '2026-11-22',\r\n    earlyBird: { discount: '10% off', standardPrice: 'Live \u00a3247 \/ On-demand \u00a3147', earlyBirdPrice: 'Live \u00a3222.30 \/ On-demand \u00a3132.30', endDate: '2026-11-08', rule: '<\u00a3500 ex-VAT, new workshop' },\r\n    milestones: [\r\n      { date: '2026-10-26', label: 'PLV1 \u2014 belief-shift piece goes out' },\r\n      { date: '2026-10-29', label: 'PLV2 \u2014 proof\/technique piece goes out' },\r\n      { date: '2026-11-01', label: 'PLV3 \u2014 transformation + big reveal goes out' },\r\n      { date: '2026-11-02', label: 'Tickets open \u2014 early bird pricing live' },\r\n      { date: '2026-11-08', label: 'Early bird ends \u2014 standard pricing applies' },\r\n      { date: '2026-11-21', label: 'Live workshop session' },\r\n      { date: '2026-11-22', label: 'Cart closes' }\r\n    ],\r\n    theme: \"We asked what format you actually wanted, and built exactly that \u2014 live online, with a replay, no Manchester date nobody asked for.\",\r\n    outcome: \"By the end of the campaign, readers feel the workshop was genuinely shaped by their own survey answers, and understand the choice between live (\u00a3247) and on-demand (\u00a3147) is a real trade-off, not a false scarcity tactic.\",\r\n    prelaunch: [\r\n      {\r\n        n: 1, date: '2026-10-26', time: '8:00am',\r\n        stage: 'PLV1 \u2014 Belief shift',\r\n        segment: 'Full list',\r\n        title: \"Micro-entity accounts feel simple. That's exactly the risk.\",\r\n        preheader: \"The mistakes I see aren't complexity mistakes\",\r\n        purpose: \"Collapse the belief that 'simple' filings carry low risk \u2014 the actual mistakes come from treating them as low-stakes.\",\r\n        cta: \"Reply \u2014 what's the trickiest bit of micro-entity accounts for you?\",\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: \"60-90 sec direct-to-camera, Rachel \u2014 why simple filings aren't low-risk\",\r\n        body: `Micro-entity accounts have a reputation for being the easy end of the job. Small numbers, simplified disclosure, quick to file.\r\n\r\nThat reputation is exactly why the mistakes happen. Not because it's technically hard \u2014 because it's treated as low-stakes, so the second look that would catch a small error never happens.\r\n\r\nRecorded a short video on the specific mistakes I see most, because they're rarely about the accounting itself.\r\n\r\n[Watch \u2014 90 seconds \u2192]\r\n\r\nWhat's the trickiest bit of micro-entity work for you? Hit reply.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 2, date: '2026-10-29', time: '8:00am',\r\n        stage: 'PLV2 \u2014 Proof & technique',\r\n        segment: 'Full list',\r\n        title: \"The check that catches most micro-entity errors\",\r\n        preheader: \"One real technique, free to use regardless\",\r\n        purpose: \"Genuine standalone technique \u2014 a specific review check they can use on their next filing.\",\r\n        cta: 'Watch the walkthrough',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: 'Screen recording of the specific pre-filing check, Rachel narrating \u2014 2-3 min',\r\n        body: `Following on from last week \u2014 here's the specific check I run before any micro-entity accounts go out, the one that catches most of the errors I've seen over the years.\r\n\r\n[Watch the walkthrough \u2192]\r\n\r\nFree to use on your own filings regardless of anything else.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 3, date: '2026-11-01', time: '8:00am',\r\n        stage: 'PLV3 \u2014 Transformation & the reveal',\r\n        segment: 'Full list',\r\n        title: \"We asked what format you actually wanted\",\r\n        preheader: \"The survey results, and what's opening tomorrow\",\r\n        purpose: \"Transparency\/reveal \u2014 survey results build trust, then reveal tickets open tomorrow.\",\r\n        cta: 'Nothing to click yet \u2014 more tomorrow',\r\n        video: false,\r\n        body: `A few weeks ago I sent a quick survey asking what format you'd actually want for a proper Micro Entity Accounts session.\r\n\r\nThe honest results: almost none of you wanted an in-person Manchester date (zero, actually \u2014 0 of 28 responses). More than half wanted it live online, with a chunk wanting on-demand instead.\r\n\r\nSo that's what's opening tomorrow \u2014 no venue nobody would travel to, just a genuinely useful live session with a replay for anyone who can't make it live.\r\n\r\nRach X`\r\n      }\r\n    ],\r\n    emails: [\r\n      {\r\n        n: 1, date: '2026-11-02', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"It's open \u2014 Micro Entity Workshop (early bird 10% off)\",\r\n        preheader: \"As promised \u2014 tickets open now, ends 8 November\",\r\n        purpose: 'Cart open \u2014 the ask, now that PLV1-3 have built belief and given away a real technique',\r\n        cta: 'Book at the early bird price',\r\n        video: false,\r\n        body: `As promised, tickets are open.\r\n\r\nMicro Entity Accounts in Practice \u2014 built around what the survey told us: live online with a replay, no Manchester date nobody asked for, covering everything from the mistakes we talked about this week through to filing step by step and pricing this to clients.\r\n\r\nTickets are open now, 10% off until 8 November \u2014 live \u00a3222.30 (down from \u00a3247), on-demand \u00a3132.30 (down from \u00a3147).\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 2, date: '2026-11-07', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"Early bird ends tomorrow \u2014 what's actually inside\",\r\n        preheader: \"10% off, gone from 8 November \u2014 built around what you said you wanted covered\",\r\n        purpose: 'Price-increase alert \u2014 early bird closing',\r\n        cta: 'Book at the early bird price today',\r\n        video: false,\r\n        body: `Quick one today.\r\n\r\nEarly bird pricing ends tomorrow \u2014 last chance at \u00a3222.30 live \/ \u00a3132.30 on-demand before it goes to \u00a3247 \/ \u00a3147.\r\n\r\nWhen we asked what you wanted covered, the overwhelming answer was \"all of it\" \u2014 mistakes, filing step by step, HMRC and Companies House queries, pricing to clients. So that's the shape of the session: a proper end-to-end walkthrough, not a narrow single-topic webinar.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 3, date: '2026-11-19', time: '9:00am',\r\n        segment: 'Full list',\r\n        subject: \"Micro Entity Workshop is open\",\r\n        preheader: \"Live \u00a3247, on-demand \u00a3147 \u2014 live session 21 November\",\r\n        purpose: 'Launch day \/ cart open',\r\n        cta: 'Book your spot',\r\n        video: false,\r\n        body: `It's open.\r\n\r\nMicro Entity Accounts in Practice \u2014 everything from common mistakes and HMRC\/Companies House queries through to filing step by step and pricing this to clients.\r\n\r\nLive online, 21 November: \u00a3247. Can't make it live? On-demand recording: \u00a3147.\r\n\r\n[Book your spot \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 4, date: '2026-11-21', time: '9:00am',\r\n        segment: 'Full list',\r\n        subject: \"Today: the Micro Entity Workshop\",\r\n        preheader: \"Live now, or grab the on-demand version\",\r\n        purpose: 'Day-of \/ launch',\r\n        cta: 'Join live',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: 'Live session itself',\r\n        body: `Today's the day.\r\n\r\n[Join live \u2192]\r\n\r\nIf live doesn't work today, the on-demand version is available right after \u2014 same content, your own time.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 5, date: '2026-11-22', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"You missed it... but here's the replay\",\r\n        preheader: \"Full session, available on-demand\",\r\n        purpose: 'Replay + future-pacing',\r\n        cta: 'Get the on-demand version',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: 'Replay of the full session',\r\n        body: `If you missed yesterday, the full recording is available now.\r\n\r\n[Get the on-demand version \u2192]\r\n\r\nSame content whether you watched live or catch it this way \u2014 the checklist and templates are identical either way.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 6, date: '2026-11-22', time: '6:00pm',\r\n        segment: 'Non-purchasers',\r\n        subject: \"Last call \u2014 Micro Entity Workshop\",\r\n        preheader: \"On-demand access closes this week\",\r\n        purpose: 'Final close',\r\n        cta: 'Get on-demand access',\r\n        video: false,\r\n        body: `Closing this window shortly.\r\n\r\nIf micro-entity accounts is a real gap in your practice right now, this is the fastest way to close it.\r\n\r\n[Get on-demand access \u2192]\r\n\r\nRach X`\r\n      }\r\n    ],\r\n    socials: [\r\n      {\r\n        type: 'Reframe post 1', date: '2026-11-12', platforms: ['Instagram','LinkedIn'],\r\n        angle: \"We surveyed the list before building this. Zero people wanted Manchester.\",\r\n        ig: \"We surveyed the list before building this workshop.\\n\\nZero people wanted a Manchester date. Over half wanted live online. So that's what we built.\",\r\n        linkedin: \"Before building the Micro Entity Workshop, we sent a proper survey asking what format the list actually wanted \u2014 not what we assumed they'd want.\\n\\nThe answer was clear: live online, with an on-demand option, and genuinely zero appetite for an in-person Manchester date. Building it that way.\"\r\n      },\r\n      {\r\n        type: 'Reframe post 2', date: '2026-11-16', platforms: ['Instagram','LinkedIn'],\r\n        angle: \"You told us what to cover, so that's exactly what's in it.\",\r\n        ig: \"You told us what to cover in this workshop.\\n\\nCommon mistakes, HMRC and Companies House queries, filing step by step, pricing to clients \u2014 all of it, because that's what you asked for.\",\r\n        linkedin: \"Rather than guessing at content, we asked the list what they wanted covered in the Micro Entity Workshop. The overwhelming answer was 'all of it' \u2014 so the session covers common mistakes, filing step by step, HMRC\/Companies House queries, and pricing to clients, end to end.\"\r\n      },\r\n      {\r\n        type: 'Carousel', date: '2026-11-19', platforms: ['Instagram'],\r\n        title: \"What survey respondents actually asked for (and what we built)\",\r\n        slides: [\r\n          \"HOOK: We asked what you wanted from a Micro Entity Workshop. Here's what came back.\",\r\n          \"77% said yes, they'd attend.\",\r\n          \"57% wanted live online. 32% wanted on-demand. Almost nobody wanted in-person.\",\r\n          \"82% wanted everything covered \u2014 mistakes, filing, HMRC queries, pricing.\",\r\n          \"TENSION: So that's exactly what we built, no more, no less.\",\r\n          \"CTA: Live session 21 November \u2014 link in bio.\"\r\n        ]\r\n      },\r\n      {\r\n        type: 'Short-form video 1', date: '2026-11-14', platforms: ['TikTok','YouTube Shorts'],\r\n        hook: \"We asked 52 people what workshop format they wanted. The answer surprised us.\",\r\n        pivot: \"Zero wanted in-person. Most wanted live online. So that's what got built.\",\r\n        consequence: \"Building things nobody asked for is how workshops end up half-empty.\",\r\n        close: \"Micro Entity Workshop, live 21 November \u2014 link in bio.\"\r\n      },\r\n      {\r\n        type: 'Short-form video 2', date: '2026-11-20', platforms: ['TikTok','YouTube Shorts'],\r\n        hook: \"Micro-entity accounts mistakes I see most often in practice.\",\r\n        pivot: \"Quick rundown of the top 2-3, with the full breakdown live tomorrow.\",\r\n        consequence: \"Small mistakes on micro-entity accounts compound fast across a whole client book.\",\r\n        close: \"Full session live tomorrow \u2014 link in bio.\"\r\n      }\r\n    ]\r\n  },\r\n  {\r\n    id: 'start-your-firm',\r\n    name: 'Start Your Firm course + 60\/90 day sequence',\r\n    status: 'complete',\r\n    price: '\u00a399',\r\n    salesUrl: 'https:\/\/accountantshe.com\/start-your-firm (PLACEHOLDER \u2014 confirm real URL)',\r\n    cartOpen: '2026-11-02',\r\n    cartClose: 'Evergreen \u2014 no hard close (see note)',\r\n    earlyBird: { notApplicable: true, reason: \"Evergreen, no cart-close date to count back 2 weeks from \u2014 the early bird mechanic needs a real deadline to work against. If you want a time-boxed early bird here (e.g. for the first cohort of new subscribers only), that needs an actual close date decided first, which changes this from evergreen to a proper launch window.\" },\r\n    theme: \"The technical skills to run a practice are the easy part. Nobody teaches the actual first 90 days \u2014 getting the first client, pricing with no track record, and not panicking in month two.\",\r\n    outcome: \"By the end of the initial push, readers considering leaving employment to start their own firm see the course as the missing '90 day plan' rather than another technical training, and the evergreen sequence continues nurturing new subscribers after this window closes.\",\r\n    deviationNote: \"This product is evergreen, not cart-close \u2014 flagging the deviation from the standard 6-email close-date shape per the brief's own rule. I've kept 6 emails for an initial promotional push to seed the evergreen sequence, but email 6 wraps up this push rather than threatening a hard deadline, since the course stays available afterward and false urgency here would misrepresent the product.\",\r\n    prelaunch: [\r\n      {\r\n        n: 1, date: '2026-10-19', time: '8:00am',\r\n        stage: 'PLV1 \u2014 Belief shift',\r\n        segment: 'Full list',\r\n        title: \"It's not a skills problem\",\r\n        preheader: \"What actually stops people starting their own firm\",\r\n        purpose: \"Collapse the belief that technical ability is the barrier to starting a firm \u2014 it's not knowing what 'normal' looks like at this stage.\",\r\n        cta: 'Reply \u2014 is starting your own firm on your mind?',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: \"60-90 sec direct-to-camera, Rachel \u2014 skills vs the 'normal' gap\",\r\n        body: `If you've ever thought about leaving employment to start your own firm, here's something worth sitting with.\r\n\r\nYou already know the technical side \u2014 the accounts, the tax, the compliance. That's not what would trip you up.\r\n\r\nWhat actually trips people up is month one with no clients, month two wondering if you priced everything wrong, and not having any idea what \"normal\" looks like for a firm at this stage. Nobody teaches that part.\r\n\r\nFilmed a short video on this one \u2014 it's the thing I wish someone had told me straight before I started.\r\n\r\n[Watch \u2014 90 seconds \u2192]\r\n\r\nIs this on your mind at all? Hit reply, no judgement either way.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 2, date: '2026-10-22', time: '8:00am',\r\n        stage: 'PLV2 \u2014 Proof & technique',\r\n        segment: 'Full list',\r\n        title: \"My actual first 90 days (it wasn't smooth)\",\r\n        preheader: \"The real story, not the LinkedIn version\",\r\n        purpose: \"Genuine case study \u2014 the honest first-90-days story, standalone value with no pitch attached.\",\r\n        cta: 'Watch the full story',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: \"Rachel's own early-days story, unfiltered \u2014 3-4 min\",\r\n        body: `I want to tell you honestly what my own first 90 days looked like, because it wasn't smooth, and I think the polished version everyone else tells does new firm owners a disservice.\r\n\r\nI recorded the real version \u2014 the client I nearly turned down out of nerves, the fee I badly underpriced, and what actually got me through the wobbliest weeks.\r\n\r\n[Watch the full story \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 3, date: '2026-10-25', time: '8:00am',\r\n        stage: 'PLV3 \u2014 Transformation & the reveal',\r\n        segment: 'Full list',\r\n        title: \"\\\"I'm not ready yet\\\" \u2014 when is the right time, actually?\",\r\n        preheader: \"Plus what's opening Monday\",\r\n        purpose: \"Handle the top objection honestly, then reveal cart opens Monday.\",\r\n        cta: 'Watch: am I ready?',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: \"Short direct-to-camera on the 'not ready yet' objection \u2014 90 sec\",\r\n        body: `The objection I hear most about starting a firm: \"I'm not ready yet.\"\r\n\r\nI made a short video on this, because in my experience almost nobody feels ready, and waiting for that feeling tends to just mean waiting longer than necessary.\r\n\r\n[Watch: am I ready? \u2192]\r\n\r\nMonday, everything from this week becomes a proper course \u2014 the real 60\/90 day plan for actually getting started.\r\n\r\nRach X`\r\n      }\r\n    ],\r\n    emails: [\r\n      {\r\n        n: 1, date: '2026-10-26', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"Quick recap before Monday\",\r\n        preheader: \"What we've covered this week, and what's coming\",\r\n        purpose: \"Reminder \u2014 recap the week's prelaunch content, build toward Monday's cart open\",\r\n        cta: 'Course opens Monday',\r\n        video: false,\r\n        body: `This week: why it's not a skills problem, my own honest first-90-days story, and the truth about \"not feeling ready.\"\r\n\r\nIf you've been following along, Monday is where it all becomes something you can actually use \u2014 the real 60\/90 day plan.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 2, date: '2026-10-29', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"What actually happens in the first 90 days\",\r\n        preheader: \"A realistic version, not the LinkedIn highlight reel\",\r\n        purpose: 'Reminder \u2014 reintroduce hooks fresh',\r\n        cta: 'Course opens Monday',\r\n        video: false,\r\n        body: `Quick one today.\r\n\r\nThe honest version of starting a firm looks nothing like the LinkedIn version. It's a slow first few weeks, some pricing conversations that go worse than expected, and a lot of \"is this normal\" moments with nobody to ask.\r\n\r\nThat's exactly what this course walks through \u2014 the real 60\/90 day version, not the highlight reel.\r\n\r\nOpens Monday.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 3, date: '2026-11-02', time: '9:00am',\r\n        segment: 'Full list',\r\n        subject: \"It's open \u2014 Start Your Firm\",\r\n        preheader: \"\u00a399 \u2014 the 60\/90 day plan for actually getting started\",\r\n        purpose: 'Cart open',\r\n        cta: 'Join Start Your Firm',\r\n        video: false,\r\n        body: `As promised, it's open.\r\n\r\nStart Your Firm walks through the real first 90 days \u2014 getting your first client, pricing with no track record yet, and the 60\/90 day sequence that gets you from \"just started\" to \"actually running a firm.\"\r\n\r\n\u00a399.\r\n\r\n[Join Start Your Firm \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 4, date: '2026-11-05', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"What early joiners are already saying\",\r\n        preheader: \"Real reactions from this week's joiners\",\r\n        purpose: \"Social proof \u2014 distinct from PLV2's founder story\",\r\n        cta: 'Join Start Your Firm',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: \"Short screen-recording of 2 real early-joiner replies (with permission), Rachel reading them out \u2014 90 sec\",\r\n        body: `A few people who joined this week have replied already:\r\n\r\n\"Just having a benchmark for what 'normal' looks like at month two took so much pressure off.\"\r\n\r\n\"Wish this existed when I actually started \u2014 would have saved me from underpricing my first client.\"\r\n\r\nRecorded a short video reading these out properly.\r\n\r\n[Watch \u2192]\r\n\r\n[Join Start Your Firm \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 5, date: '2026-11-10', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"Your questions about Start Your Firm, answered\",\r\n        preheader: \"Who it's for, refunds, timing\",\r\n        purpose: 'FAQ\/objection roundup \u2014 distinct from PLV3',\r\n        cta: 'Join Start Your Firm',\r\n        video: false,\r\n        body: `What's actually been asked:\r\n\r\n\"Is this only for people about to quit their job, or is it useful earlier too?\" Useful earlier too \u2014 most of the value is in planning before you've handed in notice, not after.\r\n\r\n\"What if I've already started and I'm past month 3?\" Still useful \u2014 most people say the month-two content is where they'd have changed something in hindsight.\r\n\r\n\"Refund if it's not for me?\" 14-day money-back, no questions.\r\n\r\n[Join Start Your Firm \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 6, date: '2026-11-13', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"This is always here, but the extra nudge stops today\",\r\n        preheader: \"Course stays open \u2014 just wrapping up this initial run of emails\",\r\n        purpose: 'Wrap-up \u2014 evergreen, no hard deadline, honest framing',\r\n        cta: 'Join Start Your Firm',\r\n        video: false,\r\n        body: `Last one of these for now.\r\n\r\nStart Your Firm isn't going anywhere \u2014 it's not a cart-close product, so there's no deadline pressure here. This is just the last of this initial run of emails about it.\r\n\r\nIf starting your own firm is genuinely on your mind, the 60\/90 day plan is there whenever you're ready for it.\r\n\r\n[Join Start Your Firm \u2192]\r\n\r\nRach X`\r\n      }\r\n    ],\r\n    socials: [\r\n      {\r\n        type: 'Reframe post 1', date: '2026-10-26', platforms: ['Instagram','LinkedIn'],\r\n        angle: \"The technical side isn't what trips new firm owners up. The first 90 days is.\",\r\n        ig: \"The technical side of running a firm isn't what trips new owners up.\\n\\nIt's the first 90 days \u2014 no clients yet, pricing with no track record, and nobody to ask 'is this normal.'\",\r\n        linkedin: \"Most people considering starting their own firm worry about the technical side \u2014 will I be good enough at the accounting itself. That's rarely the real barrier.\\n\\nThe actual hard part is the first 90 days: no clients yet, pricing decisions with no track record to lean on, and no benchmark for what 'normal' looks like at this stage. That's the gap Start Your Firm closes.\"\r\n      },\r\n      {\r\n        type: 'Reframe post 2', date: '2026-10-30', platforms: ['Instagram','LinkedIn'],\r\n        angle: \"Nobody feels ready. Waiting to feel ready just means waiting longer.\",\r\n        ig: \"Nobody feels ready to start their own firm.\\n\\nWaiting for that feeling to arrive usually just means waiting longer than you needed to.\",\r\n        linkedin: \"'I'm not ready yet' is the objection I hear most from accountants considering starting their own firm. In my experience, almost nobody feels ready \u2014 the feeling doesn't reliably arrive before the decision, it tends to arrive somewhere in the first few months of actually doing it.\"\r\n      },\r\n      {\r\n        type: 'Carousel', date: '2026-11-02', platforms: ['Instagram'],\r\n        title: \"5 things nobody tells you about the first 90 days of your own firm\",\r\n        slides: [\r\n          \"HOOK: 5 things nobody tells you about the first 90 days\",\r\n          \"1. Your first client will probably come from somewhere unexpected, not a marketing plan.\",\r\n          \"2. You will underprice something. Almost everyone does.\",\r\n          \"3. Month two feels slower than month one \u2014 that's normal, not a warning sign.\",\r\n          \"4. 'Is this normal' will be your most common thought, with nobody obvious to ask.\",\r\n          \"TENSION: The technical skills were never the hard part.\",\r\n          \"CTA: Start Your Firm opens today \u2014 link in bio.\"\r\n        ]\r\n      },\r\n      {\r\n        type: 'Short-form video 1', date: '2026-10-28', platforms: ['TikTok','YouTube Shorts'],\r\n        hook: \"My first client as a firm owner came from somewhere I never expected.\",\r\n        pivot: \"Not the marketing plan I'd carefully built \u2014 a genuinely random conversation.\",\r\n        consequence: \"If you're waiting for the 'planned' path to work before starting, you might be waiting for the wrong thing.\",\r\n        close: \"Start Your Firm opens Monday \u2014 link in bio.\"\r\n      },\r\n      {\r\n        type: 'Short-form video 2', date: '2026-11-07', platforms: ['TikTok','YouTube Shorts'],\r\n        hook: \"The fee I badly underpriced in my first three months.\",\r\n        pivot: \"Reveal the actual number and what I'd do differently.\",\r\n        consequence: \"Underpricing early sets a reference point clients remember when you try to raise it later.\",\r\n        close: \"Link in bio for the full 60\/90 day plan.\"\r\n      }\r\n    ]\r\n  },\r\n  {\r\n    id: 'exit-succession',\r\n    name: 'Practice Exit & Succession Planning',\r\n    status: 'complete',\r\n    price: '\u00a3350 inc VAT',\r\n    salesUrl: 'https:\/\/accountantshe.com\/exit-succession (PLACEHOLDER \u2014 confirm real URL)',\r\n    cartOpen: '2027-03-11',\r\n    cartClose: '2027-04-01',\r\n    earlyBird: { discount: '10% off', standardPrice: '\u00a3350 inc VAT', earlyBirdPrice: '\u00a3315 inc VAT', endDate: '2027-03-18', rule: '<\u00a3500 ex-VAT, new course' },\r\n    milestones: [\r\n      { date: '2027-03-01', label: 'PLV1 \u2014 belief-shift piece goes out (gentle tone)' },\r\n      { date: '2027-03-04', label: 'PLV2 \u2014 proof\/technique piece goes out (gentle tone)' },\r\n      { date: '2027-03-07', label: 'PLV3 \u2014 transformation + reveal goes out (gentle tone)' },\r\n      { date: '2027-03-11', label: 'Available now \u2014 early bird pricing live' },\r\n      { date: '2027-03-18', label: 'Early bird ends \u2014 standard pricing applies' },\r\n      { date: '2027-04-01', label: 'Window closes' }\r\n    ],\r\n    theme: \"You built this practice. It deserves a proper exit plan, not a fire sale out of exhaustion when you finally can't do it anymore.\",\r\n    outcome: \"By the end of the campaign, readers thinking about winding down or selling feel they have a dignified, protective plan available to them, rather than facing the decision alone or rushed.\",\r\n    deviationNote: \"Different buyer and different emotional weight to every other launch in this plan \u2014 retiring or exhausted practice owners, not growth-focused ones. I've deliberately toned down the countdown urgency in emails 2 and 6 (no 'closes tonight at midnight' pressure) since hard-sell tactics feel inappropriate for a decision this significant. The prelaunch (PLV) pieces below keep this same gentle register \u2014 soft replies invited, no hype CTAs, consistent with the rest of this launch. Flagging this per the brief's own rule to note deviations from the standard pattern.\",\r\n    prelaunch: [\r\n      {\r\n        n: 1, date: '2027-03-01', time: '8:00am',\r\n        stage: 'PLV1 \u2014 Belief shift (gentle tone)',\r\n        segment: 'Longest-tenured students\/clients',\r\n        title: \"Thinking about this early isn't giving up\",\r\n        preheader: \"A gentle one \u2014 no sales pitch here\",\r\n        purpose: \"Collapse the belief that planning an exit means you're ready to leave now, or that it's somehow morbid or premature \u2014 planning early is protective, not defeatist.\",\r\n        cta: \"Reply if this is on your mind, even quietly\",\r\n        video: false,\r\n        body: `A gentler one today.\r\n\r\nSome of you have been running your practice for a very long time. Long enough that thinking about what happens when you stop isn't hypothetical \u2014 it's something that crosses your mind quietly now and then.\r\n\r\nI want to say something that might help: thinking about this early doesn't mean you're ready to leave, or that you're giving up on the practice. It's the opposite, actually \u2014 the people who plan earliest tend to have the most control over how it eventually goes, for them and for their clients.\r\n\r\nIf this has crossed your mind at all, even quietly, hit reply. I'd rather hear where you're at than send you anything today.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 2, date: '2027-03-04', time: '8:00am',\r\n        stage: 'PLV2 \u2014 Proof & reflection (gentle tone)',\r\n        segment: 'Full list',\r\n        title: \"A conversation I had with a practice owner about leaving\",\r\n        preheader: \"What she was actually worried about\",\r\n        purpose: \"Genuine reflection, no pitch \u2014 the real emotional weight behind exit planning, shared honestly.\",\r\n        cta: 'No action needed \u2014 just wanted to share this',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: \"Rachel reflecting on a real conversation with a retiring practice owner \u2014 4 min\",\r\n        body: `I want to share something from a conversation I had with a practice owner thinking about winding down.\r\n\r\nShe wasn't worried about the money, not really. She was worried about her clients \u2014 what would happen to them, whether whoever took over would actually care the way she had. That worry was the thing keeping her from starting the process at all.\r\n\r\nI recorded my thoughts on that conversation, because I think it's the real barrier for a lot of you, more than any technical or financial question.\r\n\r\n[Watch the conversation \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 3, date: '2027-03-07', time: '8:00am',\r\n        stage: 'PLV3 \u2014 Reassurance & reveal (gentle tone)',\r\n        segment: 'Full list',\r\n        title: \"\\\"I'm not ready to decide yet\\\" \u2014 that's alright\",\r\n        preheader: \"Something is available soon, no pressure to act on it\",\r\n        purpose: \"Reassure directly, then gently mention something is becoming available in a couple of weeks \u2014 no countdown energy.\",\r\n        cta: 'No action needed',\r\n        video: false,\r\n        body: `A lot of you have said some version of \"I'm not ready to actually decide yet.\"\r\n\r\nThat's genuinely fine. Having a plan doesn't commit you to using it this year, or even next. What it gives you is clarity on your options, so when you are ready, you're not starting from nothing under pressure.\r\n\r\nIn a couple of weeks I'm making something available for exactly this \u2014 a proper plan for exiting or winding down on your own terms. No pressure to act on it the day it's there.\r\n\r\nRach X`\r\n      }\r\n    ],\r\n    emails: [\r\n      {\r\n        n: 1, date: '2027-03-14\/15', time: '8:00am',\r\n        segment: 'Longest-tenured students\/clients 14 Mar (day ahead) \u2192 full list 15 Mar',\r\n        subject: \"It's available \u2014 for when you're ready to think about the end\",\r\n        preheader: \"As mentioned recently \u2014 not a sales email, a genuine offer\",\r\n        purpose: 'Gentle reveal \u2014 the ask, but softly, consistent with PLV1-3',\r\n        cta: \"Reply if this is on your mind, even quietly\",\r\n        video: false,\r\n        body: `As I mentioned a couple of weeks ago, it's available now.\r\n\r\nPractice Exit & Succession Planning \u2014 not a course on growth, the opposite. A proper plan for exiting or winding down a practice you built, on your own terms, protecting both its value and the clients you've cared for along the way.\r\n\r\nIt's available now at \u00a3315 (down from \u00a3350) for the first couple of weeks \u2014 but genuinely, that's not the point of this email. If it's on your mind, even quietly, hit reply. I'd rather hear where you're at than sell you anything today.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 2, date: '2027-03-18', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"The difference between exiting and just stopping\",\r\n        preheader: \"A proper plan, not a fire sale\",\r\n        purpose: 'Reminder \u2014 reintroduce hooks gently, no artificial urgency',\r\n        cta: 'Read more, no pressure',\r\n        video: false,\r\n        body: `Quick thought today.\r\n\r\nThere's a real difference between exiting a practice properly and just eventually stopping because you're too exhausted to keep going. The first protects what you built. The second usually means selling for less than it's worth, to whoever's available, on their timeline instead of yours.\r\n\r\nSmall practical note: the introductory price (\u00a3315) is available through today, back to \u00a3350 after \u2014 but please don't let that rush a decision this significant. I'd genuinely rather you take the time you need.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 3, date: '2027-03-21', time: '9:00am',\r\n        segment: 'Full list',\r\n        subject: \"Practice Exit & Succession Planning is open\",\r\n        preheader: \"\u00a3350 \u2014 a proper plan for leaving on your own terms\",\r\n        purpose: 'Launch day \/ cart open \u2014 full offer detail',\r\n        cta: 'Get the plan',\r\n        video: false,\r\n        body: `It's open.\r\n\r\nPractice Exit & Succession Planning walks through valuing what you've built properly, the real options for exiting (sale, merger, gradual wind-down, internal succession), and how to protect your clients through whichever path you choose.\r\n\r\n\u00a3350 inc VAT.\r\n\r\n[Get the plan \u2192]\r\n\r\nIf you'd rather talk it through before deciding, just reply \u2014 I mean that.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 4, date: '2027-03-25', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"What it's actually like to have the plan in hand\",\r\n        preheader: \"A few quiet reflections from people who've taken this step\",\r\n        purpose: \"Gentle proof \u2014 distinct from PLV2's conversation, focused on relief rather than persuasion\",\r\n        cta: 'Get the plan',\r\n        video: false,\r\n        body: `A few people who've already taken this step have said things I wanted to pass on gently, with permission:\r\n\r\n\"I didn't expect the relief. I'm not doing anything differently yet, I just feel less alone with it.\"\r\n\r\n\"Having it mapped out took away the sense that I'd be figuring this out from nothing when the time comes.\"\r\n\r\nNo pressure \u2014 just wanted you to hear it.\r\n\r\n[Get the plan \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 5, date: '2027-03-29', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"A few honest answers, in case they help\",\r\n        preheader: \"Timing, cost, what this actually commits you to\",\r\n        purpose: 'Gentle FAQ roundup \u2014 distinct from PLV3, softly answering practical questions',\r\n        cta: 'Get the plan',\r\n        video: false,\r\n        body: `A few things people have asked, gently answered:\r\n\r\n\"Does buying this commit me to anything?\" No \u2014 it's information and a plan, nothing more. What you do with it, and when, is entirely yours.\r\n\r\n\"Is this only for people selling soon?\" No \u2014 plenty of people use this years ahead of actually acting on it.\r\n\r\n\"What if I read it and I'm still not sure?\" That's completely normal. Reply any time, I'm happy to talk it through.\r\n\r\nCloses Wednesday, no pressure attached to that.\r\n\r\n[Get the plan \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 6, date: '2027-04-01', time: '5:00pm',\r\n        segment: 'Full list',\r\n        subject: \"Closing this evening\",\r\n        preheader: \"No hard countdown \u2014 just a gentle close\",\r\n        purpose: 'Final close \u2014 deliberately gentle, not a hard-urgency push',\r\n        cta: 'Get the plan',\r\n        video: false,\r\n        body: `Closing this evening.\r\n\r\nIf you've been thinking about this quietly and haven't acted yet, I'd rather you take the time you need than rush a decision this significant because of an email deadline. If now genuinely isn't the moment, that's completely fine \u2014 reply any time and I'll point you to it whenever it is.\r\n\r\n[Get the plan \u2192]\r\n\r\nThank you to everyone who's trusted me with this conversation.\r\n\r\nRach X`\r\n      }\r\n    ],\r\n    socials: [\r\n      {\r\n        type: 'Reframe post 1', date: '2027-03-15', platforms: ['Instagram','LinkedIn'],\r\n        angle: \"There's a real difference between exiting a practice properly and just eventually stopping.\",\r\n        ig: \"There's a real difference between exiting a practice properly and just eventually stopping.\\n\\nOne protects what you built. The other usually means selling for less, to whoever's available, on their timeline.\",\r\n        linkedin: \"Most practice owners think about their exit as a single future event, if they think about it at all. In reality, the difference between a proper exit and just eventually stopping (through exhaustion, ill health, or simply running out of road) is enormous \u2014 one protects the value you've built and the clients you care about, the other rarely does.\"\r\n      },\r\n      {\r\n        type: 'Reframe post 2', date: '2027-03-19', platforms: ['Instagram','LinkedIn'],\r\n        angle: \"The real worry usually isn't the money. It's what happens to the clients.\",\r\n        ig: \"The real worry about exiting a practice usually isn't the money.\\n\\nIt's what happens to the clients you've looked after for years.\",\r\n        linkedin: \"In conversations with practice owners thinking about winding down, the financial questions rarely come first. What comes first is almost always about the clients \u2014 will whoever takes over actually care the way they did. A proper succession plan addresses that directly, not just the valuation.\"\r\n      },\r\n      {\r\n        type: 'Carousel', date: '2027-03-21', platforms: ['Instagram'],\r\n        title: \"4 questions worth asking before you exit your practice\",\r\n        slides: [\r\n          \"HOOK: 4 questions worth asking before you exit your practice\",\r\n          \"1. Do you know what your practice is actually worth, or are you guessing?\",\r\n          \"2. Have you thought about what happens to your clients specifically, not just the business?\",\r\n          \"3. Sale, merger, gradual wind-down, or internal succession \u2014 which fits how you actually want this to go?\",\r\n          \"4. Are you planning this on your own timeline, or waiting until you're forced to decide?\",\r\n          \"CTA: Practice Exit & Succession Planning is open \u2014 link in bio.\"\r\n        ]\r\n      },\r\n      {\r\n        type: 'Short-form video 1', date: '2027-03-17', platforms: ['TikTok','YouTube Shorts'],\r\n        hook: \"A practice owner told me she wasn't ready to think about leaving. Here's what she actually meant.\",\r\n        pivot: \"It wasn't about the money \u2014 it was about her clients, and whether anyone would care for them the way she had.\",\r\n        consequence: \"That worry, unaddressed, is what keeps most practice owners from planning at all.\",\r\n        close: \"Practice Exit & Succession Planning \u2014 link in bio.\"\r\n      },\r\n      {\r\n        type: 'Short-form video 2', date: '2027-03-27', platforms: ['TikTok','YouTube Shorts'],\r\n        hook: \"You don't need to decide today. You just need a plan for when you do.\",\r\n        pivot: \"Having options mapped out doesn't commit you to using them this year.\",\r\n        consequence: \"Without a plan, the decision usually gets made for you, under pressure, later.\",\r\n        close: \"Closes Wednesday \u2014 link in bio.\"\r\n      }\r\n    ]\r\n  },\r\n  {\r\n    id: 'cis-vat',\r\n    name: 'CIS Returns & VAT Confidence Boost (as own lever)',\r\n    status: 'complete',\r\n    price: 'CIS Returns \u00a3716.40 \/ VAT Confidence Boost \u00a3716.40 (both confirmed, inc VAT)',\r\n    salesUrl: 'https:\/\/accountantshe.com\/cis-returns and https:\/\/accountantshe.com\/vat-confidence (PLACEHOLDERS \u2014 confirm real URLs)',\r\n    cartOpen: '2026-09-11',\r\n    cartClose: '2026-10-02',\r\n    earlyBird: { discount: '\u00a3100 off (ex-VAT)', standardPrice: '\u00a3716.40 each (inc VAT)', earlyBirdPrice: '\u00a3596.40 each (inc VAT)', endDate: '2026-09-18', rule: '>\u00a3500 ex-VAT (\u00a3597 ex-VAT each)' },\r\n    milestones: [\r\n      { date: '2026-09-04', label: 'PLV1 \u2014 belief-shift piece goes out' },\r\n      { date: '2026-09-07', label: 'PLV2 \u2014 proof\/technique piece goes out' },\r\n      { date: '2026-09-10', label: 'PLV3 \u2014 transformation + big reveal goes out' },\r\n      { date: '2026-09-11', label: 'Cart opens \u2014 early bird pricing live (both courses)' },\r\n      { date: '2026-09-18', label: 'Early bird ends \u2014 price rises to \u00a3716.40 each' },\r\n      { date: '2026-10-02', label: 'Cart closes' }\r\n    ],\r\n    theme: \"You've already shown us you're interested in this \u2014 you downloaded the pitfalls guide, maybe even bought the working papers. This is the complete course behind both, brought properly to the front instead of buried behind cheaper products.\",\r\n    outcome: \"By the end of the campaign, readers who engaged with the CIS or VAT lead magnets and working papers see the full course as the natural next step, and pick whichever track (CIS or VAT) matches the gap in their practice.\",\r\n    prelaunch: [\r\n      {\r\n        n: 1, date: '2026-09-04', time: '8:00am',\r\n        stage: 'PLV1 \u2014 Belief shift',\r\n        segment: 'CIS\/VAT pitfalls guide & Working Papers buyers',\r\n        title: \"It's not that you don't know VAT or CIS\",\r\n        preheader: \"It's the specific scenarios you double-check every time\",\r\n        purpose: \"Collapse the belief that hesitancy on CIS\/VAT is a knowledge gap \u2014 it's a confidence gap in specific rare scenarios.\",\r\n        cta: 'Reply \u2014 CIS or VAT, which trips you up more?',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: \"60-90 sec direct-to-camera, Rachel \u2014 knowledge gap vs confidence gap\",\r\n        body: `Most accountants aren't missing the underlying VAT or CIS knowledge. You know the rules.\r\n\r\nWhat's missing is confidence in the specific scenarios that come up rarely enough to never feel automatic \u2014 reverse charge, deemed contractor status, mixed supplies. The ones you double-check every single time instead of just knowing.\r\n\r\nMade a short video on this, since it's a different kind of problem to a knowledge gap \u2014 and it needs a different fix.\r\n\r\n[Watch \u2014 90 seconds \u2192]\r\n\r\nWhich one trips you up more \u2014 CIS or VAT? Hit reply.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 2, date: '2026-09-07', time: '8:00am',\r\n        stage: 'PLV2 \u2014 Proof & technique',\r\n        segment: 'Full list',\r\n        title: \"The CIS mistake that cost a colleague a client\",\r\n        preheader: \"A real story, and the check that would have caught it\",\r\n        purpose: \"Real case study + a usable technique (the verification timing check) they can take regardless of buying.\",\r\n        cta: 'Watch the full story',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: \"Rachel telling the real story behind one of the working paper checks \u2014 3 min\",\r\n        body: `I want to tell you about a mistake a colleague made early on with CIS verification.\r\n\r\nShe verified a subcontractor late \u2014 after the first payment had already gone out. It came back higher-rate. She was the one who had to have the conversation about clawing back tax from someone who'd already spent it.\r\n\r\nI recorded the full story, including the specific timing check that would have caught it \u2014 steal it for your own process regardless of anything else.\r\n\r\n[Watch the full story \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 3, date: '2026-09-10', time: '8:00am',\r\n        stage: 'PLV3 \u2014 Transformation, objections & the reveal',\r\n        segment: 'Full list',\r\n        title: \"\\\"I only need one of these\\\" \u2014 which should I pick?\",\r\n        preheader: \"Plus what's opening tomorrow\",\r\n        purpose: \"Help readers self-select CIS vs VAT, then reveal cart opens tomorrow with early bird.\",\r\n        cta: 'Watch: which one should I pick?',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: \"Short direct-to-camera helping readers choose between CIS and VAT \u2014 90 sec\",\r\n        body: `Fair question: \"I only need one of these right now, which should I actually pick?\"\r\n\r\nI made a short video walking through how to decide \u2014 mostly it comes down to which client type shows up more in your book right now.\r\n\r\n[Watch: which one should I pick? \u2192]\r\n\r\nTomorrow, both full courses open \u2014 CIS Returns and VAT Confidence Boost, with early bird pricing for the first week.\r\n\r\nRach X`\r\n      }\r\n    ],\r\n    emails: [\r\n      {\r\n        n: 1, date: '2026-09-11', time: '8:00am',\r\n        segment: 'CIS\/VAT pitfalls guide & Working Papers buyers day ahead \u2192 full list',\r\n        subject: \"It's open \u2014 CIS Returns & VAT Confidence Boost\",\r\n        preheader: \"As mentioned this week \u2014 early bird \u00a3596.40 each, ends 18 September\",\r\n        purpose: 'Cart open \/ full offer reveal',\r\n        cta: 'Claim the early bird price before 18 September',\r\n        video: false,\r\n        body: `As promised, both are open.\r\n\r\nCIS Returns and VAT Confidence Boost are the full courses behind the working papers a lot of you already own \u2014 everything properly taught, with the reasoning behind every check rather than just a template to fill in.\r\n\r\nEarly bird price \u00a3596.40 each (down from \u00a3716.40) until 18 September.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 2, date: '2026-09-17', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"Early bird ends tomorrow \u2014 which one is actually holding you back?\",\r\n        preheader: \"\u00a3596.40 each, gone from tomorrow \u2014 the honest breakdown of what each covers\",\r\n        purpose: 'Price-increase alert + reminder \u2014 help self-select track',\r\n        cta: 'Claim the early bird price before it ends',\r\n        video: false,\r\n        body: `Quick one today \u2014 early bird pricing on both CIS Returns and VAT Confidence Boost ends tomorrow. From 18 September it's back to \u00a3716.40 each.\r\n\r\nCIS Returns is for you if you've got (or want) construction industry clients and the verification, deemed-contractor, and gross-payment-status rules make you nervous.\r\n\r\nVAT Confidence Boost is for you if VAT scenarios \u2014 reverse charge, imports, mixed supplies \u2014 are the thing you double-check every single time instead of just knowing.\r\n\r\nDoors open Monday, both courses.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 3, date: '2026-09-21', time: '9:00am',\r\n        segment: 'Full list',\r\n        subject: \"CIS Returns and VAT Confidence Boost are open\",\r\n        preheader: \"\u00a3716.40 each, doors close 2 October\",\r\n        purpose: 'Launch day \/ cart open \u2014 full offer detail',\r\n        cta: 'Join CIS Returns or VAT Confidence Boost',\r\n        video: false,\r\n        body: `Both are open.\r\n\r\nCIS Returns: verification, deemed contractor status, gross payment status monitoring, the 2026 fraud rules, and the working papers to back it all up.\r\n\r\nVAT Confidence Boost: real scenarios \u2014 construction reverse charge, imports, mixed supplies, Flat Rate Scheme edge cases \u2014 with full working papers and the reasoning behind each one.\r\n\r\n\u00a3716.40 each. Doors close 2 October.\r\n\r\n[Join CIS Returns \u2192]\r\n[Join VAT Confidence Boost \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 4, date: '2026-09-24', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"What working-papers owners say after upgrading\",\r\n        preheader: \"Real feedback from people who already had the template\",\r\n        purpose: \"Social proof \u2014 genuine reaction from working-papers owners who upgraded, distinct from PLV2's mistake story\",\r\n        cta: 'Join CIS Returns or VAT Confidence Boost',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: \"Short screen-recording of 2-3 real upgrade-buyer quotes (with permission), Rachel reading them out \u2014 90 sec\",\r\n        body: `A few people who already owned the working papers and upgraded to the full course said things I wanted to pass on (with permission):\r\n\r\n\"Had the template for a year and never fully trusted it \u2014 the course is where I actually understood why each check matters.\"\r\n\r\n\"Wish I'd done this before, not after, the CIS mistake that nearly happened on my own book.\"\r\n\r\nI recorded a short video reading a couple of these out properly.\r\n\r\n[Watch \u2192]\r\n\r\nDoors close in 8 days.\r\n\r\n[Join CIS Returns \u2192]\r\n[Join VAT Confidence Boost \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 5, date: '2026-09-29', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"Your questions about CIS Returns & VAT Confidence Boost, answered\",\r\n        preheader: \"Overlap with the working papers, refunds, what's included\",\r\n        purpose: 'FAQ\/objection roundup \u2014 distinct from PLV3, addresses questions since cart open',\r\n        cta: 'Join before doors close',\r\n        video: false,\r\n        body: `What's actually been asked this week:\r\n\r\n\"I already own the working papers \u2014 am I paying twice for the same content?\" No \u2014 the course goes well beyond the template itself, into the reasoning and edge cases behind each check.\r\n\r\n\"Can I do both courses if I need them?\" Yes, no restriction either way.\r\n\r\n\"What if I start and it's not for me?\" 14-day money-back, no questions.\r\n\r\nDoors close Friday at midnight.\r\n\r\n[Join before midnight \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 6, date: '2026-10-02', time: '5:00pm (resend 9:30pm to non-openers)',\r\n        segment: 'Full list, then non-openers only for resend',\r\n        subject: \"Closes tonight \u2014 CIS Returns & VAT Confidence Boost\",\r\n        resendSubject: \"Last call (genuinely, midnight)\",\r\n        preheader: \"Midnight, then back to the working papers alone\",\r\n        purpose: 'Final close',\r\n        cta: 'Join before midnight',\r\n        video: false,\r\n        body: `Doors close tonight.\r\n\r\nIf CIS or VAT scenarios are the thing you double-check every time instead of just knowing, this is the moment that changes.\r\n\r\n[Join before midnight \u2192]\r\n\r\nThank you to everyone who's already joined.\r\n\r\nRach X\r\n\r\n---\r\nRESEND (non-openers only, 9:30pm):\r\nQuick one - doors close in a couple of hours. [Join before midnight \u2192]. No hard feelings if it's a no.`\r\n      }\r\n    ],\r\n    socials: [\r\n      {\r\n        type: 'Reframe post 1', date: '2026-09-14', platforms: ['Instagram','LinkedIn'],\r\n        angle: \"You already own the working papers. This is the full course behind them.\",\r\n        ig: \"You already own the CIS or VAT working papers.\\n\\nThis is the full course behind them \u2014 the reasoning behind every check, not just a template to fill in.\",\r\n        linkedin: \"A lot of you already own the CIS or VAT working papers as standalone downloads. CIS Returns and VAT Confidence Boost are the full courses behind those templates \u2014 the reasoning behind every check, taught properly, not just a document to fill in blind.\"\r\n      },\r\n      {\r\n        type: 'Reframe post 2', date: '2026-09-18', platforms: ['Instagram','LinkedIn'],\r\n        angle: \"It's not that you don't know VAT or CIS. It's the scenarios you double-check every time.\",\r\n        ig: \"It's not that you don't know VAT or CIS rules.\\n\\nIt's the specific scenarios you double-check every single time instead of just knowing.\",\r\n        linkedin: \"Most accountants aren't missing the underlying VAT or CIS knowledge \u2014 they're missing confidence in the specific scenarios that come up rarely enough to never feel automatic: reverse charge, deemed contractor status, mixed supplies. That's exactly what these two courses are built around.\"\r\n      },\r\n      {\r\n        type: 'Carousel', date: '2026-09-21', platforms: ['Instagram'],\r\n        title: \"CIS or VAT \u2014 which one is the bigger gap in your practice?\",\r\n        slides: [\r\n          \"HOOK: CIS or VAT \u2014 which one is the bigger gap in your practice?\",\r\n          \"CIS: do you have (or want) construction clients? Does verification and deemed contractor status make you nervous?\",\r\n          \"VAT: do reverse charge, imports, or mixed supplies make you double-check every time instead of just knowing?\",\r\n          \"TENSION: Both are genuinely common gaps \u2014 the difference is which one shows up more in your actual client book.\",\r\n          \"CTA: Both courses are open today \u2014 link in bio.\"\r\n        ]\r\n      },\r\n      {\r\n        type: 'Short-form video 1', date: '2026-09-16', platforms: ['TikTok','YouTube Shorts'],\r\n        hook: \"The CIS mistake that meant clawing back tax from a subcontractor who'd already spent it.\",\r\n        pivot: \"Reveal: verifying late, after the first payment had already gone out.\",\r\n        consequence: \"That conversation is never a fun one, and it's completely avoidable with the right process.\",\r\n        close: \"CIS Returns opens Monday \u2014 link in bio.\"\r\n      },\r\n      {\r\n        type: 'Short-form video 2', date: '2026-09-25', platforms: ['TikTok','YouTube Shorts'],\r\n        hook: \"The VAT scenario that catches even experienced accountants out.\",\r\n        pivot: \"Construction reverse charge \u2014 the end-user exception nobody checks properly.\",\r\n        consequence: \"Get it wrong and you've either over- or under-charged VAT on the whole job.\",\r\n        close: \"Doors close 2 October \u2014 link in bio.\"\r\n      }\r\n    ]\r\n  },\r\n  {\r\n    id: 'self-assessment',\r\n    name: 'Self-Assessment Tax Returns',\r\n    status: 'complete',\r\n    price: '\u00a31,440 inc VAT (\u00a31,200 ex-VAT)',\r\n    salesUrl: 'https:\/\/accountantshe.com\/self-assessment (PLACEHOLDER \u2014 confirm real URL)',\r\n    cartOpen: '2026-11-16',\r\n    cartClose: '2027-01-15',\r\n    dateFlag: \"\u26a0 Long window (60 days) deliberately spans Dec and Jan per Rebecca's instruction to catch both sales periods. This overlaps Boardroom (4\u201315 Jan, 12 days) \u2014 flagged, not fixed, since the long window was explicitly requested.\",\r\n    earlyBird: { discount: '\u00a3100 off', standardPrice: '\u00a31,440 inc VAT', earlyBirdPrice: '\u00a31,320 inc VAT', endDate: '2027-01-01', rule: '>\u00a3500 ex-VAT' },\r\n    milestones: [\r\n      { date: '2026-11-09', label: 'PLV1 \u2014 belief-shift piece goes out' },\r\n      { date: '2026-11-12', label: 'PLV2 \u2014 proof\/technique piece goes out' },\r\n      { date: '2026-11-15', label: 'PLV3 \u2014 transformation + big reveal goes out' },\r\n      { date: '2026-11-16', label: 'Cart opens \u2014 early bird pricing live' },\r\n      { date: '2027-01-01', label: 'Early bird ends \u2014 price rises to \u00a31,440' },\r\n      { date: '2027-01-15', label: 'Cart closes' }\r\n    ],\r\n    theme: \"January is coming whether you're ready or not. This is the course that turns Self Assessment season from a scramble into a system.\",\r\n    outcome: \"By the close, readers heading into their busiest quarter feel equipped for the scenarios that actually catch practices out \u2014 not just the mechanics they already know.\",\r\n    prelaunch: [\r\n      {\r\n        n: 1, date: '2026-11-09', time: '8:00am',\r\n        stage: 'PLV1 \u2014 Belief shift',\r\n        segment: 'Full list',\r\n        title: \"It's not the hard cases that catch practices out\",\r\n        preheader: \"It's the ones everyone assumes are simple\",\r\n        purpose: \"Collapse the belief that January risk sits in complex cases \u2014 it's actually the assumed-simple returns that slip through.\",\r\n        cta: 'Reply \u2014 what caught you out last January?',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: \"60-90 sec direct-to-camera, Rachel \u2014 complex cases vs assumed-simple ones\",\r\n        body: `The Self Assessment cases that go wrong in January are rarely the technically complex ones \u2014 those get proper attention because everyone knows to be careful with them.\r\n\r\nIt's the assumed-simple returns where something slips through: payments on account nobody warned the client about, a small dividend or savings interest nobody asked about, a capital gains event that surfaces too late.\r\n\r\nPut a short video together on this pattern \u2014 worth naming properly before the season actually starts.\r\n\r\n[Watch \u2014 90 seconds \u2192]\r\n\r\nWhat caught you out last January, if anything? Hit reply.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 2, date: '2026-11-12', time: '8:00am',\r\n        stage: 'PLV2 \u2014 Proof & technique',\r\n        segment: 'Full list',\r\n        title: \"The payments on account conversation nobody has early enough\",\r\n        preheader: \"A real scenario, and the script to use now\",\r\n        purpose: \"Genuine standalone value \u2014 a real scenario and a usable conversation script, free to use regardless of the course.\",\r\n        cta: 'Get the conversation script',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: 'Rachel walking through the POA conversation script \u2014 2-3 min',\r\n        body: `First-time filers looking at payments on account are often blindsided in January \u2014 the bill isn't just what they owe, it's that plus 50% towards next year, due the same day. Nearly double what they budgeted for.\r\n\r\nThat conversation needs to happen months before the deadline, not the week of it. I've written out the actual script I use \u2014 free to take and use with your own clients now.\r\n\r\n[Get the conversation script \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 3, date: '2026-11-15', time: '8:00am',\r\n        stage: 'PLV3 \u2014 Transformation & the reveal',\r\n        segment: 'Full list',\r\n        title: \"Why waiting until December costs more than the discount\",\r\n        preheader: \"Plus what's opening tomorrow\",\r\n        purpose: \"Collapse the 'I'll sort this closer to January' delay bias, then reveal cart opens tomorrow with early bird.\",\r\n        cta: 'Nothing to click yet \u2014 more tomorrow',\r\n        video: false,\r\n        body: `Easy to think there's plenty of time before January. There usually is, right up until there isn't.\r\n\r\nThe conversations this week have been about \u2014 payments on account, missing income, the assumed-simple cases \u2014 all need lead time to actually help a client. Waiting until December to get organised means having them too late to matter.\r\n\r\nTomorrow I'm opening the full course \u2014 everything from this week, plus what's actually new for this filing year.\r\n\r\nRach X`\r\n      }\r\n    ],\r\n    emails: [\r\n      {\r\n        n: 1, date: '2026-11-16', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"It's open \u2014 Self-Assessment Tax Returns\",\r\n        preheader: \"As mentioned this week \u2014 early bird \u00a31,320, ends 1 January\",\r\n        purpose: 'Cart open \/ full offer reveal',\r\n        cta: 'Claim the early bird price',\r\n        video: false,\r\n        body: `As promised, it's open.\r\n\r\nThis course covers the scenarios that actually catch practices out \u2014 payments on account nobody warned the client about, missing income clients forget to mention, the High Income Child Benefit Charge nobody checks every year, capital gains events that surface too late.\r\n\r\nOpen now, early bird \u00a31,320 (down from \u00a31,440) until 1 January.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 2, date: '2026-12-05', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"The missing income clients never think to mention\",\r\n        preheader: \"Savings interest, a small dividend, crypto gains \u2014 the quiet ones\",\r\n        purpose: \"Value \u2014 a different real scenario to PLV2's payments on account script, cost-framed\",\r\n        cta: 'Claim the early bird price',\r\n        video: false,\r\n        body: `Quick one today.\r\n\r\nThe income that gets missed on a return usually isn't the obvious stuff. It's a savings account nobody mentioned, a small dividend from shares held years ago, or a crypto disposal the client didn't think \"counted.\"\r\n\r\nEach one is a discovery risk later, not just a filing gap now. This course walks through exactly what to ask and when.\r\n\r\nEarly bird still open \u2014 \u00a31,320 until 1 January.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 3, date: '2026-12-30', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"Early bird ends Friday\",\r\n        preheader: \"Last few days at \u00a31,320 before it goes to \u00a31,440\",\r\n        purpose: 'Price-increase alert',\r\n        cta: 'Claim the early bird price before Friday',\r\n        video: false,\r\n        body: `Quick reminder \u2014 early bird pricing on Self-Assessment Tax Returns ends Friday, 1 January. From then it's back to \u00a31,440.\r\n\r\nIf January's already on your mind, this is the moment to get it sorted before the season actually starts.\r\n\r\n[Claim the early bird price \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 4, date: '2027-01-05', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"The SA102 rule that catches directors out this year\",\r\n        preheader: \"A real, current scenario (video inside)\",\r\n        purpose: 'Value\/proof \u2014 founder voice, current and specific',\r\n        cta: 'Watch the full breakdown',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: 'Rachel walking through the new SA102 per-directorship rule \u2014 3 min',\r\n        body: `Since 2025\/26, a close company director needs a separate employment page for each directorship \u2014 not one page listing several companies. Miss a box on any one and it's a \u00a360 penalty, per instance, per directorship.\r\n\r\nI recorded a full walkthrough of this and a few other scenarios that are genuinely new this year, not just the usual list.\r\n\r\n[Watch the full breakdown \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 5, date: '2027-01-10', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"Mid-season and drowning? This still helps\",\r\n        preheader: \"You don't need to finish it before you start using it\",\r\n        purpose: 'Future-pacing + objection handling',\r\n        cta: 'Join now',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: \"Short direct-to-camera on using the course mid-season, not just before it starts \u2014 90 sec\",\r\n        body: `If you're already knee-deep in January and wondering if it's too late to bother \u2014 it isn't. The working papers and pre-submission checklist are useful mid-season, not just as prep.\r\n\r\nI made a short video on getting value from this even if you're joining now rather than back in November.\r\n\r\n[Watch: is it too late? \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 6, date: '2027-01-15', time: '5:00pm (resend 9:30pm to non-openers)',\r\n        segment: 'Full list, then non-openers only for resend',\r\n        subject: \"Closes tonight \u2014 Self-Assessment Tax Returns\",\r\n        resendSubject: \"Last call before the season really hits\",\r\n        preheader: \"Midnight, then it's full attention on filing, not buying\",\r\n        purpose: 'Final close',\r\n        cta: 'Join before midnight',\r\n        video: false,\r\n        body: `Doors close tonight.\r\n\r\nWhatever's left of the season is easier with the working papers and checklist in hand than without.\r\n\r\n[Join before midnight \u2192]\r\n\r\nRach X\r\n\r\n---\r\nRESEND (non-openers only, 9:30pm):\r\nQuick one - doors close in a couple of hours. [Join before midnight \u2192]. No hard feelings if it's a no.`\r\n      }\r\n    ],\r\n    socials: [\r\n      {\r\n        type: 'Reframe post 1', date: '2026-11-16', platforms: ['Instagram','LinkedIn'],\r\n        angle: \"January doesn't catch practices out because of hard cases. It's the ones everyone assumes are simple.\",\r\n        ig: \"January doesn't usually catch practices out on the hard cases.\\n\\nIt's the ones everyone assumes are simple \u2014 until the payments on account bill lands and nobody warned the client.\",\r\n        linkedin: \"The Self Assessment cases that go wrong in January are rarely the technically complex ones \u2014 those get proper attention. It's the assumed-simple returns where payments on account, missing income, or a capital gains event nobody asked about slip through.\"\r\n      },\r\n      {\r\n        type: 'Reframe post 2', date: '2026-12-08', platforms: ['Instagram','LinkedIn'],\r\n        angle: \"The SA102 rule changed this year. Most practices haven't caught up yet.\",\r\n        ig: \"The SA102 rule changed this year.\\n\\nOne page per directorship now, not one page listing several. Most practices haven't caught up yet \u2014 and it's a \u00a360 penalty, per instance.\",\r\n        linkedin: \"From 2025\/26, close company directors need a separate SA102 employment page for each directorship, not one page listing multiple companies. It's a small procedural change with a real penalty attached, and it's easy to miss if you're working from last year's process.\"\r\n      },\r\n      {\r\n        type: 'Carousel', date: '2026-12-30', platforms: ['Instagram'],\r\n        title: \"5 Self Assessment scenarios that catch practices out every January\",\r\n        slides: [\r\n          \"HOOK: 5 Self Assessment scenarios that catch practices out every January\",\r\n          \"1. Payments on account blindsiding first-time filers.\",\r\n          \"2. Missing income \u2014 savings interest, a small dividend, crypto gains.\",\r\n          \"3. The High Income Child Benefit Charge nobody checks every year.\",\r\n          \"4. SA102 \u2014 one page per directorship now, not one page total.\",\r\n          \"TENSION: None of these are technically hard. All of them get missed under time pressure.\",\r\n          \"CTA: Early bird ends Friday \u2014 link in bio.\"\r\n        ]\r\n      },\r\n      {\r\n        type: 'Short-form video 1', date: '2026-11-20', platforms: ['TikTok','YouTube Shorts'],\r\n        hook: \"The Self Assessment bill that's nearly double what the client budgeted for.\",\r\n        pivot: \"Reveal: payments on account \u2014 the bill isn't just what's owed, it's that plus 50% towards next year.\",\r\n        consequence: \"Nobody warned them, so it lands as a shock the day before the deadline.\",\r\n        close: \"Self-Assessment Tax Returns, early bird open \u2014 link in bio.\"\r\n      },\r\n      {\r\n        type: 'Short-form video 2', date: '2027-01-06', platforms: ['TikTok','YouTube Shorts'],\r\n        hook: \"One SA102 page is now doing the job of several, and it's costing practices \u00a360 a time.\",\r\n        pivot: \"New rule: a separate employment page per directorship, not one page listing several companies.\",\r\n        consequence: \"Miss a box on any one and it's a penalty, per instance, per directorship.\",\r\n        close: \"Full breakdown inside the course \u2014 link in bio.\"\r\n      }\r\n    ]\r\n  },\r\n  {\r\n    id: 'cis-cohort-feb27',\r\n    name: 'CIS Live Cohort (6 sessions)',\r\n    status: 'complete',\r\n    price: 'TBC \u2014 placeholder used: \u00a31,000 + VAT\/session x6 (\u00a37,200 gross total), matching the Boardroom cohort structure. CONFIRM WITH REBECCA before using these figures.',\r\n    salesUrl: 'https:\/\/accountantshe.com\/cis-live-cohort (PLACEHOLDER \u2014 confirm real URL)',\r\n    cartOpen: '2027-01-25',\r\n    cartClose: '2027-02-12',\r\n    courseStart: '2027-02-15',\r\n    dateFlag: \"\u26a0 Q1 2027 is now very tight \u2014 Boardroom, this cohort, VAT cohort, and MTD IT all sit within a 10-week span with only 2-3 day gaps between them. Adding a proper 3-piece PLV prelaunch (below) makes this tighter still: PLV1-3 for this cohort now run 18\u201324 January, overlapping directly with Boardroom's own cart-close week (its emails 5-6 run 19-22 Jan). Workable if Rachel\/Rebecca are both sending, but there's no slack left in this stretch \u2014 worth a specific look before committing to it as written. Price is a placeholder copied from the Boardroom structure since none was given \u2014 confirm before this goes live.\",\r\n    earlyBird: { discount: '\u00a3100 off total package', standardPrice: '\u00a36,000 total ex-VAT', earlyBirdPrice: '\u00a35,900 total ex-VAT', endDate: '2027-01-29', rule: '>\u00a3500 ex-VAT (placeholder price)' },\r\n    milestones: [\r\n      { date: '2027-01-18', label: 'PLV1 \u2014 belief-shift piece goes out' },\r\n      { date: '2027-01-20', label: 'PLV2 \u2014 proof\/technique piece goes out (\u26a0 overlaps Boardroom close week)' },\r\n      { date: '2027-01-22', label: 'PLV3 \u2014 transformation + big reveal goes out (\u26a0 same day Boardroom closes)' },\r\n      { date: '2027-01-25', label: 'Cart opens \u2014 early bird pricing live' },\r\n      { date: '2027-01-29', label: 'Early bird ends \u2014 standard pricing applies' },\r\n      { date: '2027-02-12', label: 'Cart closes' },\r\n      { date: '2027-02-15', label: 'Cohort starts (runs alongside VAT Live Cohort)' }\r\n    ],\r\n    theme: \"The standalone CIS course teaches the framework. This is six live sessions working through your actual client scenarios with a small group, not just watching a recording.\",\r\n    outcome: \"By the end, readers who found the standalone course useful but wanted live, worked examples see this cohort as the natural next step \u2014 running side by side with the VAT cohort for anyone who wants both.\",\r\n    prelaunch: [\r\n      {\r\n        n: 1, date: '2027-01-18', time: '8:00am',\r\n        stage: 'PLV1 \u2014 Belief shift',\r\n        segment: 'CIS Returns course owners',\r\n        title: \"You don't need another course. You need your scenario worked through.\",\r\n        preheader: \"The gap a recording can't close\",\r\n        purpose: \"Collapse the belief that another module\/recording closes the gap \u2014 real-world CIS variation needs live, worked feedback.\",\r\n        cta: \"Reply \u2014 what CIS scenario doesn't quite match the course examples?\",\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: \"60-90 sec direct-to-camera, Rachel \u2014 why CIS specifically needs live working-through\",\r\n        body: `If you already own CIS Returns, here's something worth naming.\r\n\r\nThe framework in the course is solid \u2014 but every construction client's situation is slightly different, and no recording can cover every variation you'll actually hit. The gap isn't knowledge, it's not having your specific scenario worked through by someone else.\r\n\r\nRecorded a short video on this \u2014 it's the reason I'm opening something different to the course itself this week.\r\n\r\n[Watch \u2014 90 seconds \u2192]\r\n\r\nWhat's the CIS scenario that doesn't quite match the course examples for you? Hit reply.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 2, date: '2027-01-20', time: '8:00am',\r\n        stage: 'PLV2 \u2014 Proof & technique',\r\n        segment: 'Full list',\r\n        title: \"Why live beats another recording for this specific topic\",\r\n        preheader: \"The honest reasoning, worked through with a real example\",\r\n        purpose: \"Genuine reasoning + a worked example, standalone value regardless of joining anything.\",\r\n        cta: 'Watch the full reasoning',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: 'Rachel explaining why CIS specifically benefits from live working-through, with a real worked example \u2014 3 min',\r\n        body: `CIS is one of the areas where the framework is simple but the real-world scenarios are genuinely varied \u2014 every construction client's situation is slightly different.\r\n\r\nI recorded a full explanation of why, working through one real example live, because it's more useful seeing it than reading about it.\r\n\r\n[Watch the full reasoning \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 3, date: '2027-01-22', time: '8:00am',\r\n        stage: 'PLV3 \u2014 Transformation & the reveal',\r\n        segment: 'Full list',\r\n        title: \"I already own the course \u2014 is a live cohort still worth it?\",\r\n        preheader: \"Plus what's opening Monday\",\r\n        purpose: \"Handle the top objection for existing course owners, then reveal cart opens Monday.\",\r\n        cta: 'Nothing to click yet \u2014 more Monday',\r\n        video: false,\r\n        body: `Fair question if you already own CIS Returns: would a live cohort actually be worth it on top?\r\n\r\nHonestly, if the course gave you the framework and you're now hitting real scenarios that don't quite match the examples, yes. That's the exact gap this closes.\r\n\r\nMonday, I'm opening a live cohort \u2014 six sessions, working through real scenarios as a small group, running alongside a VAT version if you want both.\r\n\r\nRach X`\r\n      }\r\n    ],\r\n    emails: [\r\n      {\r\n        n: 1, date: '2027-01-25', time: '8:00am',\r\n        segment: 'CIS Returns course owners day ahead \u2192 full list',\r\n        subject: \"It's open \u2014 CIS Live Cohort\",\r\n        preheader: \"As mentioned last week \u2014 running alongside the VAT cohort\",\r\n        purpose: 'Cart open \/ full offer reveal',\r\n        cta: 'Claim your spot',\r\n        video: false,\r\n        body: `As promised, it's open.\r\n\r\nSix live sessions, working through actual client scenarios as a small group, not just watching a recording alone.\r\n\r\nRunning alongside the VAT Live Cohort if you want both. Early bird pricing open now.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 2, date: '2027-01-28', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"Early bird ends tomorrow\",\r\n        preheader: \"Last day before standard pricing kicks in\",\r\n        purpose: 'Price-increase alert',\r\n        cta: 'Claim the early bird price today',\r\n        video: false,\r\n        body: `Quick one today \u2014 early bird pricing on the CIS Live Cohort ends tomorrow.\r\n\r\nIf working through real CIS scenarios live, with a small group and direct feedback, is more useful to you than another recording, this is that.\r\n\r\n[Claim the early bird price \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 3, date: '2027-02-01', time: '9:00am',\r\n        segment: 'Full list',\r\n        subject: \"CIS Live Cohort is open\",\r\n        preheader: \"Six sessions, starts 15 February\",\r\n        purpose: 'Launch day \/ cart open',\r\n        cta: 'Join the cohort',\r\n        video: false,\r\n        body: `It's open.\r\n\r\nSix live sessions working through real CIS scenarios \u2014 verification, deemed contractor status, gross payment status, the 2026 fraud rules \u2014 as a small group, with direct feedback on your actual questions.\r\n\r\nStarts 15 February. Doors close 12 February.\r\n\r\n[Join the cohort \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 4, date: '2027-02-05', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"What the six CIS sessions actually cover\",\r\n        preheader: \"Session by session, for anyone deciding before doors close\",\r\n        purpose: \"Mid-cart curriculum breakdown \u2014 distinct from PLV2's reasoning piece\",\r\n        cta: 'Join the cohort',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: \"Short screen-recording talking through the 6-session structure on screen \u2014 2 min\",\r\n        body: `A few of you have asked for the session-by-session breakdown before deciding, so here it is \u2014 recorded a quick walkthrough rather than just listing it.\r\n\r\n[Watch the breakdown \u2192]\r\n\r\nSessions 1-2: verification and deemed contractor status, working through real cases submitted by the group.\r\nSessions 3-4: gross payment status monitoring and the 2026 fraud rules.\r\nSessions 5-6: your own live scenarios, whatever's actually in front of you that week.\r\n\r\nDoors close in 7 days.\r\n\r\n[Join the cohort \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 5, date: '2027-02-09', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"Your questions about the CIS Live Cohort, answered\",\r\n        preheader: \"Missed sessions, refunds, group size\",\r\n        purpose: \"FAQ\/objection roundup \u2014 distinct from PLV3's already-own-the-course objection\",\r\n        cta: 'Join the cohort',\r\n        video: false,\r\n        body: `What's actually been asked this week:\r\n\r\n\"What if I miss a session?\" Recorded and shared with the group, but live is genuinely better for the working-through element.\r\n\r\n\"How big is the group?\" Small \u2014 capped, so real feedback stays possible for everyone.\r\n\r\n\"Refund if it's not for me?\" 14-day money-back, no questions.\r\n\r\nDoors close Friday.\r\n\r\n[Join the cohort \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 6, date: '2027-02-12', time: '5:00pm',\r\n        segment: 'Full list',\r\n        subject: \"Closes tonight \u2014 CIS Live Cohort\",\r\n        preheader: \"Starts 15 February either way\",\r\n        purpose: 'Final close',\r\n        cta: 'Join before midnight',\r\n        video: false,\r\n        body: `Doors close tonight. Starts 15 February.\r\n\r\n[Join before midnight \u2192]\r\n\r\nRach X`\r\n      }\r\n    ],\r\n    socials: [\r\n      {\r\n        type: 'Reframe post 1', date: '2027-01-25', platforms: ['Instagram','LinkedIn'],\r\n        angle: \"A course teaches the framework. A live cohort works through your actual scenario.\",\r\n        ig: \"A course teaches you the framework.\\n\\nA live cohort works through your actual client scenario, with real feedback, not just a generic example.\",\r\n        linkedin: \"CIS Returns gives you the full framework \u2014 but every construction client's situation is slightly different, and a pre-recorded course can only cover so many examples. The CIS Live Cohort is six sessions working through real, submitted scenarios as a small group.\"\r\n      },\r\n      {\r\n        type: 'Reframe post 2', date: '2027-01-29', platforms: ['Instagram','LinkedIn'],\r\n        angle: \"Running alongside the VAT cohort \u2014 pick one or both.\",\r\n        ig: \"CIS and VAT live cohorts are running side by side this February.\\n\\nPick whichever is the bigger gap in your practice \u2014 or both.\",\r\n        linkedin: \"Two live cohorts open this February, running in parallel: CIS and VAT. Both six sessions, both built around real client scenarios rather than generic examples. Join whichever matches your practice's actual gap.\"\r\n      },\r\n      {\r\n        type: 'Carousel', date: '2027-02-01', platforms: ['Instagram'],\r\n        title: \"Is the CIS Live Cohort right for you?\",\r\n        slides: [\r\n          \"HOOK: Is the CIS Live Cohort right for you?\",\r\n          \"1. Do you already own the CIS Returns course but keep hitting scenarios that don't quite match the examples?\",\r\n          \"2. Would live feedback on your actual client situation help more than another recording?\",\r\n          \"3. Are you building or growing a construction client base right now?\",\r\n          \"CTA: Six sessions, starts 15 February \u2014 link in bio.\"\r\n        ]\r\n      },\r\n      {\r\n        type: 'Short-form video 1', date: '2027-01-27', platforms: ['TikTok','YouTube Shorts'],\r\n        hook: \"Why I built a live CIS cohort instead of just another recorded module.\",\r\n        pivot: \"Every construction client's situation is different \u2014 a recording can only cover so many examples.\",\r\n        consequence: \"Live means your actual scenario gets worked through, not a generic one.\",\r\n        close: \"CIS Live Cohort opens now \u2014 link in bio.\"\r\n      },\r\n      {\r\n        type: 'Short-form video 2', date: '2027-02-06', platforms: ['TikTok','YouTube Shorts'],\r\n        hook: \"CIS and VAT live cohorts, running side by side this February.\",\r\n        pivot: \"Same six-session structure, different topic \u2014 pick your gap.\",\r\n        consequence: \"Both close 12 February.\",\r\n        close: \"Link in bio for either or both.\"\r\n      }\r\n    ]\r\n  },\r\n  {\r\n    id: 'vat-cohort-feb27',\r\n    name: 'VAT Live Cohort (6 sessions)',\r\n    status: 'complete',\r\n    price: 'TBC \u2014 placeholder used: \u00a31,000 + VAT\/session x6 (\u00a37,200 gross total), matching the Boardroom cohort structure. CONFIRM WITH REBECCA before using these figures.',\r\n    salesUrl: 'https:\/\/accountantshe.com\/vat-live-cohort (PLACEHOLDER \u2014 confirm real URL)',\r\n    cartOpen: '2027-01-25',\r\n    cartClose: '2027-02-12',\r\n    courseStart: '2027-02-15',\r\n    dateFlag: \"\u26a0 Same window as the CIS Live Cohort, deliberately \u2014 running side by side per Rebecca's instruction. Adding the PLV prelaunch (below) means this also overlaps Boardroom's cart-close week (18-22 Jan), same as the CIS cohort \u2014 see that launch's dateFlag for the detail. Price is a placeholder copied from the Boardroom structure since none was given \u2014 confirm before this goes live.\",\r\n    earlyBird: { discount: '\u00a3100 off total package', standardPrice: '\u00a36,000 total ex-VAT', earlyBirdPrice: '\u00a35,900 total ex-VAT', endDate: '2027-01-29', rule: '>\u00a3500 ex-VAT (placeholder price)' },\r\n    milestones: [\r\n      { date: '2027-01-18', label: 'PLV1 \u2014 belief-shift piece goes out' },\r\n      { date: '2027-01-20', label: 'PLV2 \u2014 proof\/technique piece goes out (\u26a0 overlaps Boardroom close week)' },\r\n      { date: '2027-01-22', label: 'PLV3 \u2014 transformation + big reveal goes out (\u26a0 same day Boardroom closes)' },\r\n      { date: '2027-01-25', label: 'Cart opens \u2014 early bird pricing live' },\r\n      { date: '2027-01-29', label: 'Early bird ends \u2014 standard pricing applies' },\r\n      { date: '2027-02-12', label: 'Cart closes' },\r\n      { date: '2027-02-15', label: 'Cohort starts (runs alongside CIS Live Cohort)' }\r\n    ],\r\n    theme: \"The standalone VAT course teaches the scenarios. This is six live sessions working through your actual client cases with a small group.\",\r\n    outcome: \"By the end, readers who found the standalone course useful but wanted live, worked examples see this cohort as the natural next step \u2014 running side by side with the CIS cohort for anyone who wants both.\",\r\n    prelaunch: [\r\n      {\r\n        n: 1, date: '2027-01-18', time: '8:00am',\r\n        stage: 'PLV1 \u2014 Belief shift',\r\n        segment: 'VAT Confidence Boost course owners',\r\n        title: \"You don't need another course. You need your case worked through.\",\r\n        preheader: \"The gap a recording can't close\",\r\n        purpose: \"Collapse the belief that another module\/recording closes the gap \u2014 real VAT cases never quite match the textbook example.\",\r\n        cta: \"Reply \u2014 what VAT scenario doesn't quite match the course examples?\",\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: \"60-90 sec direct-to-camera, Rachel \u2014 why VAT specifically needs live working-through\",\r\n        body: `If you already own VAT Confidence Boost, here's something worth naming.\r\n\r\nThe scenario library in the course is thorough \u2014 but real client cases never quite match the textbook example, and no recording can cover every variation you'll actually hit. The gap isn't knowledge, it's not having your specific case worked through by someone else.\r\n\r\nMade a short video on this one \u2014 same reason, opening something alongside the course itself this week.\r\n\r\n[Watch \u2014 90 seconds \u2192]\r\n\r\nWhat's the VAT scenario that doesn't quite match the course examples for you? Hit reply.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 2, date: '2027-01-20', time: '8:00am',\r\n        stage: 'PLV2 \u2014 Proof & technique',\r\n        segment: 'Full list',\r\n        title: \"Why live beats another recording for this specific topic\",\r\n        preheader: \"The honest reasoning, worked through with a real example\",\r\n        purpose: \"Genuine reasoning + a worked example, standalone value regardless of joining anything.\",\r\n        cta: 'Watch the full reasoning',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: 'Rachel explaining why VAT specifically benefits from live working-through, with a real worked example \u2014 3 min',\r\n        body: `VAT is one of those areas where the rules are clear but the real scenarios never quite match the textbook example.\r\n\r\nI recorded a full explanation of why, working through one real example live, because it's more useful seeing it than reading about it.\r\n\r\n[Watch the full reasoning \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 3, date: '2027-01-22', time: '8:00am',\r\n        stage: 'PLV3 \u2014 Transformation & the reveal',\r\n        segment: 'Full list',\r\n        title: \"I already own the course \u2014 is a live cohort still worth it?\",\r\n        preheader: \"Plus what's opening Monday\",\r\n        purpose: \"Handle the top objection for existing course owners, then reveal cart opens Monday.\",\r\n        cta: 'Nothing to click yet \u2014 more Monday',\r\n        video: false,\r\n        body: `Fair question if you already own VAT Confidence Boost: would a live cohort actually be worth it on top?\r\n\r\nHonestly, if the course gave you the scenario library and you're now hitting real cases that don't quite match it, yes. That's the exact gap this closes.\r\n\r\nMonday, I'm opening a live cohort \u2014 six sessions, working through real cases as a small group, running alongside a CIS version if you want both.\r\n\r\nRach X`\r\n      }\r\n    ],\r\n    emails: [\r\n      {\r\n        n: 1, date: '2027-01-25', time: '8:00am',\r\n        segment: 'VAT Confidence Boost course owners day ahead \u2192 full list',\r\n        subject: \"It's open \u2014 VAT Live Cohort\",\r\n        preheader: \"As mentioned last week \u2014 running alongside the CIS cohort\",\r\n        purpose: 'Cart open \/ full offer reveal',\r\n        cta: 'Claim your spot',\r\n        video: false,\r\n        body: `As promised, it's open.\r\n\r\nSix live sessions, working through your actual client cases as a small group, not just watching a recording alone.\r\n\r\nRunning alongside the CIS Live Cohort if you want both. Early bird pricing open now.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 2, date: '2027-01-28', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"Early bird ends tomorrow\",\r\n        preheader: \"Last day before standard pricing kicks in\",\r\n        purpose: 'Price-increase alert',\r\n        cta: 'Claim the early bird price today',\r\n        video: false,\r\n        body: `Quick one today \u2014 early bird pricing on the VAT Live Cohort ends tomorrow.\r\n\r\nIf working through real VAT scenarios live, with direct feedback on your actual questions, is more useful than another recording, this is that.\r\n\r\n[Claim the early bird price \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 3, date: '2027-02-01', time: '9:00am',\r\n        segment: 'Full list',\r\n        subject: \"VAT Live Cohort is open\",\r\n        preheader: \"Six sessions, starts 15 February\",\r\n        purpose: 'Launch day \/ cart open',\r\n        cta: 'Join the cohort',\r\n        video: false,\r\n        body: `It's open.\r\n\r\nSix live sessions working through real VAT scenarios \u2014 reverse charge, imports, mixed supplies, Flat Rate Scheme edge cases \u2014 as a small group, with direct feedback on your actual questions.\r\n\r\nStarts 15 February. Doors close 12 February.\r\n\r\n[Join the cohort \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 4, date: '2027-02-05', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"What the six VAT sessions actually cover\",\r\n        preheader: \"Session by session, for anyone deciding before doors close\",\r\n        purpose: \"Mid-cart curriculum breakdown \u2014 distinct from PLV2's reasoning piece\",\r\n        cta: 'Join the cohort',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: \"Short screen-recording talking through the 6-session structure on screen \u2014 2 min\",\r\n        body: `A few of you have asked for the session-by-session breakdown before deciding, so here it is \u2014 recorded a quick walkthrough rather than just listing it.\r\n\r\n[Watch the breakdown \u2192]\r\n\r\nSessions 1-2: reverse charge and imports, working through real cases submitted by the group.\r\nSessions 3-4: mixed supplies and Flat Rate Scheme edge cases.\r\nSessions 5-6: your own live scenarios, whatever's actually in front of you that week.\r\n\r\nDoors close in 7 days.\r\n\r\n[Join the cohort \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 5, date: '2027-02-09', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"Your questions about the VAT Live Cohort, answered\",\r\n        preheader: \"Missed sessions, refunds, group size\",\r\n        purpose: \"FAQ\/objection roundup \u2014 distinct from PLV3's already-own-the-course objection\",\r\n        cta: 'Join the cohort',\r\n        video: false,\r\n        body: `What's actually been asked this week:\r\n\r\n\"What if I miss a session?\" Recorded and shared with the group, but live is genuinely better for the working-through element.\r\n\r\n\"How big is the group?\" Small \u2014 capped, so real feedback stays possible for everyone.\r\n\r\n\"Refund if it's not for me?\" 14-day money-back, no questions.\r\n\r\nDoors close Friday.\r\n\r\n[Join the cohort \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 6, date: '2027-02-12', time: '5:00pm',\r\n        segment: 'Full list',\r\n        subject: \"Closes tonight \u2014 VAT Live Cohort\",\r\n        preheader: \"Starts 15 February either way\",\r\n        purpose: 'Final close',\r\n        cta: 'Join before midnight',\r\n        video: false,\r\n        body: `Doors close tonight. Starts 15 February.\r\n\r\n[Join before midnight \u2192]\r\n\r\nRach X`\r\n      }\r\n    ],\r\n    socials: [\r\n      {\r\n        type: 'Reframe post 1', date: '2027-01-26', platforms: ['Instagram','LinkedIn'],\r\n        angle: \"A course teaches the scenarios. A live cohort works through your actual case.\",\r\n        ig: \"A course teaches you the scenarios.\\n\\nA live cohort works through your actual client case, with real feedback.\",\r\n        linkedin: \"VAT Confidence Boost gives you the scenario library \u2014 but real client situations never quite match the textbook example. The VAT Live Cohort is six sessions working through real, current cases as a small group.\"\r\n      },\r\n      {\r\n        type: 'Reframe post 2', date: '2027-01-30', platforms: ['Instagram','LinkedIn'],\r\n        angle: \"Running alongside the CIS cohort \u2014 pick one or both.\",\r\n        ig: \"CIS and VAT live cohorts are running side by side this February.\\n\\nPick whichever is the bigger gap \u2014 or both.\",\r\n        linkedin: \"Two live cohorts open this February, running in parallel: CIS and VAT. Both six sessions, both built around real client scenarios. Join whichever matches your practice's actual gap.\"\r\n      },\r\n      {\r\n        type: 'Carousel', date: '2027-02-02', platforms: ['Instagram'],\r\n        title: \"Is the VAT Live Cohort right for you?\",\r\n        slides: [\r\n          \"HOOK: Is the VAT Live Cohort right for you?\",\r\n          \"1. Do you already own VAT Confidence Boost but keep hitting scenarios that don't quite match the examples?\",\r\n          \"2. Would live feedback on your actual client situation help more than another recording?\",\r\n          \"3. Do reverse charge, imports, or mixed supplies come up often enough to be worth deeper support?\",\r\n          \"CTA: Six sessions, starts 15 February \u2014 link in bio.\"\r\n        ]\r\n      },\r\n      {\r\n        type: 'Short-form video 1', date: '2027-01-28', platforms: ['TikTok','YouTube Shorts'],\r\n        hook: \"Why I built a live VAT cohort instead of just another recorded module.\",\r\n        pivot: \"Real scenarios never quite match the textbook example \u2014 a recording can only cover so much.\",\r\n        consequence: \"Live means your actual case gets worked through, not a generic one.\",\r\n        close: \"VAT Live Cohort opens now \u2014 link in bio.\"\r\n      },\r\n      {\r\n        type: 'Short-form video 2', date: '2027-02-07', platforms: ['TikTok','YouTube Shorts'],\r\n        hook: \"CIS and VAT live cohorts, running side by side this February.\",\r\n        pivot: \"Same six-session structure, different topic \u2014 pick your gap.\",\r\n        consequence: \"Both close 12 February.\",\r\n        close: \"Link in bio for either or both.\"\r\n      }\r\n    ]\r\n  },\r\n  {\r\n    id: 'mtd-it-course',\r\n    name: 'MTD IT: The 6-Week Course',\r\n    status: 'complete',\r\n    price: '\u00a3365 inc VAT (\u00a3304.17 ex-VAT) \u2014 NEW course, not previously in the funnel map',\r\n    salesUrl: 'https:\/\/accountantshe.com\/mtd-it-course (PLACEHOLDER \u2014 confirm real URL)',\r\n    cartOpen: '2027-02-15',\r\n    cartClose: '2027-03-08',\r\n    courseStart: '2027-03-09',\r\n    dateFlag: \"\u26a0 New product, built fresh at Rebecca's request \u2014 not in the original funnel map or revenue recovery plan. Q1 2027 is very tight; this sits with only a 3-day gap after the CIS\/VAT cohorts close. Adding a proper 3-piece PLV prelaunch (below) doesn't fit in that 3-day gap at all \u2014 PLV1-3 would need to run 9-13 February, which sits entirely inside the CIS\/VAT Live Cohort's own cart-open window (25 Jan-12 Feb) and its cohort sessions starting 15 Feb. This is a genuine scheduling conflict, not just a tight one: as things stand, subscribers would be getting CIS\/VAT cohort emails and MTD IT prelaunch emails in the same week. Worth deciding whether to compress this to a 2-piece PLV, push MTD IT's whole window back, or accept the overlap \u2014 flagging rather than silently resolving it.\",\r\n    earlyBird: { discount: '10% off', standardPrice: '\u00a3365 inc VAT', earlyBirdPrice: '\u00a3328.50 inc VAT', endDate: '2027-02-22', rule: '<\u00a3500 ex-VAT, new course' },\r\n    milestones: [\r\n      { date: '2027-02-09', label: 'PLV1 \u2014 belief-shift piece goes out (\u26a0 overlaps CIS\/VAT cohort cart-open window)' },\r\n      { date: '2027-02-11', label: 'PLV2 \u2014 proof\/technique piece goes out (\u26a0 same overlap)' },\r\n      { date: '2027-02-13', label: 'PLV3 \u2014 transformation + big reveal goes out (\u26a0 same overlap, 2 days before CIS\/VAT cohorts start)' },\r\n      { date: '2027-02-15', label: 'Cart opens \u2014 early bird pricing live' },\r\n      { date: '2027-02-22', label: 'Early bird ends \u2014 standard pricing applies' },\r\n      { date: '2027-03-08', label: 'Cart closes' },\r\n      { date: '2027-03-09', label: 'Course opens \u2014 6 weeks begin' }\r\n    ],\r\n    theme: \"MTD for Income Tax isn't optional anymore. This is the structured, six-week route to being genuinely ready \u2014 not scrambling client by client as the mandation deadlines land.\",\r\n    outcome: \"By the end of the campaign, readers with MTD-mandated (or soon-to-be-mandated) clients feel they have a clear, paced plan to get ready, rather than facing it one confused client at a time.\",\r\n    prelaunch: [\r\n      {\r\n        n: 1, date: '2027-02-09', time: '8:00am',\r\n        stage: 'PLV1 \u2014 Belief shift',\r\n        segment: 'MTD pitfalls guide subscribers',\r\n        title: \"You probably have more mandated clients than you think\",\r\n        preheader: \"The combined-income trap\",\r\n        purpose: \"Collapse the belief that 'none of my clients are affected yet' \u2014 combined income sources catch more people than practices realise.\",\r\n        cta: 'Reply \u2014 have you checked combined income sources yet?',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: \"60-90 sec direct-to-camera, Rachel \u2014 the combined-income scoping trap\",\r\n        body: `One of the most common MTD scoping mistakes isn't a technical error \u2014 it's checking income sources separately instead of combined.\r\n\r\nA client who looks safely under the threshold on paper can be very much in scope once sole trade income and rental income, say, are added together. Nobody checks the combination until it's too late.\r\n\r\nFilmed a quick one on this \u2014 worth checking now, before the pressure hits, not after.\r\n\r\n[Watch \u2014 90 seconds \u2192]\r\n\r\nHave you checked combined income sources across your client list yet? Hit reply.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 2, date: '2027-02-11', time: '8:00am',\r\n        stage: 'PLV2 \u2014 Proof & technique',\r\n        segment: 'Full list',\r\n        title: \"The MTD mistake that's easiest to make and hardest to unpick\",\r\n        preheader: \"A real story, and the check that catches it\",\r\n        purpose: \"Real case study + a usable scoping check they can run today.\",\r\n        cta: 'Watch the full story',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: 'Rachel telling a real story about a client wrongly assessed as out of scope \u2014 3 min',\r\n        body: `I want to tell you about a client who looked comfortably under the MTD threshold on paper \u2014 until we combined their sole trade income with their rental income, which pushed them well over.\r\n\r\nNobody had checked the combination. I recorded the full story, including the specific check that would have caught it \u2014 free to run on your own client list regardless of anything else.\r\n\r\n[Watch the full story \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 3, date: '2027-02-13', time: '8:00am',\r\n        stage: 'PLV3 \u2014 Transformation & the reveal',\r\n        segment: 'Full list',\r\n        title: \"\\\"I don't have any mandated clients yet\\\" \u2014 should I still prepare?\",\r\n        preheader: \"Plus what's opening Monday\",\r\n        purpose: \"Handle the top objection honestly, then reveal cart opens Monday.\",\r\n        cta: 'Nothing to click yet \u2014 more Monday',\r\n        video: false,\r\n        body: `Fair question: if none of your clients are mandated yet, is preparing now worth it?\r\n\r\nHonestly, yes \u2014 the combined-income trap means more clients are in scope than practices realise, and getting the process built before the pressure hits beats building it under pressure.\r\n\r\nMonday, everything from this week becomes a proper structured course \u2014 six weeks, paced, from scoping through to your first live quarterly submission.\r\n\r\nRach X`\r\n      }\r\n    ],\r\n    emails: [\r\n      {\r\n        n: 1, date: '2027-02-15', time: '8:00am',\r\n        segment: 'MTD pitfalls guide subscribers day ahead \u2192 full list',\r\n        subject: \"It's open \u2014 MTD IT: The 6-Week Course\",\r\n        preheader: \"As mentioned this week \u2014 early bird \u00a3328.50, ends 22 February\",\r\n        purpose: 'Cart open \/ full offer reveal',\r\n        cta: 'Claim the early bird price',\r\n        video: false,\r\n        body: `As promised, it's open.\r\n\r\nMTD for Income Tax mandation is landing whether practices are ready or not \u2014 checking which clients are in scope, sorting software, repricing before quarterly submissions start eating four times the touchpoints of an annual return.\r\n\r\nThis is a structured six-week route through all of it, paced so it's actually doable alongside client work rather than crammed into one panicked week.\r\n\r\nEarly bird \u00a3328.50 (down from \u00a3365) until 22 February. Course starts 9 March.\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 2, date: '2027-02-21', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"Early bird ends tomorrow\",\r\n        preheader: \"\u00a3328.50, gone from 22 February\",\r\n        purpose: 'Price-increase alert',\r\n        cta: 'Claim the early bird price today',\r\n        video: false,\r\n        body: `Quick one today \u2014 early bird pricing on the MTD IT course ends tomorrow. From 22 February it's back to \u00a3365.\r\n\r\nIf you've got clients whose mandation date is creeping closer and you haven't got a clear plan yet, this is the moment to sort it before the six weeks start.\r\n\r\n[Claim the early bird price \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 3, date: '2027-02-24', time: '9:00am',\r\n        segment: 'Full list',\r\n        subject: \"What the six weeks actually cover\",\r\n        preheader: \"Week by week, from scope-checking to your first live quarter\",\r\n        purpose: 'Full offer detail',\r\n        cta: 'Join the course',\r\n        video: false,\r\n        body: `Here's the six-week shape:\r\n\r\nWeek 1: checking which clients are actually in scope (the combined-income trap catches more people than you'd think)\r\nWeek 2: software \u2014 what actually finishes the job, not just handles quarterly updates\r\nWeek 3: repricing before mandation hits\r\nWeek 4: capacity planning for the quarterly crunch\r\nWeek 5: the basis period and transitional edge cases most software won't flag\r\nWeek 6: your first live quarterly submission, walked through properly\r\n\r\n\u00a3365 + VAT. Starts 9 March, doors close 8 March.\r\n\r\n[Join the course \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 4, date: '2027-02-27', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"What early joiners are already finding in their client list\",\r\n        preheader: \"Real reactions from this week's joiners\",\r\n        purpose: 'Social proof \u2014 distinct from PLV2\\'s founder story',\r\n        cta: 'Join the course',\r\n        video: true,\r\n        filmedBy: 'Rachel',\r\n        videoNote: \"Short screen-recording of 2 real early-joiner replies (with permission), Rachel reading them out \u2014 90 sec\",\r\n        body: `A few people who joined this week have already replied:\r\n\r\n\"Ran the combined-income check on my client list in week one \u2014 found two clients I hadn't flagged.\"\r\n\r\n\"The repricing module alone justified the cost, I'd been putting that conversation off.\"\r\n\r\nRecorded a short video reading these out properly.\r\n\r\n[Watch \u2192]\r\n\r\nDoors close in 9 days.\r\n\r\n[Join the course \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 5, date: '2027-03-03', time: '8:00am',\r\n        segment: 'Full list',\r\n        subject: \"Your questions about MTD IT: The 6-Week Course, answered\",\r\n        preheader: \"Timing, refunds, what's included\",\r\n        purpose: 'FAQ\/objection roundup \u2014 distinct from PLV3',\r\n        cta: 'Join the course',\r\n        video: false,\r\n        body: `What's actually been asked this week:\r\n\r\n\"None of my clients are mandated yet \u2014 is this too early for me?\" No \u2014 the combined-income trap means more clients are in scope than most practices realise, and building the process before the pressure hits beats building it under pressure.\r\n\r\n\"What if I fall behind during the six weeks?\" Self-paced within the six weeks \u2014 the structure is a guide, not a hard weekly deadline.\r\n\r\n\"Refund if it's not for me?\" 14-day money-back, no questions.\r\n\r\nDoors close Monday.\r\n\r\n[Join the course \u2192]\r\n\r\nRach X`\r\n      },\r\n      {\r\n        n: 6, date: '2027-03-08', time: '5:00pm',\r\n        segment: 'Full list',\r\n        subject: \"Closes tonight \u2014 MTD IT: The 6-Week Course\",\r\n        preheader: \"Starts tomorrow either way\",\r\n        purpose: 'Final close',\r\n        cta: 'Join before midnight',\r\n        video: false,\r\n        body: `Doors close tonight. The six weeks start tomorrow.\r\n\r\n[Join before midnight \u2192]\r\n\r\nRach X`\r\n      }\r\n    ],\r\n    socials: [\r\n      {\r\n        type: 'Reframe post 1', date: '2027-02-15', platforms: ['Instagram','LinkedIn'],\r\n        angle: \"The clients who look under threshold on paper aren't always under threshold in reality.\",\r\n        ig: \"The clients who look comfortably under the MTD threshold on paper aren't always under threshold in reality.\\n\\nSole trade income plus rental income, combined, pushes plenty of people over without anyone checking.\",\r\n        linkedin: \"One of the most common MTD scoping mistakes isn't a technical error \u2014 it's checking income sources separately instead of combined. A client who looks safely under the threshold on paper can be very much in scope once everything's added together.\"\r\n      },\r\n      {\r\n        type: 'Reframe post 2', date: '2027-02-19', platforms: ['Instagram','LinkedIn'],\r\n        angle: \"Six weeks, paced, beats one panicked week later.\",\r\n        ig: \"Six weeks, paced properly, beats one panicked week when mandation actually lands.\",\r\n        linkedin: \"MTD readiness done properly is a six-week process \u2014 scoping, software, repricing, capacity, edge cases, and a walked-through first submission. Compressed into one panicked week under deadline pressure, it's a much worse experience for you and the client.\"\r\n      },\r\n      {\r\n        type: 'Carousel', date: '2027-02-24', platforms: ['Instagram'],\r\n        title: \"What the MTD IT 6-week course actually covers\",\r\n        slides: [\r\n          \"HOOK: What the MTD IT 6-week course actually covers\",\r\n          \"Week 1: Who's actually in scope (the combined-income trap)\",\r\n          \"Week 2: Software that actually finishes the job\",\r\n          \"Week 3: Repricing before mandation hits\",\r\n          \"Week 4: Capacity planning for the quarterly crunch\",\r\n          \"Week 5: Basis period edge cases\",\r\n          \"Week 6: Your first live quarterly submission, walked through\",\r\n          \"CTA: Starts 9 March \u2014 link in bio.\"\r\n        ]\r\n      },\r\n      {\r\n        type: 'Short-form video 1', date: '2027-02-17', platforms: ['TikTok','YouTube Shorts'],\r\n        hook: \"A client I nearly got wrong on MTD scope.\",\r\n        pivot: \"Sole trade income alone looked fine. Combined with rental income, well over threshold.\",\r\n        consequence: \"That single missed combination is one of the most common reasons clients get brought in late.\",\r\n        close: \"MTD IT 6-week course, early bird open \u2014 link in bio.\"\r\n      },\r\n      {\r\n        type: 'Short-form video 2', date: '2027-03-01', platforms: ['TikTok','YouTube Shorts'],\r\n        hook: \"Quarterly submissions are roughly four times the touchpoints of an annual return.\",\r\n        pivot: \"Same client, same fee, unless you reprice before mandation hits.\",\r\n        consequence: \"Practices that don't renegotiate fees absorb the extra workload at the old annual price.\",\r\n        close: \"Doors close 8 March \u2014 link in bio.\"\r\n      }\r\n    ]\r\n  },\r\n  {\r\n    id: 'digital-downloads-bts',\r\n    name: 'Digital Downloads & BTS (26 products)',\r\n    status: 'placeholder',\r\n    roughTiming: 'Staggered Aug 26 \u2013 Mar 27, once Tamzin\\'s evergreen automation is live and tested (~3 weeks out as of 11 Aug 26). Email Templates (Ltd Co, SA, CIS, VAT basic\/full, MTD), Working Papers (SA, CIS, Sole Trader, Bookkeeping & VAT, Ltd Co), Practice Makes Perfect, Companies House ACSP & ID Verification, R&D Tax Credits, Estate & IHT Planning Awareness, How to Disengage (blocked, mid-build). See the Digital Downloads & BTS tab of the Revenue Recovery Plan for per-product pricing and start weeks.'\r\n  }\r\n];\r\n\r\n<\/script>\r\n<script>\r\nfunction showMainTab(tab){\r\n  document.querySelectorAll('.tabpanel').forEach(p=>p.classList.remove('active'));\r\n  document.querySelectorAll('.tabbtn').forEach(b=>b.classList.remove('active'));\r\n  document.getElementById('tab-'+tab).classList.add('active');\r\n  event.target.classList.add('active');\r\n}\r\n\r\nfunction fmtDate(d){\r\n  if(!d) return '';\r\n  if(d.includes('\/')) {\r\n    \/\/ date range like 2026-11-01\/02\r\n    return d;\r\n  }\r\n  const dt = new Date(d+'T00:00:00');\r\n  if(isNaN(dt)) return d;\r\n  return dt.toLocaleDateString('en-GB', {day:'numeric', month:'short', year:'numeric'});\r\n}\r\n\r\n\/\/ ---- Render summary cards ----\r\nfunction renderSummary(){\r\n  const grid = document.getElementById('launchGrid');\r\n  grid.innerHTML = '';\r\n  launches.forEach(l => {\r\n    const card = document.createElement('div');\r\n    card.className = 'launch-card ' + (l.status==='placeholder' ? 'placeholder' : '');\r\n    let meta = '';\r\n    if(l.status === 'complete'){\r\n      const plvVideoCount = l.prelaunch ? l.prelaunch.filter(p => p.video).length : 0;\r\n      const plvCount = l.prelaunch ? l.prelaunch.length : 0;\r\n      const withVideo = l.emails.filter(e => e.video).length + plvVideoCount;\r\n      const totalPieces = l.emails.length + plvCount;\r\n      const videoLow = totalPieces > 0 && (withVideo \/ totalPieces) < 0.34;\r\n      const videoNote = videoLow\r\n        ? `<span style=\"color:#c0392b;font-weight:700;\">${withVideo}\/${totalPieces} pieces (PLV+emails) have video \u2014 below Rachel's bar, add more<\/span>`\r\n        : `${withVideo}\/${totalPieces} pieces (PLV+emails) have video`;\r\n      const plvNote = l.prelaunch\r\n        ? `<span style=\"color:#3c3489;font-weight:700;\">Prelaunch (PLV) built \u2014 ${l.prelaunch.length} pieces<\/span>`\r\n        : `<span style=\"color:#c0392b;font-weight:700;\">No prelaunch (PLV) sequence yet<\/span>`;\r\n      meta = `<div class=\"card-meta\"><b>${fmtDate(l.cartOpen)}<\/b> \u2013 <b>${fmtDate(l.cartClose)}<\/b><br>${l.emails.length} emails \u00b7 ${l.socials.length} social pieces<br>${l.price}<br>${videoNote}<br>${plvNote}<\/div>`;\r\n    } else {\r\n      meta = `<div class=\"card-meta\">${l.roughTiming || 'Not yet scheduled'}<\/div>`;\r\n    }\r\n    card.innerHTML = `\r\n      <span class=\"status-pill ${l.status}\">${l.status === 'complete' ? 'Full plan built' : 'Placeholder'}<\/span>\r\n      <h3>${l.name}<\/h3>\r\n      ${meta}\r\n    `;\r\n    card.addEventListener('click', () => openDetail(l.id));\r\n    grid.appendChild(card);\r\n  });\r\n}\r\n\r\n\/\/ ---- Detail slide-over ----\r\nfunction openDetail(id){\r\n  const l = launches.find(x => x.id === id);\r\n  const content = document.getElementById('detailContent');\r\n  if(l.status === 'placeholder'){\r\n    content.innerHTML = `\r\n      <h2 class=\"detail-title\">${l.name}<\/h2>\r\n      <div class=\"detail-sub\">${l.roughTiming || 'Not yet scheduled'}<\/div>\r\n      <div class=\"empty-note\">This launch hasn't been built out yet \u2014 no dates, emails, or social plan drafted.\r\n      Tell Claude to build this one next and it'll follow the same structure as Management Accounts.<\/div>\r\n    `;\r\n  } else {\r\n    content.innerHTML = `\r\n      <h2 class=\"detail-title\">${l.name}<\/h2>\r\n      <div class=\"detail-sub\">${fmtDate(l.cartOpen)} \u2013 ${fmtDate(l.cartClose)} &nbsp;\u00b7&nbsp; ${l.price}<\/div>\r\n      <div class=\"detail-sub\" style=\"margin-top:-14px;\"><b>Theme:<\/b> ${l.theme}<br><b>Outcome:<\/b> ${l.outcome}<\/div>\r\n      ${l.earlyBird && !l.earlyBird.notApplicable ? `<div class=\"detail-sub\" style=\"background:#e3f4e9;border:1px solid #a8d9ba;border-radius:8px;padding:10px 12px;color:#1f6b3a;margin-top:8px;\"><b>Early bird:<\/b> ${l.earlyBird.discount} \u2014 ${l.earlyBird.earlyBirdPrice} until ${fmtDate(l.earlyBird.endDate)}, then ${l.earlyBird.standardPrice} (${l.earlyBird.rule})<\/div>` : ''}\r\n      ${l.earlyBird && l.earlyBird.notApplicable ? `<div class=\"detail-sub\" style=\"background:#f0f0f0;border:1px solid #ccc;border-radius:8px;padding:10px 12px;color:#555;margin-top:8px;\"><b>Early bird: not applied here.<\/b> ${l.earlyBird.reason}<\/div>` : ''}\r\n      ${l.dateFlag ? `<div class=\"detail-sub\" style=\"background:#fdedd8;border:1px solid #ef9f27;border-radius:8px;padding:10px 12px;color:#8a5100;margin-top:8px;\">${l.dateFlag}<\/div>` : ''}\r\n      ${l.deviationNote ? `<div class=\"detail-sub\" style=\"background:#fdf2f1;border:1px solid #f0b8b8;border-radius:8px;padding:10px 12px;color:#8a1f1f;margin-top:8px;\"><b>Deviation from standard pattern:<\/b> ${l.deviationNote}<\/div>` : ''}\r\n      <div class=\"detail-tabs\">\r\n        <button class=\"dtab active\" onclick=\"showDetailTab(this,'ddates')\">Dates<\/button>\r\n        <button class=\"dtab\" onclick=\"showDetailTab(this,'dprelaunch')\">Prelaunch \/ PLV ${l.prelaunch ? '('+l.prelaunch.length+')' : ''}<\/button>\r\n        <button class=\"dtab\" onclick=\"showDetailTab(this,'demails')\">Emails (${l.emails.length})<\/button>\r\n        <button class=\"dtab\" onclick=\"showDetailTab(this,'dsocials')\">Socials (${l.socials.length})<\/button>\r\n      <\/div>\r\n      <div id=\"ddates\" class=\"dpanel active\">${renderDetailDates(l)}<\/div>\r\n      <div id=\"dprelaunch\" class=\"dpanel\">${renderPrelaunch(l)}<\/div>\r\n      <div id=\"demails\" class=\"dpanel\">${renderEmails(l.emails)}<\/div>\r\n      <div id=\"dsocials\" class=\"dpanel\">${renderSocials(l.socials)}<\/div>\r\n    `;\r\n  }\r\n  document.getElementById('detailPanel').classList.add('open');\r\n  document.getElementById('detailOverlay').classList.add('open');\r\n}\r\nfunction closeDetail(){\r\n  document.getElementById('detailPanel').classList.remove('open');\r\n  document.getElementById('detailOverlay').classList.remove('open');\r\n}\r\nfunction showDetailTab(btn, id){\r\n  btn.parentElement.querySelectorAll('.dtab').forEach(b=>b.classList.remove('active'));\r\n  btn.classList.add('active');\r\n  btn.closest('#detailContent').querySelectorAll('.dpanel').forEach(p=>p.classList.remove('active'));\r\n  document.getElementById(id).classList.add('active');\r\n}\r\n\r\nfunction renderDetailDates(l){\r\n  let rows = '';\r\n  if(l.prelaunch){\r\n    l.prelaunch.forEach(p => {\r\n      rows += `<div class=\"date-row\" style=\"background:#f9f8ff;\"><span class=\"date-badge\" style=\"color:#3c3489;\">${fmtDate(p.date)}<\/span><span class=\"date-type\" style=\"color:#3c3489;\">${p.stage}<\/span><span class=\"date-desc\">${p.title}<\/span><\/div>`;\r\n    });\r\n  }\r\n  if(l.milestones){\r\n    l.milestones.forEach(m => {\r\n      rows += `<div class=\"date-row\" style=\"background:#fdf6fa;\"><span class=\"date-badge\" style=\"color:var(--black);\">${fmtDate(m.date)}<\/span><span class=\"date-type\" style=\"color:var(--pink);\">Milestone<\/span><span class=\"date-desc\"><b>${m.label}<\/b><\/span><\/div>`;\r\n    });\r\n  }\r\n  l.emails.forEach(e => {\r\n    rows += `<div class=\"date-row\"><span class=\"date-badge\">${fmtDate(e.date)}<\/span><span class=\"date-type\">Email ${e.n}<\/span><span class=\"date-desc\">${e.subject}<\/span><\/div>`;\r\n  });\r\n  l.socials.forEach(s => {\r\n    rows += `<div class=\"date-row\"><span class=\"date-badge\">${fmtDate(s.date)}<\/span><span class=\"date-type\">${s.type}<\/span><span class=\"date-desc\">${s.platforms.join(', ')}<\/span><\/div>`;\r\n  });\r\n  return `<div class=\"date-group\"><div class=\"date-group-head\">Full timeline<\/div>${rows}<\/div>`;\r\n}\r\n\r\nfunction renderPrelaunch(l){\r\n  if(!l.prelaunch){\r\n    return `<div class=\"plv-missing\"><b>No prelaunch (PLV) sequence built for this launch yet.<\/b><br><br>\r\n      Per Jeff Walker's Launch framework, this should be 2-3 pieces of genuinely standalone-valuable content (ideally video) delivered <i>before<\/i> cart open \u2014 no pitch, no CTA to buy. The shape to follow (see Management Accounts for the worked example):<br><br>\r\n      <b>PLV1 \u2014 belief shift:<\/b> collapse one specific wrong belief the reader holds about this topic.<br>\r\n      <b>PLV2 \u2014 proof &amp; technique:<\/b> a real case study or walkthrough they can use even if they never buy.<br>\r\n      <b>PLV3 \u2014 transformation &amp; reveal:<\/b> future-pace the outcome, handle the top 1-2 objections, then reveal cart opens soon.<br><br>\r\n      Tell Claude to build this launch's PLV sequence next using Management Accounts as the template.\r\n    <\/div>`;\r\n  }\r\n  return l.prelaunch.map(p => `\r\n    <div class=\"plv-card\">\r\n      <span class=\"plv-num\">${p.n}<\/span><h4>${p.title}<\/h4><span class=\"plv-label\">${p.stage}<\/span>${p.video ? `<span class=\"video-tag\">Video \u2014 films: ${p.filmedBy || 'TBC'}<\/span>` : ''}\r\n      <div class=\"plv-meta\">\r\n        <b>Date:<\/b> ${fmtDate(p.date)} at ${p.time} &nbsp;|&nbsp; <b>Segment:<\/b> ${p.segment}<br>\r\n        <b>Preheader:<\/b> ${p.preheader}<br>\r\n        <b>Purpose:<\/b> ${p.purpose}<br>\r\n        <b>CTA:<\/b> ${p.cta}\r\n        ${p.videoNote ? `<br><b>Video:<\/b> ${p.videoNote}` : ''}\r\n      <\/div>\r\n      <button class=\"toggle-body\" onclick=\"this.nextElementSibling.classList.toggle('open'); this.textContent = this.nextElementSibling.classList.contains('open') ? 'Hide full copy \u25b2' : 'Show full copy \u25bc'\">Show full copy \u25bc<\/button>\r\n      <div class=\"email-body\">${p.body}<\/div>\r\n    <\/div>\r\n  `).join('');\r\n}\r\n\r\nfunction renderEmails(emails){\r\n  return emails.map(e => `\r\n    <div class=\"email-card\">\r\n      <span class=\"email-num\">${e.n}<\/span><h4>${e.subject}<\/h4>${e.video ? `<span class=\"video-tag\">Video \u2014 films: ${e.filmedBy || 'TBC'}<\/span>` : ''}\r\n      <div class=\"email-meta\">\r\n        <b>Date:<\/b> ${fmtDate(e.date)} at ${e.time} &nbsp;|&nbsp; <b>Segment:<\/b> ${e.segment}<br>\r\n        <b>Preheader:<\/b> ${e.preheader}<br>\r\n        <b>Purpose:<\/b> ${e.purpose}<br>\r\n        <b>CTA:<\/b> ${e.cta}\r\n        ${e.resendSubject ? `<br><b>Resend subject:<\/b> ${e.resendSubject}` : ''}\r\n        ${e.videoNote ? `<br><b>Video:<\/b> ${e.videoNote}` : ''}\r\n      <\/div>\r\n      <button class=\"toggle-body\" onclick=\"this.nextElementSibling.classList.toggle('open'); this.textContent = this.nextElementSibling.classList.contains('open') ? 'Hide full copy \u25b2' : 'Show full copy \u25bc'\">Show full copy \u25bc<\/button>\r\n      <div class=\"email-body\">${e.body}<\/div>\r\n    <\/div>\r\n  `).join('');\r\n}\r\n\r\nfunction renderSocials(socials){\r\n  return socials.map(s => {\r\n    let body = '';\r\n    if(s.slides){\r\n      body = `<div class=\"slide-list\">${s.slides.map((sl,i)=>`<li>${sl}<\/li>`).join('')}<\/div>`;\r\n    } else if(s.ig || s.linkedin){\r\n      body = `<div class=\"social-body\"><b>Instagram:<\/b>\\n${s.ig}\\n\\n<b>LinkedIn:<\/b>\\n${s.linkedin}<\/div>`;\r\n    } else if(s.hook){\r\n      body = `<div class=\"social-body\"><b>Hook:<\/b> ${s.hook}\\n<b>Pivot:<\/b> ${s.pivot}\\n<b>Consequence:<\/b> ${s.consequence}\\n<b>Close:<\/b> ${s.close}<\/div>`;\r\n    }\r\n    return `\r\n      <div class=\"social-card\">\r\n        <h4>${s.type}${s.title ? ' \u2014 ' + s.title : ''}<\/h4>\r\n        <div class=\"platform-tags\">${s.platforms.map(p=>`<span class=\"ptag\">${p}<\/span>`).join('')} <span style=\"font-size:11.5px;color:var(--ink-soft);\">${fmtDate(s.date)}<\/span><\/div>\r\n        ${s.angle ? `<div style=\"font-size:12.5px;color:var(--ink-soft);margin-bottom:6px;\"><i>${s.angle}<\/i><\/div>` : ''}\r\n        ${body}\r\n      <\/div>\r\n    `;\r\n  }).join('');\r\n}\r\n\r\n\/\/ ---- All Dates tab ----\r\nfunction renderAllDates(){\r\n  const el = document.getElementById('datesContent');\r\n  const complete = launches.filter(l => l.status === 'complete');\r\n  if(!complete.length){ el.innerHTML = '<div class=\"empty-note\">No launches built yet.<\/div>'; return; }\r\n  let html = '';\r\n  complete.forEach(l => {\r\n    let rows = '';\r\n    const items = [];\r\n    if(l.prelaunch){\r\n      l.prelaunch.forEach(p => items.push({date:p.date, type:p.stage, desc:p.title, prelaunch:true}));\r\n    }\r\n    if(l.milestones){\r\n      l.milestones.forEach(m => items.push({date:m.date, type:'Milestone', desc:`<b>${m.label}<\/b>`, milestone:true}));\r\n    }\r\n    l.emails.forEach(e => items.push({date:e.date, type:'Email '+e.n, desc:e.subject}));\r\n    l.socials.forEach(s => items.push({date:s.date, type:s.type, desc:s.platforms.join(', ') + (s.title ? ' \u2014 '+s.title : '')}));\r\n    items.sort((a,b) => a.date.localeCompare(b.date));\r\n    items.forEach(it => {\r\n      const bg = it.milestone ? 'style=\"background:#fdf6fa;\"' : (it.prelaunch ? 'style=\"background:#f9f8ff;\"' : '');\r\n      const typeColor = it.milestone ? 'style=\"color:var(--pink);\"' : (it.prelaunch ? 'style=\"color:#3c3489;\"' : '');\r\n      const badgeColor = it.milestone ? 'style=\"color:var(--black);\"' : (it.prelaunch ? 'style=\"color:#3c3489;\"' : '');\r\n      rows += `<div class=\"date-row\" ${bg}><span class=\"date-badge\" ${badgeColor}>${fmtDate(it.date)}<\/span><span class=\"date-type\" ${typeColor}>${it.type}<\/span><span class=\"date-launch\">${l.name}<\/span><span class=\"date-desc\">${it.desc}<\/span><\/div>`;\r\n    });\r\n    html += `<div class=\"date-group\"><div class=\"date-group-head\">${l.name}<\/div>${rows}<\/div>`;\r\n  });\r\n  el.innerHTML = html;\r\n}\r\n\r\n\/\/ ---- All Socials tab ----\r\nfunction renderAllSocials(){\r\n  const el = document.getElementById('socialsContent');\r\n  const complete = launches.filter(l => l.status === 'complete');\r\n  if(!complete.length){ el.innerHTML = '<div class=\"empty-note\">No launches built yet.<\/div>'; return; }\r\n  let html = '';\r\n  complete.forEach(l => {\r\n    html += `<h3 style=\"font-family:'Lora',Georgia,serif;font-size:15px;margin:20px 0 10px;\">${l.name}<\/h3>`;\r\n    html += renderSocials(l.socials);\r\n  });\r\n  el.innerHTML = html;\r\n}\r\n\r\n\/\/ ---- All Emails tab ----\r\nfunction renderAllEmails(){\r\n  const el = document.getElementById('emailsContent');\r\n  const complete = launches.filter(l => l.status === 'complete');\r\n  if(!complete.length){ el.innerHTML = '<div class=\"empty-note\">No launches built yet.<\/div>'; return; }\r\n  let html = '';\r\n  complete.forEach(l => {\r\n    html += `<h3 style=\"font-family:'Lora',Georgia,serif;font-size:15px;margin:20px 0 10px;\">${l.name}<\/h3>`;\r\n    html += renderEmails(l.emails);\r\n  });\r\n  el.innerHTML = html;\r\n}\r\n\r\n\/\/ ---- Full Timeline tab: everything interleaved by true date order ----\r\nconst launchColors = ['#F6267F','#a3105a','#1f8a4c','#c77d0a','#3c3489','#993c1d','#0f6e56','#8a5100','#6b5b63'];\r\nfunction launchColorFor(idx){\r\n  const c = launchColors[idx % launchColors.length];\r\n  return c;\r\n}\r\nfunction firstDate(d){\r\n  \/\/ handle date ranges like '2026-11-01\/02' -> use the first date for sorting\r\n  if(d.includes('\/')){\r\n    const parts = d.split('\/');\r\n    return parts[0];\r\n  }\r\n  return d;\r\n}\r\nfunction renderFullTimeline(){\r\n  const el = document.getElementById('timelineContent');\r\n  const complete = launches.filter(l => l.status === 'complete');\r\n  if(!complete.length){ el.innerHTML = '<div class=\"empty-note\">No launches built yet.<\/div>'; return; }\r\n\r\n  const items = [];\r\n  complete.forEach((l, idx) => {\r\n    const color = launchColorFor(idx);\r\n    if(l.prelaunch){\r\n      l.prelaunch.forEach(p => items.push({\r\n        sortDate: firstDate(p.date), displayDate: p.date, type: p.stage, desc: p.title,\r\n        launchName: l.name, color, prelaunch: true\r\n      }));\r\n    }\r\n    if(l.milestones){\r\n      l.milestones.forEach(m => items.push({\r\n        sortDate: firstDate(m.date), displayDate: m.date, type: 'Milestone', desc: '<b>'+m.label+'<\/b>',\r\n        launchName: l.name, color, milestone: true\r\n      }));\r\n    }\r\n    l.emails.forEach(e => items.push({\r\n      sortDate: firstDate(e.date), displayDate: e.date, type: 'Email '+e.n, desc: e.subject,\r\n      launchName: l.name, color\r\n    }));\r\n    l.socials.forEach(s => items.push({\r\n      sortDate: firstDate(s.date), displayDate: s.date, type: s.type, desc: s.platforms.join(', ') + (s.title ? ' \u2014 '+s.title : ''),\r\n      launchName: l.name, color\r\n    }));\r\n  });\r\n  items.sort((a,b) => a.sortDate.localeCompare(b.sortDate));\r\n\r\n  let html = '';\r\n  let currentMonth = '';\r\n  items.forEach(it => {\r\n    const dt = new Date(it.sortDate+'T00:00:00');\r\n    const monthLabel = isNaN(dt) ? 'Unscheduled' : dt.toLocaleDateString('en-GB', {month:'long', year:'numeric'});\r\n    if(monthLabel !== currentMonth){\r\n      html += `<div class=\"month-divider\">${monthLabel}<\/div>`;\r\n      currentMonth = monthLabel;\r\n    }\r\n    const rowStyle = it.milestone ? 'style=\"background:#fdf6fa;border-left:3px solid var(--pink);\"' : (it.prelaunch ? 'style=\"background:#f9f8ff;border-left:3px solid #3c3489;\"' : '');\r\n    const dateStyle = it.milestone ? 'style=\"color:var(--black);\"' : (it.prelaunch ? 'style=\"color:#3c3489;\"' : '');\r\n    const typeStyle = it.milestone ? 'style=\"color:var(--pink);\"' : (it.prelaunch ? 'style=\"color:#3c3489;\"' : '');\r\n    html += `<div class=\"timeline-row\" ${rowStyle}>\r\n      <span class=\"tl-date\" ${dateStyle}>${fmtDate(it.displayDate)}<\/span>\r\n      <span class=\"tl-launch-tag\" style=\"background:${it.color}22;color:${it.color};\">${it.launchName}<\/span>\r\n      <span class=\"tl-type\" ${typeStyle}>${it.type}<\/span>\r\n      <span class=\"tl-desc\">${it.desc}<\/span>\r\n    <\/div>`;\r\n  });\r\n  el.innerHTML = html;\r\n}\r\n\r\n\/\/ ---- Testing & Retro tab: diary slot per launch, compared against every prior launch ----\r\nfunction addDays(dateStr, days){\r\n  const d = new Date(dateStr+'T00:00:00');\r\n  if(isNaN(d)) return null;\r\n  d.setDate(d.getDate() + days);\r\n  return d.toISOString().slice(0,10);\r\n}\r\nfunction renderRetro(){\r\n  const el = document.getElementById('retroContent');\r\n  const complete = launches.filter(l => l.status === 'complete' && l.cartOpen);\r\n  if(!complete.length){ el.innerHTML = '<div class=\"empty-note\">No launches built yet.<\/div>'; return; }\r\n  \/\/ sort chronologically by cart open so each launch can be compared against everything before it\r\n  const sorted = [...complete].sort((a,b) => firstDate(a.cartOpen).localeCompare(firstDate(b.cartOpen)));\r\n  let html = '';\r\n  sorted.forEach((l, idx) => {\r\n    const priorLaunches = sorted.slice(0, idx).map(p => p.name);\r\n    const closeIsRealDate = l.cartClose && \/^\\d{4}-\\d{2}-\\d{2}\/.test(l.cartClose);\r\n    const anchor = closeIsRealDate ? firstDate(l.cartClose) : firstDate(l.cartOpen);\r\n    const anchorLabel = closeIsRealDate ? 'cart close' : 'launch start (evergreen \u2014 no cart close)';\r\n    const reviewDate = addDays(anchor, 7);\r\n    html += `\r\n      <div class=\"date-group\">\r\n        <div class=\"date-group-head\">${l.name}<\/div>\r\n        <div class=\"date-row\">\r\n          <span class=\"date-badge\">${reviewDate ? fmtDate(reviewDate) : 'TBC'}<\/span>\r\n          <span class=\"date-type\">Diary slot<\/span>\r\n          <span class=\"date-launch\">~7 days after ${anchorLabel}<\/span>\r\n          <span class=\"date-desc\">\r\n            Book a 30\u201345 min review. Pull: Flodesk open\/click rates for this sequence, Teachable conversion vs. the Mid scenario for this lever in the Revenue Recovery Plan, and video engagement (views\/completion on the video email(s)).<br>\r\n            <b>Compare against:<\/b> ${priorLaunches.length ? priorLaunches.join(', ') : 'no prior launch yet \u2014 this is the baseline, first launch under the current format.'}\r\n          <\/span>\r\n        <\/div>\r\n      <\/div>\r\n    `;\r\n  });\r\n  el.innerHTML = html;\r\n}\r\n\r\n\/\/ ---- Video Scripts tab: every video needed across every launch ----\r\nfunction extractLength(note){\r\n  if(!note) return '';\r\n  const m = note.match(\/(\\d+(-\\d+)?\\s*(sec|min))\/i);\r\n  return m ? m[1] : '';\r\n}\r\nfunction renderVideoScripts(){\r\n  const el = document.getElementById('videoScriptsContent');\r\n  const complete = launches.filter(l => l.status === 'complete');\r\n  const rows = [];\r\n  complete.forEach(l => {\r\n    if(l.prelaunch){\r\n      l.prelaunch.forEach(p => {\r\n        if(p.video) rows.push({launch: l.name, stage: p.stage, title: p.title, filmedBy: p.filmedBy || 'TBC', length: extractLength(p.videoNote), date: p.date});\r\n      });\r\n    }\r\n    l.emails.forEach(e => {\r\n      if(e.video) rows.push({launch: l.name, stage: 'Email '+e.n, title: e.subject, filmedBy: e.filmedBy || 'TBC', length: extractLength(e.videoNote), date: e.date});\r\n    });\r\n  });\r\n  rows.sort((a,b) => firstDate(a.date).localeCompare(firstDate(b.date)));\r\n  if(!rows.length){ el.innerHTML = '<div class=\"empty-note\">No videos flagged yet.<\/div>'; return; }\r\n  const header = `<div class=\"vs-row\" style=\"background:#faf8f5;font-weight:700;font-size:11px;text-transform:uppercase;letter-spacing:.02em;color:var(--ink-soft);\">\r\n    <span class=\"vs-launch\">Launch<\/span><span class=\"vs-stage\">Stage<\/span><span class=\"vs-title\">Video<\/span><span class=\"vs-filmedby\">Films<\/span><span class=\"vs-length\">Length<\/span><span class=\"vs-status\">Script<\/span>\r\n  <\/div>`;\r\n  const body = rows.map(r => `\r\n    <div class=\"vs-row\">\r\n      <span class=\"vs-launch\">${r.launch}<\/span>\r\n      <span class=\"vs-stage\">${r.stage}<\/span>\r\n      <span class=\"vs-title\">${r.title}<\/span>\r\n      <span class=\"vs-filmedby\">${r.filmedBy}<\/span>\r\n      <span class=\"vs-length\">${r.length}<\/span>\r\n      <span class=\"vs-status\">Not written<\/span>\r\n    <\/div>\r\n  `).join('');\r\n  el.innerHTML = `<div class=\"date-group\">${header}${body}<\/div>\r\n    <p style=\"font-size:12px;color:var(--ink-soft);margin-top:14px;\">${rows.length} videos flagged across ${complete.length} launches. All currently need scripts written.<\/p>`;\r\n}\r\n\r\nrenderSummary();\r\nrenderFullTimeline();\r\nrenderAllDates();\r\nrenderAllSocials();\r\nrenderAllEmails();\r\nrenderRetro();\r\nrenderVideoScripts();\r\n<\/script>\r\n<\/body>\r\n<\/html>\r\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>\ud83d\udea6 Sales Funnel Priority Tracker Enter your personal passcode to continue. Enter \u2303 Collapse Sign out @accountant_she \ud83d\udea6 Sales Funnel Priority Tracker Every idea for improving the funnel, scored 1\u201310 by impact and urgency, with a diary plan and a Monday morning review. \ud83d\udccb Task List \u2615 Monday Review + Add a task \ud83d\udce4 Diary [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_canvas","meta":{"_acf_changed":false,"_eb_attr":"","_templately_pack_id":"","_templately_imported_at":"","_templately_source":"","_templately_import_session_id":"","footnotes":""},"class_list":["post-3235","page","type-page","status-publish","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.bare-digital.com\/ashe\/wp-json\/wp\/v2\/pages\/3235","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.bare-digital.com\/ashe\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.bare-digital.com\/ashe\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.bare-digital.com\/ashe\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.bare-digital.com\/ashe\/wp-json\/wp\/v2\/comments?post=3235"}],"version-history":[{"count":25,"href":"https:\/\/www.bare-digital.com\/ashe\/wp-json\/wp\/v2\/pages\/3235\/revisions"}],"predecessor-version":[{"id":3262,"href":"https:\/\/www.bare-digital.com\/ashe\/wp-json\/wp\/v2\/pages\/3235\/revisions\/3262"}],"wp:attachment":[{"href":"https:\/\/www.bare-digital.com\/ashe\/wp-json\/wp\/v2\/media?parent=3235"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}