{"id":1343,"date":"2026-06-24T17:24:16","date_gmt":"2026-06-24T21:24:16","guid":{"rendered":"https:\/\/rismethod.com\/?page_id=1343"},"modified":"2026-07-17T09:01:34","modified_gmt":"2026-07-17T13:01:34","slug":"leadership-friction-suite","status":"publish","type":"page","link":"https:\/\/rismethod.com\/fr\/leadership-friction-suite\/","title":{"rendered":"Leadership Friction Autopsy"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"1343\" class=\"elementor elementor-1343\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-c58048b e-flex e-con-boxed e-con e-parent\" data-id=\"c58048b\" 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-6b0ccbb elementor-widget elementor-widget-html\" data-id=\"6b0ccbb\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <title>RIS METHOD\u2122 \u00b7 Leadership Friction Autopsy\u2122<\/title>\n  <link href=\"https:\/\/fonts.googleapis.com\/css2?family=Playfair+Display:wght@600;700&family=Inter:wght@400;500;600&display=swap\" rel=\"stylesheet\">\n  <script src=\"https:\/\/cdn.jsdelivr.net\/npm\/@emailjs\/browser@4\/dist\/email.min.js\"><\/script>\n\n  <style>\n    * { margin: 0; padding: 0; box-sizing: border-box; }\n\n    :root {\n      --bg-primary: #0d1117;\n      --bg-secondary: #131920;\n      --bg-card: #1a2332;\n      --accent-gold: #C9A84C;\n      --accent-gold-light: #e8c96a;\n      --text-primary: #f0ede8;\n      --text-muted: #9aa3b0;\n      --border-light: rgba(201, 168, 76, 0.2);\n      --border-strong: rgba(201, 168, 76, 0.5);\n    }\n\n    body {\n      font-family: 'Inter', sans-serif;\n      background-color: var(--bg-primary);\n      color: var(--text-primary);\n      line-height: 1.6;\n      overflow-x: hidden;\n    }\n\n    h1, h2, h3, h4 { font-family: 'Playfair Display', serif; }\n\n    strong { color: var(--accent-gold-light); font-weight: 600; }\n\n    .container { max-width: 1200px; margin: 0 auto; padding: 0 20px; }\n\n    \/* ===== LANDING SCREEN ===== *\/\n    #landingScreen {\n      min-height: 100vh;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      padding: 40px 20px;\n      animation: fadeInUp 0.6s ease-out;\n    }\n\n    .landing-content {\n      max-width: 700px;\n      text-align: center;\n    }\n\n    .landing-logo {\n      width: 100px;\n      height: 100px;\n      margin: 0 auto 24px;\n      border-radius: 12px;\n      \n      padding: 16px;\n    }\n\n    .landing-logo img {\n      width: 100%;\n      height: 100%;\n      object-fit: contain;\n    }\n\n    .landing-badge {\n      display: inline-block;\n      padding: 8px 16px;\n      background: var(--bg-card);\n      border: 1px solid var(--border-light);\n      border-radius: 50px;\n      font-size: 12px;\n      letter-spacing: 1px;\n      text-transform: uppercase;\n      color: var(--accent-gold);\n      margin-bottom: 24px;\n    }\n\n    .landing-title {\n      font-size: clamp(32px, 6vw, 52px);\n      font-weight: 700;\n      margin-bottom: 16px;\n      line-height: 1.2;\n    }\n\n    .landing-subtitle {\n      font-size: 18px;\n      color: var(--text-muted);\n      margin-bottom: 32px;\n      line-height: 1.6;\n    }\n\n    .landing-meta {\n      display: flex;\n      gap: 24px;\n      justify-content: center;\n      flex-wrap: wrap;\n      margin-bottom: 40px;\n      font-size: 14px;\n    }\n\n    .landing-meta-item {\n      display: flex;\n      align-items: center;\n      gap: 8px;\n    }\n\n    .landing-meta-item::before {\n      content: '';\n      width: 6px;\n      height: 6px;\n      background: var(--accent-gold);\n      border-radius: 50%;\n    }\n\n    .quote-card {\n      background: var(--bg-card);\n      border: 1px solid var(--border-light);\n      border-radius: 20px;\n      padding: 32px;\n      margin-bottom: 40px;\n      font-style: italic;\n      font-size: 16px;\n      color: var(--text-muted);\n      line-height: 1.8;\n    }\n\n    .quote-card::before {\n      content: '\"';\n      font-size: 48px;\n      color: var(--accent-gold);\n      display: block;\n      margin-bottom: 16px;\n      line-height: 0.5;\n    }\n\n    .quote-attribution {\n      font-style: normal;\n      color: var(--accent-gold);\n      margin-top: 16px;\n      font-size: 14px;\n      font-weight: 500;\n    }\n\n    .landing-cta {\n      margin-top: 8px;\n      font-size: 16px;\n      padding: 16px 36px;\n      cursor: pointer;\n    }\n\n    \/* ===== MAIN LAYOUT ===== *\/\n    #app { display: none; }\n    #app.active { display: flex; flex-direction: column; min-height: 100vh; }\n\n    .tab-bar {\n      background: var(--bg-secondary);\n      border-bottom: 1px solid var(--border-light);\n      display: flex;\n      gap: 0;\n      padding: 0 20px;\n    }\n\n    .tab-btn {\n      flex: 1;\n      padding: 16px 20px;\n      background: none;\n      border: none;\n      color: var(--text-muted);\n      font-size: 14px;\n      font-weight: 500;\n      cursor: pointer;\n      border-bottom: 2px solid transparent;\n      transition: all 0.25s ease;\n      text-transform: uppercase;\n      letter-spacing: 0.5px;\n    }\n\n    .tab-btn.active {\n      color: var(--accent-gold);\n      border-bottom-color: var(--accent-gold);\n    }\n\n    .tab-btn:hover:not(.active) {\n      color: var(--text-primary);\n    }\n\n    .screens-container {\n      flex: 1;\n      padding: 40px 20px;\n      overflow-y: auto;\n    }\n\n    .screen {\n      display: none;\n      animation: fadeInUp 0.4s ease-out;\n    }\n\n    .screen.active { display: block; }\n\n    \/* ===== FORMS ===== *\/\n    .form-group {\n      margin-bottom: 20px;\n    }\n\n    label {\n      display: block;\n      font-size: 14px;\n      font-weight: 500;\n      margin-bottom: 8px;\n      color: var(--text-primary);\n    }\n\n    .form-required::after {\n      content: ' *';\n      color: var(--accent-gold-light);\n    }\n\n    input[type=\"text\"],\n    input[type=\"email\"],\n    input[type=\"number\"],\n    input[type=\"date\"],\n    input[type=\"password\"],\n    select {\n      width: 100%;\n      padding: 12px 16px;\n      background: var(--bg-card);\n      border: 1px solid var(--border-light);\n      border-radius: 12px;\n      color: var(--text-primary);\n      font-family: 'Inter', sans-serif;\n      font-size: 14px;\n      transition: all 0.25s ease;\n    }\n\n    input[type=\"text\"]:focus,\n    input[type=\"email\"]:focus,\n    input[type=\"number\"]:focus,\n    input[type=\"date\"]:focus,\n    input[type=\"password\"]:focus,\n    select:focus {\n      outline: none;\n      border-color: var(--accent-gold);\n      box-shadow: 0 0 0 3px rgba(201, 168, 76, 0.1);\n    }\n\n    input::placeholder {\n      color: var(--text-muted);\n    }\n\n    \/* ===== BUTTONS ===== *\/\n    .btn {\n      padding: 12px 24px;\n      border: none;\n      border-radius: 12px;\n      font-family: 'Inter', sans-serif;\n      font-size: 14px;\n      font-weight: 600;\n      cursor: pointer;\n      transition: all 0.25s ease;\n      text-transform: uppercase;\n      letter-spacing: 0.5px;\n    }\n\n    .btn-primary {\n      background: linear-gradient(135deg, var(--accent-gold), var(--accent-gold-light));\n      color: var(--bg-primary);\n    }\n\n    .btn-primary:hover {\n      box-shadow: 0 8px 24px rgba(201, 168, 76, 0.3);\n      transform: translateY(-2px);\n    }\n\n    .btn-secondary {\n      background: var(--bg-card);\n      color: var(--accent-gold);\n      border: 1px solid var(--border-strong);\n    }\n\n    .btn-secondary:hover {\n      background: var(--bg-primary);\n      border-color: var(--accent-gold);\n    }\n\n    .btn:disabled {\n      opacity: 0.5;\n      cursor: not-allowed;\n    }\n\n    .btn-circle {\n      width: 56px;\n      height: 56px;\n      padding: 0;\n      border-radius: 50%;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      font-size: 18px;\n      font-weight: 600;\n    }\n\n    @media (max-width: 640px) {\n      .btn-circle { width: 48px; height: 48px; font-size: 16px; }\n    }\n\n    @media (max-width: 400px) {\n      .btn-circle { width: 44px; height: 44px; font-size: 14px; }\n    }\n\n    \/* ===== SURVEY FLOW ===== *\/\n    .progress-bar-container {\n      background: var(--bg-secondary);\n      border-bottom: 1px solid var(--border-light);\n      padding: 20px;\n    }\n\n    .progress-label {\n      font-size: 12px;\n      text-transform: uppercase;\n      letter-spacing: 1px;\n      color: var(--accent-gold);\n      margin-bottom: 12px;\n      font-weight: 600;\n    }\n\n    .progress-bar {\n      width: 100%;\n      height: 6px;\n      background: var(--bg-card);\n      border-radius: 3px;\n      overflow: hidden;\n    }\n\n    .progress-fill {\n      height: 100%;\n      background: linear-gradient(90deg, var(--accent-gold), var(--accent-gold-light));\n      border-radius: 3px;\n      transition: width 0.4s ease;\n    }\n\n    .question-card {\n      max-width: 700px;\n      margin: 0 auto;\n      background: var(--bg-card);\n      border: 1px solid var(--border-light);\n      border-radius: 20px;\n      padding: 40px;\n      animation: slideInRight 0.4s ease-out;\n    }\n\n    .zone-pill {\n      display: inline-block;\n      padding: 6px 12px;\n      border-radius: 50px;\n      font-size: 11px;\n      font-weight: 600;\n      text-transform: uppercase;\n      letter-spacing: 0.5px;\n      margin-bottom: 16px;\n    }\n\n    .zone-pill.cf { background: rgba(201, 168, 76, 0.15); color: var(--accent-gold); }\n    .zone-pill.drag { background: rgba(220, 74, 57, 0.15); color: #dc4a39; }\n\n    .question-counter {\n      font-size: 12px;\n      color: var(--text-muted);\n      text-transform: uppercase;\n      letter-spacing: 0.5px;\n      margin-bottom: 12px;\n    }\n\n    .question-text {\n      font-size: 20px;\n      font-family: 'Playfair Display', serif;\n      font-weight: 600;\n      margin-bottom: 32px;\n      line-height: 1.4;\n    }\n\n    .answer-grid {\n      margin-bottom: 40px;\n    }\n\n    \/* Scale buttons *\/\n    .scale-buttons {\n      display: flex;\n      justify-content: space-between;\n      gap: 12px;\n      margin-bottom: 20px;\n    }\n\n    .scale-label {\n      font-size: 12px;\n      color: var(--text-muted);\n      text-align: center;\n      margin-top: 8px;\n    }\n\n    .scale-label.left { text-align: left; }\n    .scale-label.center { text-align: center; }\n    .scale-label.right { text-align: right; }\n\n    \/* Option buttons *\/\n    .option-buttons {\n      display: flex;\n      flex-direction: column;\n      gap: 12px;\n    }\n\n    .option-btn {\n      display: flex;\n      align-items: center;\n      gap: 16px;\n      padding: 16px 20px;\n      background: var(--bg-primary);\n      border: 1px solid var(--border-light);\n      border-radius: 12px;\n      cursor: pointer;\n      transition: all 0.25s ease;\n      color: var(--text-primary);\n      font-size: 15px;\n      text-align: left;\n    }\n\n    .option-btn:hover {\n      border-color: var(--accent-gold);\n      background: rgba(201, 168, 76, 0.05);\n      transform: translateX(8px);\n    }\n\n    .option-btn.selected {\n      background: rgba(201, 168, 76, 0.1);\n      border-color: var(--accent-gold);\n    }\n\n    .option-radio {\n      width: 20px;\n      height: 20px;\n      border: 2px solid var(--border-light);\n      border-radius: 50%;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      flex-shrink: 0;\n      transition: all 0.25s ease;\n    }\n\n    .option-btn.selected .option-radio {\n      border-color: var(--accent-gold);\n      background: var(--accent-gold);\n    }\n\n    .option-radio::after {\n      content: '';\n      width: 8px;\n      height: 8px;\n      background: var(--bg-primary);\n      border-radius: 50%;\n      opacity: 0;\n      transition: opacity 0.25s ease;\n    }\n\n    .option-btn.selected .option-radio::after {\n      opacity: 1;\n    }\n\n    .nav-buttons {\n      display: flex;\n      gap: 16px;\n      margin-top: 40px;\n      justify-content: space-between;\n    }\n\n    \/* ===== RESULTS SCREEN ===== *\/\n    .results-header {\n      max-width: 700px;\n      margin: 0 auto 40px;\n      text-align: center;\n    }\n\n    .results-title {\n      font-size: clamp(24px, 5vw, 36px);\n      margin-bottom: 8px;\n    }\n\n    .results-subtitle {\n      color: var(--text-muted);\n      font-size: 16px;\n      margin-bottom: 12px;\n    }\n\n    .results-meta {\n      display: flex;\n      gap: 16px;\n      justify-content: center;\n      flex-wrap: wrap;\n      font-size: 13px;\n      color: var(--text-muted);\n    }\n\n    .results-section {\n      max-width: 700px;\n      margin: 0 auto 40px;\n    }\n\n    .score-card {\n      background: var(--bg-card);\n      border: 1px solid var(--border-light);\n      border-radius: 20px;\n      padding: 32px;\n      text-align: center;\n      margin-bottom: 24px;\n    }\n\n    .score-visualization {\n      width: 150px;\n      height: 150px;\n      margin: 0 auto 24px;\n    }\n\n    .score-visualization svg {\n      width: 100%;\n      height: 100%;\n    }\n\n    .score-level-badge {\n      display: inline-block;\n      padding: 8px 16px;\n      border-radius: 50px;\n      font-size: 12px;\n      font-weight: 600;\n      text-transform: uppercase;\n      letter-spacing: 0.5px;\n      margin-bottom: 16px;\n    }\n\n    .level-green { background: rgba(76, 175, 80, 0.15); color: #4caf50; }\n    .level-gold { background: rgba(201, 168, 76, 0.15); color: var(--accent-gold); }\n    .level-orange { background: rgba(255, 152, 0, 0.15); color: #ff9800; }\n    .level-red { background: rgba(220, 74, 57, 0.15); color: #dc4a39; }\n\n    .score-summary {\n      font-size: 16px;\n      line-height: 1.6;\n      color: var(--text-muted);\n    }\n\n    .zone-breakdown {\n      display: grid;\n      grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));\n      gap: 16px;\n    }\n\n    .zone-card {\n      background: var(--bg-primary);\n      border: 1px solid var(--border-light);\n      border-radius: 12px;\n      padding: 20px;\n    }\n\n    .zone-name {\n      font-family: 'Playfair Display', serif;\n      font-weight: 600;\n      margin-bottom: 12px;\n      font-size: 16px;\n    }\n\n    .zone-score {\n      display: flex;\n      justify-content: space-between;\n      align-items: center;\n      margin-bottom: 12px;\n      font-size: 14px;\n      color: var(--text-muted);\n    }\n\n    .zone-bar {\n      width: 100%;\n      height: 8px;\n      background: var(--bg-card);\n      border-radius: 4px;\n      overflow: hidden;\n    }\n\n    .zone-bar-fill {\n      height: 100%;\n      background: linear-gradient(90deg, var(--accent-gold), var(--accent-gold-light));\n      border-radius: 4px;\n      transition: width 0.6s ease 0.2s;\n      width: 0;\n    }\n\n    .combined-read {\n      background: var(--bg-card);\n      border: 1px solid var(--border-light);\n      border-radius: 20px;\n      padding: 32px;\n      margin-top: 40px;\n      font-size: 16px;\n      line-height: 1.8;\n      color: var(--text-muted);\n    }\n\n    .combined-read-title {\n      font-family: 'Playfair Display', serif;\n      font-weight: 600;\n      color: var(--text-primary);\n      margin-bottom: 16px;\n      font-size: 18px;\n    }\n\n    .email-confirmation {\n      text-align: center;\n      font-size: 14px;\n      margin-bottom: 32px;\n    }\n\n    \/* ===== ADMIN ===== *\/\n    .admin-login-container {\n      min-height: 100vh;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      padding: 20px;\n    }\n\n    .admin-login-card {\n      background: var(--bg-card);\n      border: 1px solid var(--border-light);\n      border-radius: 20px;\n      padding: 40px;\n      max-width: 400px;\n      width: 100%;\n      text-align: center;\n    }\n\n    .admin-login-logo {\n      width: 60px;\n      height: 60px;\n      margin: 0 auto 24px;\n      background: linear-gradient(135deg, var(--accent-gold), var(--accent-gold-light));\n      border-radius: 12px;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n    }\n\n    .admin-login-title {\n      font-size: 28px;\n      margin-bottom: 8px;\n    }\n\n    .admin-login-subtitle {\n      color: var(--text-muted);\n      margin-bottom: 32px;\n      font-size: 14px;\n    }\n\n    .admin-error {\n      background: rgba(220, 74, 57, 0.1);\n      border: 1px solid rgba(220, 74, 57, 0.3);\n      color: #ff6b6b;\n      padding: 12px 16px;\n      border-radius: 8px;\n      font-size: 14px;\n      margin-bottom: 20px;\n      display: none;\n    }\n\n    .admin-error.show { display: block; }\n\n    .admin-forgot {\n      text-align: center;\n      margin-top: 20px;\n      font-size: 12px;\n      color: var(--text-muted);\n    }\n\n    .admin-forgot a {\n      color: var(--accent-gold);\n      text-decoration: none;\n    }\n\n    .admin-dashboard {\n      max-width: 1400px;\n      margin: 0 auto;\n    }\n\n    .admin-header {\n      display: flex;\n      justify-content: space-between;\n      align-items: center;\n      margin-bottom: 40px;\n      flex-wrap: wrap;\n      gap: 20px;\n    }\n\n    .admin-header h1 {\n      font-size: 32px;\n    }\n\n    .admin-header-actions {\n      display: flex;\n      gap: 12px;\n    }\n\n    .stats-grid {\n      display: grid;\n      grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n      gap: 20px;\n      margin-bottom: 40px;\n    }\n\n    .stat-card {\n      background: var(--bg-card);\n      border: 1px solid var(--border-light);\n      border-radius: 12px;\n      padding: 24px;\n    }\n\n    .stat-label {\n      font-size: 12px;\n      text-transform: uppercase;\n      letter-spacing: 1px;\n      color: var(--text-muted);\n      margin-bottom: 12px;\n    }\n\n    .stat-value {\n      font-size: 36px;\n      font-weight: 600;\n      color: var(--accent-gold);\n    }\n\n    .admin-section {\n      background: var(--bg-card);\n      border: 1px solid var(--border-light);\n      border-radius: 20px;\n      padding: 32px;\n      margin-bottom: 32px;\n    }\n\n    .admin-section-title {\n      font-size: 20px;\n      margin-bottom: 24px;\n      font-family: 'Playfair Display', serif;\n    }\n\n    .session-form {\n      display: grid;\n      grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n      gap: 20px;\n      margin-bottom: 20px;\n    }\n\n    .form-group-full {\n      grid-column: 1 \/ -1;\n    }\n\n    .session-generated {\n      background: var(--bg-primary);\n      border: 1px solid var(--border-light);\n      border-radius: 12px;\n      padding: 20px;\n      margin-top: 20px;\n      display: none;\n    }\n\n    .session-generated.show { display: block; }\n\n    .session-url {\n      background: var(--bg-secondary);\n      border: 1px solid var(--border-light);\n      border-radius: 8px;\n      padding: 12px 16px;\n      margin-bottom: 16px;\n      font-family: monospace;\n      font-size: 12px;\n      overflow-x: auto;\n      word-break: break-all;\n    }\n\n    .session-actions {\n      display: flex;\n      gap: 12px;\n    }\n\n    \/* ===== TABLES ===== *\/\n    .table-container {\n      overflow-x: auto;\n    }\n\n    table {\n      width: 100%;\n      border-collapse: collapse;\n      font-size: 14px;\n    }\n\n    th {\n      background: var(--bg-primary);\n      border-bottom: 1px solid var(--border-light);\n      padding: 16px;\n      text-align: left;\n      font-weight: 600;\n      text-transform: uppercase;\n      letter-spacing: 0.5px;\n      font-size: 12px;\n      color: var(--text-muted);\n    }\n\n    td {\n      border-bottom: 1px solid var(--border-light);\n      padding: 16px;\n    }\n\n    tr:hover { background: rgba(201, 168, 76, 0.03); }\n\n    .table-actions {\n      display: flex;\n      gap: 8px;\n    }\n\n    .action-btn {\n      padding: 6px 12px;\n      font-size: 12px;\n      border-radius: 6px;\n    }\n\n    .badge {\n      display: inline-block;\n      padding: 4px 12px;\n      border-radius: 50px;\n      font-size: 11px;\n      font-weight: 600;\n      text-transform: uppercase;\n      letter-spacing: 0.5px;\n    }\n\n    .badge-active {\n      background: rgba(76, 175, 80, 0.15);\n      color: #4caf50;\n    }\n\n    .badge-expired {\n      background: rgba(220, 74, 57, 0.15);\n      color: #dc4a39;\n    }\n\n    .progress-mini {\n      width: 100%;\n      height: 6px;\n      background: var(--bg-secondary);\n      border-radius: 3px;\n      overflow: hidden;\n      margin-top: 4px;\n    }\n\n    .progress-mini-fill {\n      height: 100%;\n      background: var(--accent-gold);\n    }\n\n    \/* ===== MODAL ===== *\/\n    .modal {\n      display: none;\n      position: fixed;\n      top: 0;\n      left: 0;\n      right: 0;\n      bottom: 0;\n      background: rgba(0, 0, 0, 0.7);\n      backdrop-filter: blur(4px);\n      z-index: 1000;\n      align-items: center;\n      justify-content: center;\n      padding: 20px;\n    }\n\n    .modal.active { display: flex; }\n\n    .modal-content {\n      background: var(--bg-card);\n      border: 1px solid var(--border-light);\n      border-radius: 20px;\n      padding: 40px;\n      max-width: 700px;\n      width: 100%;\n      max-height: 80vh;\n      overflow-y: auto;\n      animation: fadeInUp 0.3s ease-out;\n    }\n\n    .modal-header {\n      display: flex;\n      justify-content: space-between;\n      align-items: flex-start;\n      margin-bottom: 24px;\n    }\n\n    .modal-title {\n      font-size: 24px;\n      font-family: 'Playfair Display', serif;\n    }\n\n    .modal-close {\n      background: none;\n      border: none;\n      color: var(--text-muted);\n      font-size: 24px;\n      cursor: pointer;\n      padding: 0;\n      width: 32px;\n      height: 32px;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n    }\n\n    .modal-close:hover { color: var(--accent-gold); }\n\n    \/* ===== TOAST ===== *\/\n    .toast-container {\n      position: fixed;\n      top: 20px;\n      right: 20px;\n      z-index: 2000;\n      display: flex;\n      flex-direction: column;\n      gap: 12px;\n    }\n\n    .toast {\n      background: var(--bg-card);\n      border: 1px solid var(--border-light);\n      border-radius: 12px;\n      padding: 16px 20px;\n      display: flex;\n      gap: 12px;\n      align-items: flex-start;\n      max-width: 400px;\n      animation: slideInRight 0.3s ease-out;\n      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);\n    }\n\n    .toast.success { border-color: rgba(76, 175, 80, 0.3); }\n    .toast.error { border-color: rgba(220, 74, 57, 0.3); }\n\n    .toast-icon {\n      font-size: 20px;\n      flex-shrink: 0;\n    }\n\n    .toast.success .toast-icon { color: #4caf50; }\n    .toast.error .toast-icon { color: #dc4a39; }\n\n    \/* ===== ANIMATIONS ===== *\/\n    @keyframes fadeInUp {\n      from {\n        opacity: 0;\n        transform: translateY(20px);\n      }\n      to {\n        opacity: 1;\n        transform: translateY(0);\n      }\n    }\n\n    @keyframes slideInRight {\n      from {\n        opacity: 0;\n        transform: translateX(20px);\n      }\n      to {\n        opacity: 1;\n        transform: translateX(0);\n      }\n    }\n\n    \/* ===== RESPONSIVE ===== *\/\n    @media (max-width: 640px) {\n      .screens-container { padding: 24px 16px; }\n      .question-card { padding: 24px 20px; }\n      .admin-section { padding: 20px; }\n      .modal-content { padding: 24px; }\n      .zone-breakdown {\n        grid-template-columns: 1fr;\n      }\n      .tab-bar {\n        gap: 0;\n      }\n      .tab-btn {\n        padding: 12px 16px;\n        font-size: 12px;\n      }\n    }\n\n    @media (max-width: 400px) {\n      .landing-title { font-size: 28px; }\n      .landing-subtitle { font-size: 16px; }\n      .question-card { padding: 20px 16px; }\n      .question-text { font-size: 18px; }\n      .scale-buttons { gap: 8px; }\n      .btn-circle { width: 44px; height: 44px; }\n    }\n  <\/style>\n<\/head>\n<body>\n\n<!-- LANDING SCREEN -->\n<div id=\"landingScreen\">\n  <div class=\"landing-content\">\n    <div class=\"landing-logo\">\n        <img decoding=\"async\" src=\"https:\/\/rismethod.com\/wp-content\/uploads\/2026\/02\/cropped-RIS_LOGO_CLASSY-removebg-preview.png\" \" width=\"250\" height=\"auto\">\n      \n            <stop offset=\"0%\" style=\"stop-color:#e8c96a;stop-opacity:1\" \/>\n            <stop offset=\"100%\" style=\"stop-color:#C9A84C;stop-opacity:1\" \/>\n          <\/linearGradient>\n        <\/defs>\n        \n      <\/svg>\n    <\/div>\n    <div class=\"landing-badge\">RIS METHOD\u2122 \u00b7 Leadership Diagnostics<\/div>\n    <h1 class=\"landing-title\">The Leadership Friction Autopsy\u2122<\/h1>\n    <p class=\"landing-subtitle\">Two diagnostics, one sharp read, where culture is slowing execution and the role of leadership.<\/p>\n    <div class=\"landing-meta\">\n      <div class=\"landing-meta-item\">35 Questions \u00b7 8 Minutes<\/div>\n      <div class=\"landing-meta-item\">Confidential Team Mode<\/div>\n      <div class=\"landing-meta-item\">Results by Email<\/div>\n    <\/div>\n    <div class=\"quote-card\">\n      I work quietly with a small group of CEOs who are building legacy businesses, not just sellable assets.\n      <div class=\"quote-attribution\">\u2014 Phillip \u00b7 RISMETHOD\u2122<\/div>\n    <\/div>\n    <button type=\"button\" class=\"btn btn-primary landing-cta\" onclick=\"showApp()\">Begin the Diagnostic \u2192<\/button>\n  <\/div>\n<\/div>\n\n<!-- MAIN APP -->\n<div id=\"app\">\n  <div class=\"tab-bar\">\n    <button class=\"tab-btn active\" data-tab=\"ceo\">CEO Diagnostic<\/button>\n    <button class=\"tab-btn\" data-tab=\"team\">Team Survey<\/button>\n    <button class=\"tab-btn\" data-tab=\"admin\">Admin<\/button>\n  <\/div>\n\n  <div class=\"screens-container\">\n    <!-- CEO TAB -->\n    <div id=\"ceoScreen\" class=\"screen active\">\n      <div class=\"container\">\n        <div style=\"max-width: 600px; margin: 0 auto;\">\n          <h2 style=\"font-size: 28px; margin-bottom: 8px;\">CEO Diagnostic<\/h2>\n          <p style=\"color: var(--text-muted); margin-bottom: 32px;\">Tell us about you and your company.<\/p>\n\n          <form id=\"ceoIntakeForm\">\n            <div class=\"form-group\">\n              <label class=\"form-required\">Full Name<\/label>\n              <input type=\"text\" id=\"ceoName\" placeholder=\"Your full name\" required>\n            <\/div>\n\n            <div class=\"form-group\">\n              <label class=\"form-required\">Email Address<\/label>\n              <input type=\"email\" id=\"ceoEmail\" placeholder=\"your@email.com\" required>\n            <\/div>\n\n            <div class=\"form-group\">\n              <label class=\"form-required\">Your Role<\/label>\n              <input type=\"text\" id=\"ceoRole\" placeholder=\"e.g. CEO, Founder, MD\" required>\n            <\/div>\n\n            <div class=\"form-group\">\n              <label class=\"form-required\">Company Name<\/label>\n              <input type=\"text\" id=\"ceoCompany\" placeholder=\"Your company\" required>\n            <\/div>\n\n            <div class=\"form-group\">\n              <label class=\"form-required\">Annual Revenue<\/label>\n              <select id=\"ceoRevenue\" required>\n                <option value=\"\">Select revenue range<\/option>\n                <option value=\"under5m\">Under $5M<\/option>\n                <option value=\"5-20m\">$5M\u2013$20M<\/option>\n                <option value=\"20-50m\">$20M\u2013$50M<\/option>\n                <option value=\"50-100m\">$50M\u2013$100M<\/option>\n                <option value=\"100-200m\">$100M\u2013$200M<\/option>\n                <option value=\"200-500m\">$200M\u2013$500M<\/option>\n                <option value=\"500m+\">$500M+<\/option>\n              <\/select>\n            <\/div>\n\n            <div class=\"form-group\">\n              <label class=\"form-required\">Industry<\/label>\n              <select id=\"ceoIndustry\" required>\n                <option value=\"\">Select industry<\/option>\n                <option value=\"manufacturing\">Manufacturing<\/option>\n                <option value=\"healthcare\">Healthcare<\/option>\n                <option value=\"financial\">Financial Services<\/option>\n                <option value=\"technology\">Technology<\/option>\n                <option value=\"professional\">Professional Services<\/option>\n                <option value=\"retail\">Retail<\/option>\n                <option value=\"consumer\">Consumer<\/option>\n                <option value=\"construction\">Construction<\/option>\n                <option value=\"real-estate\">Real Estate<\/option>\n                <option value=\"nonprofit\">Non-Profit<\/option>\n                <option value=\"faith\">Faith-Based<\/option>\n                <option value=\"other\">Other<\/option>\n              <\/select>\n            <\/div>\n\n            <div class=\"form-group\">\n              <label class=\"form-required\">Number of Employees<\/label>\n              <select id=\"ceoEmployees\" required>\n                <option value=\"\">Select size<\/option>\n                <option value=\"1-25\">1\u201325<\/option>\n                <option value=\"26-100\">26\u2013100<\/option>\n                <option value=\"101-300\">101\u2013300<\/option>\n                <option value=\"301-500\">301\u2013500<\/option>\n                <option value=\"500+\">500+<\/option>\n              <\/select>\n            <\/div>\n\n            <button type=\"button\" class=\"btn btn-primary\" style=\"width: 100%; padding: 14px; font-size: 16px; margin-top: 20px;\" onclick=\"startCEODiagnostic()\">Begin My Diagnostic \u2192<\/button>\n          <\/form>\n        <\/div>\n      <\/div>\n    <\/div>\n\n    <!-- TEAM TAB -->\n    <div id=\"teamScreen\" class=\"screen\">\n      <div class=\"container\">\n        <div style=\"max-width: 600px; margin: 0 auto;\">\n          <h2 style=\"font-size: 28px; margin-bottom: 8px;\">Team Survey<\/h2>\n          <p style=\"color: var(--text-muted); margin-bottom: 32px;\">Join your leader's diagnostic session.<\/p>\n\n          <div id=\"sessionStatus\" style=\"background: var(--bg-card); border: 1px solid var(--border-light); border-radius: 12px; padding: 16px; margin-bottom: 24px; display: none;\">\n            <div style=\"font-size: 12px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 4px;\">Session Status<\/div>\n            <div style=\"color: #4caf50; font-weight: 600;\">\u2713 Active Team Session<\/div>\n          <\/div>\n\n          <form id=\"teamIntakeForm\">\n            <div class=\"form-group\">\n              <label class=\"form-required\">Your Role<\/label>\n              <input type=\"text\" id=\"teamRole\" placeholder=\"e.g. VP Sales, CFO, Head of Ops\" required>\n            <\/div>\n\n            <div class=\"form-group\">\n              <label class=\"form-required\">Your Email<\/label>\n              <input type=\"email\" id=\"teamEmail\" placeholder=\"your@email.com\" required>\n              <div style=\"font-size: 12px; color: var(--text-muted); margin-top: 6px;\">Used to confirm your submission. Your individual answers are never shared with your leader by name \u2014 only the aggregate picture.<\/div>\n            <\/div>\n\n            <div class=\"form-group\">\n              <label class=\"form-required\">Company Name<\/label>\n              <input type=\"text\" id=\"teamCompany\" readonly>\n            <\/div>\n\n            <button type=\"button\" class=\"btn btn-primary\" style=\"width: 100%; padding: 14px; font-size: 16px; margin-top: 20px;\" id=\"startTeamBtn\" onclick=\"startTeamDiagnostic()\" disabled>Begin Team Diagnostic \u2192<\/button>\n          <\/form>\n        <\/div>\n      <\/div>\n    <\/div>\n\n    <!-- ADMIN TAB -->\n    <div id=\"adminScreen\" class=\"screen\"><\/div>\n  <\/div>\n<\/div>\n\n<!-- SURVEY CONTAINER -->\n<div id=\"surveyContainer\" style=\"display: none; flex-direction: column; min-height: 100vh;\">\n  <div class=\"progress-bar-container\">\n    <div class=\"progress-label\" id=\"progressLabel\">Part 1 \u00b7 Cultural Friction \u2014 Question 1 of 25<\/div>\n    <div class=\"progress-bar\">\n      <div class=\"progress-fill\" id=\"progressFill\" style=\"width: 0%;\"><\/div>\n    <\/div>\n  <\/div>\n\n  <div class=\"screens-container\">\n    <div class=\"question-card\">\n      <div class=\"zone-pill cf\" id=\"zonePill\"><\/div>\n      <div class=\"question-counter\" id=\"questionCounter\"><\/div>\n      <div class=\"question-text\" id=\"questionText\"><\/div>\n      <div class=\"answer-grid\" id=\"answerGrid\"><\/div>\n      <div class=\"nav-buttons\">\n        <button class=\"btn btn-secondary\" id=\"backBtn\" style=\"display: none;\" onclick=\"previousQuestion()\">\u2190 Back<\/button>\n        <button class=\"btn btn-primary\" id=\"nextBtn\" disabled onclick=\"nextQuestion()\">Next \u2192<\/button>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/div>\n\n<!-- RESULTS CONTAINER -->\n<div id=\"resultsContainer\" style=\"display: none; flex-direction: column; min-height: 100vh;\">\n  <div class=\"screens-container\" style=\"padding-top: 60px; padding-bottom: 60px;\">\n    <div class=\"results-header\" id=\"resultsHeader\"><\/div>\n    <div id=\"resultsContent\"><\/div>\n  <\/div>\n<\/div>\n\n<!-- ADMIN LOGIN CONTAINER -->\n<div id=\"adminLoginContainer\" style=\"display: none;\">\n  <div class=\"admin-login-container\">\n    <div class=\"admin-login-card\">\n      <div class=\"admin-login-logo\">\ud83d\udd12<\/div>\n      <h1 class=\"admin-login-title\">Admin Access<\/h1>\n      <p class=\"admin-login-subtitle\">Enter credentials to continue<\/p>\n\n      <div class=\"admin-error\" id=\"adminError\"><\/div>\n\n      <form id=\"adminLoginForm\" onsubmit=\"adminLogin(event)\">\n        <div class=\"form-group\" style=\"text-align: left;\">\n          <label>Username<\/label>\n          <input type=\"text\" id=\"adminUsername\" placeholder=\"Username\" required>\n        <\/div>\n\n        <div class=\"form-group\" style=\"text-align: left;\">\n          <label>Password<\/label>\n          <input type=\"password\" id=\"adminPassword\" placeholder=\"Password\" required>\n        <\/div>\n\n        <button type=\"submit\" class=\"btn btn-primary\" style=\"width: 100%;\">Sign In<\/button>\n      <\/form>\n\n      <div class=\"admin-forgot\">\n        Forgot credentials? Contact <a href=\"mailto:phill@rismethod.com\">phill@rismethod.com<\/a>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/div>\n\n<!-- ADMIN DASHBOARD CONTAINER -->\n<div id=\"adminDashboardContainer\" style=\"display: none;\">\n  <div class=\"screens-container\">\n    <div class=\"admin-dashboard\">\n      <div class=\"admin-header\">\n        <h1>Admin Dashboard<\/h1>\n        <div class=\"admin-header-actions\">\n          <button class=\"btn btn-secondary\" onclick=\"exportCSV()\">\ud83d\udcca Export CSV<\/button>\n          <button class=\"btn btn-secondary\" onclick=\"adminLogout()\">Sign Out<\/button>\n        <\/div>\n      <\/div>\n\n      <div class=\"stats-grid\" id=\"statsGrid\"><\/div>\n\n      <div class=\"admin-section\">\n        <h2 class=\"admin-section-title\">Generate Session Link<\/h2>\n        <form id=\"sessionForm\" onsubmit=\"generateSessionLink(event)\">\n          <div class=\"session-form\">\n            <div class=\"form-group\">\n              <label class=\"form-required\">Company Name<\/label>\n              <input type=\"text\" id=\"sessionCompany\" required>\n            <\/div>\n            <div class=\"form-group\">\n              <label class=\"form-required\">Leader Name<\/label>\n              <input type=\"text\" id=\"sessionLeader\" required>\n            <\/div>\n            <div class=\"form-group\">\n              <label class=\"form-required\">Leader Email<\/label>\n              <input type=\"email\" id=\"sessionLeaderEmail\" required>\n            <\/div>\n            <div class=\"form-group\">\n              <label>Phone Number<\/label>\n              <input type=\"text\" id=\"sessionPhone\">\n            <\/div>\n            <div class=\"form-group\">\n              <label>Industry<\/label>\n              <select id=\"sessionIndustry\">\n                <option value=\"\">Select industry<\/option>\n                <option value=\"manufacturing\">Manufacturing<\/option>\n                <option value=\"healthcare\">Healthcare<\/option>\n                <option value=\"financial\">Financial Services<\/option>\n                <option value=\"technology\">Technology<\/option>\n                <option value=\"professional\">Professional Services<\/option>\n                <option value=\"retail\">Retail<\/option>\n                <option value=\"consumer\">Consumer<\/option>\n                <option value=\"construction\">Construction<\/option>\n                <option value=\"real-estate\">Real Estate<\/option>\n                <option value=\"nonprofit\">Non-Profit<\/option>\n                <option value=\"faith\">Faith-Based<\/option>\n                <option value=\"other\">Other<\/option>\n              <\/select>\n            <\/div>\n            <div class=\"form-group\">\n              <label>Annual Revenue<\/label>\n              <select id=\"sessionRevenue\">\n                <option value=\"\">Select revenue<\/option>\n                <option value=\"under5m\">Under $5M<\/option>\n                <option value=\"5-20m\">$5M\u2013$20M<\/option>\n                <option value=\"20-50m\">$20M\u2013$50M<\/option>\n                <option value=\"50-100m\">$50M\u2013$100M<\/option>\n                <option value=\"100-200m\">$100M\u2013$200M<\/option>\n                <option value=\"200-500m\">$200M\u2013$500M<\/option>\n                <option value=\"500m+\">$500M+<\/option>\n              <\/select>\n            <\/div>\n            <div class=\"form-group\">\n              <label>Team Size<\/label>\n              <select id=\"sessionTeamSize\">\n                <option value=\"\">Select size<\/option>\n                <option value=\"2\">2<\/option>\n                <option value=\"3\">3<\/option>\n                <option value=\"4\">4<\/option>\n                <option value=\"5\">5<\/option>\n                <option value=\"6\">6<\/option>\n                <option value=\"8\">8<\/option>\n                <option value=\"10\">10<\/option>\n                <option value=\"12\">12<\/option>\n                <option value=\"15+\">15+<\/option>\n              <\/select>\n            <\/div>\n            <div class=\"form-group\">\n              <label>Session Date<\/label>\n              <input type=\"date\" id=\"sessionDate\">\n            <\/div>\n            <button type=\"submit\" class=\"btn btn-primary form-group-full\">Generate Session Link<\/button>\n          <\/div>\n        <\/form>\n\n        <div id=\"sessionGenerated\" class=\"session-generated\">\n          <div style=\"margin-bottom: 12px;\">\n            <div style=\"font-size: 12px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 4px;\">Session Created<\/div>\n            <div style=\"color: #4caf50; font-weight: 600;\">\u2713 Link generated successfully<\/div>\n          <\/div>\n          <div style=\"font-size: 12px; color: var(--text-muted); margin-bottom: 12px;\">Share this link with your team:<\/div>\n          <div class=\"session-url\" id=\"generatedSessionUrl\"><\/div>\n          <div class=\"session-actions\">\n            <button class=\"btn btn-secondary action-btn\" onclick=\"copySessionLink()\">\ud83d\udccb Copy Link<\/button>\n            <button class=\"btn btn-secondary action-btn\" onclick=\"emailSessionLink()\">\ud83d\udce7 Email to Leader<\/button>\n          <\/div>\n        <\/div>\n      <\/div>\n\n      <div class=\"admin-section\">\n        <h2 class=\"admin-section-title\">Active Sessions<\/h2>\n        <div class=\"table-container\" id=\"sessionsTableContainer\"><\/div>\n      <\/div>\n\n      <div class=\"admin-section\">\n        <h2 class=\"admin-section-title\">All Results<\/h2>\n        <div class=\"table-container\" id=\"resultsTableContainer\"><\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/div>\n\n<!-- MODAL -->\n<div id=\"detailModal\" class=\"modal\">\n  <div class=\"modal-content\" id=\"modalContent\"><\/div>\n<\/div>\n\n<!-- TOAST CONTAINER -->\n<div class=\"toast-container\" id=\"toastContainer\"><\/div>\n\n<script>\n\/\/ ===== CONFIG =====\nconst CONFIG = {\n  appUrl: window.location.origin + window.location.pathname,\n  email: {\n    \/\/ \u2705 EmailJS credentials configured\n    serviceId: 'service_fazl3ab',\n    templateIdAlert: 'template_e2g7fot', \/\/ Admin alerts\n    templateIdResults: 'template_inpkl2c', \/\/ Respondent results\n    templateIdLeader: 'template_vceka0h', \/\/ Session links\n    publicKey: 'oobNeFhCL0yLB43bV',\n    adminEmail: 'phill@rismethod.com' \/\/ Change this to your email\n  },\n  sheetsWebhook: 'https:\/\/script.google.com\/macros\/s\/AKfycbxyW3PtpwlZA6uVMv_4IoE21v7_F1hnx5x9cKbp-qyC6G8jR9YpitTehnZT3nD1NQu4\/exec', \/\/ Google Sheets central results register\n  admin: {\n    \/\/ Credentials stored as SHA-256 hashes \u2014 plaintext no longer lives in this file.\n    \/\/ To change them: generate the SHA-256 hex of the new value and replace below.\n    userHash: '7d8030ceaa67ccb2141206dbcf9f179db3ff769b64ecccec8a60d59764391a40',\n    passHash: 'bbfe85c20bd1adc33024bc6a4bef576bd126024f3f2da7cadaa9d868e1e42752'\n  }\n};\n\n\/\/ Initialize EmailJS\nif (CONFIG.email.publicKey && CONFIG.email.publicKey !== 'YOUR_EMAILJS_PUBLIC_KEY') {\n  emailjs.init(CONFIG.email.publicKey);\n}\n\n\/\/ ===== STATE =====\nlet state = {\n  mode: null, \/\/ 'ceo' or 'team'\n  currentQuestion: 0,\n  answers: [],\n  respondent: {},\n  session: null,\n  isAdminLoggedIn: false\n};\n\n\/\/ ===== QUESTIONS DATA =====\n\/\/ v3 \u2014 rebuilt July 2026. Reverse-keyed items carry reverse:true (scoring inverts them).\n\/\/ CEO-voice set. Zones must keep 5 items each, in order, for zone scoring.\nconst CF_QUESTIONS = [\n  {\n    zone: 'Leadership Alignment',\n    text: 'If I privately interviewed my top leaders today, they would describe our single most important priority for the next 90 days in materially the <strong>same way<\/strong>.'\n  },\n  {\n    zone: 'Leadership Alignment',\n    text: 'When resources get tight, my team makes <strong>clean enterprise tradeoffs<\/strong> instead of protecting functional turf.'\n  },\n  {\n    zone: 'Leadership Alignment',\n    reverse: true,\n    text: 'When we add a new priority, it usually gets <strong>stacked on top of everything else<\/strong> \u2014 nothing is removed to make room for it.'\n  },\n  {\n    zone: 'Leadership Alignment',\n    text: \"A meaningful part of each senior leader's compensation or scorecard is tied to <strong>enterprise outcomes<\/strong>, not only their own function's numbers.\"\n  },\n  {\n    zone: 'Leadership Alignment',\n    reverse: true,\n    text: 'In a live resource conflict between departments, the decision usually <strong>waits for me to referee it<\/strong> personally.'\n  },\n  {\n    zone: 'Decision & Execution Discipline',\n    text: 'Important decisions are typically made <strong>where the best facts live<\/strong>, not escalated upward to reduce personal risk.'\n  },\n  {\n    zone: 'Decision & Execution Discipline',\n    text: 'If I were unreachable for five business days, the company would still <strong>advance major priorities<\/strong> without material drift.'\n  },\n  {\n    zone: 'Decision & Execution Discipline',\n    text: 'My senior team will <strong>challenge my thinking in the room<\/strong> when they believe I am wrong.'\n  },\n  {\n    zone: 'Decision & Execution Discipline',\n    text: 'A decision made in our leadership meetings is <strong>final<\/strong> \u2014 it does not need informal re-approval afterwards to be safe.'\n  },\n  {\n    zone: 'Decision & Execution Discipline',\n    text: 'Once a decision is made, the organisation does not quietly <strong>re-litigate it through delay<\/strong>.'\n  },\n  {\n    zone: 'Accountability Rigor',\n    text: 'When a senior leader misses a committed outcome, it triggers a <strong>real accountability conversation<\/strong> \u2014 not a polite reset of the deadline.'\n  },\n  {\n    zone: 'Accountability Rigor',\n    text: 'In the last 90 days, material problems have reached me <strong>while there was still time to fix them cheaply<\/strong>.'\n  },\n  {\n    zone: 'Accountability Rigor',\n    text: 'Our performance conversations confront <strong>ownership<\/strong>, not just the dashboard numbers.'\n  },\n  {\n    zone: 'Accountability Rigor',\n    reverse: true,\n    text: 'There is at least one underperforming leader we have <strong>tolerated too long<\/strong> because of loyalty or history.'\n  },\n  {\n    zone: 'Accountability Rigor',\n    text: 'My team would say I hold myself to the <strong>same standard of consequence<\/strong> I expect from them.'\n  },\n  {\n    zone: 'Talent Density & Energy',\n    text: 'Every leader in a critical seat is someone I would <strong>confidently hire again today<\/strong> for the same role if the seat were suddenly open.'\n  },\n  {\n    zone: 'Talent Density & Energy',\n    reverse: true,\n    text: 'At least one of my strongest performers is currently <strong>carrying a weaker colleague<\/strong> while we describe the team as fine.'\n  },\n  {\n    zone: 'Talent Density & Energy',\n    text: 'Our recent senior hires were made from <strong>conviction and standard<\/strong>, not because the seat had stayed open too long.'\n  },\n  {\n    zone: 'Talent Density & Energy',\n    reverse: true,\n    text: 'We are currently <strong>over-tolerating at least one seat<\/strong> we know is below standard.'\n  },\n  {\n    zone: 'Talent Density & Energy',\n    text: 'Difficult people decisions are made <strong>before strong performers<\/strong> start questioning the seriousness of leadership.'\n  },\n  {\n    zone: 'Leadership Courage & Cultural Integrity',\n    text: 'My senior leaders tell me the truth <strong>before it is safe<\/strong> \u2014 not the edited version once the problem is undeniable.'\n  },\n  {\n    zone: 'Leadership Courage & Cultural Integrity',\n    text: 'When a commercially valuable leader underperforms, we <strong>confront it directly and promptly<\/strong>.'\n  },\n  {\n    zone: 'Leadership Courage & Cultural Integrity',\n    text: 'Hard conversations happen <strong>in the room where decisions are made<\/strong>, not in corridor conversations afterwards.'\n  },\n  {\n    zone: 'Leadership Courage & Cultural Integrity',\n    reverse: true,\n    text: 'At least one person, process, or legacy habit here is currently <strong>exempt from honest scrutiny<\/strong> because of history, ego, or revenue.'\n  },\n  {\n    zone: 'Leadership Courage & Cultural Integrity',\n    text: 'If I rebuilt this company from scratch at the same scale, I would deliberately recreate the <strong>courage standard<\/strong> of our leadership culture as it exists today.'\n  }\n];\n\n\/\/ Team-voice mirror set \u2014 same zones, same order, observed from the team's seat.\nconst TEAM_CF_QUESTIONS = [\n  {\n    zone: 'Leadership Alignment',\n    text: \"If each member of the senior team privately wrote down the company's single most important priority for the next 90 days, the answers would be <strong>materially the same<\/strong>.\"\n  },\n  {\n    zone: 'Leadership Alignment',\n    text: 'When resources get tight, our leadership team makes <strong>clean company-first tradeoffs<\/strong> instead of protecting departmental turf.'\n  },\n  {\n    zone: 'Leadership Alignment',\n    reverse: true,\n    text: 'When leadership adds a new priority, it gets <strong>stacked on top of everything else<\/strong> \u2014 nothing is removed to make room.'\n  },\n  {\n    zone: 'Leadership Alignment',\n    text: \"Leaders here are rewarded for <strong>company outcomes<\/strong>, not only their own department's numbers.\"\n  },\n  {\n    zone: 'Leadership Alignment',\n    reverse: true,\n    text: 'When two departments compete for resources, the decision usually <strong>waits for the CEO to referee it<\/strong>.'\n  },\n  {\n    zone: 'Decision & Execution Discipline',\n    text: 'Important decisions are made <strong>where the best facts live<\/strong>, not escalated upward so nobody has to take personal risk.'\n  },\n  {\n    zone: 'Decision & Execution Discipline',\n    text: 'If the CEO were unreachable for five business days, major priorities would still <strong>move forward<\/strong> without drift.'\n  },\n  {\n    zone: 'Decision & Execution Discipline',\n    text: \"Senior leaders <strong>openly challenge the CEO's thinking in the room<\/strong> when they believe the CEO is wrong.\"\n  },\n  {\n    zone: 'Decision & Execution Discipline',\n    text: 'Decisions made in leadership meetings are <strong>final<\/strong> \u2014 they do not need informal blessing afterwards to be safe.'\n  },\n  {\n    zone: 'Decision & Execution Discipline',\n    text: 'Once a decision is made, this organisation does not quietly <strong>re-litigate it through delay<\/strong>.'\n  },\n  {\n    zone: 'Accountability Rigor',\n    text: 'When a senior leader misses a committed outcome, there is a <strong>real accountability conversation<\/strong> \u2014 not a quiet reset of the deadline.'\n  },\n  {\n    zone: 'Accountability Rigor',\n    text: 'Bad news travels upward <strong>fast enough to be fixed cheaply<\/strong> \u2014 people here do not sit on problems.'\n  },\n  {\n    zone: 'Accountability Rigor',\n    text: 'Performance conversations here confront <strong>ownership<\/strong>, not just the dashboard numbers.'\n  },\n  {\n    zone: 'Accountability Rigor',\n    reverse: true,\n    text: 'At least one underperforming leader has been <strong>tolerated too long<\/strong> because of loyalty or history.'\n  },\n  {\n    zone: 'Accountability Rigor',\n    text: 'The CEO holds themselves to the <strong>same standard of consequence<\/strong> they expect from everyone else.'\n  },\n  {\n    zone: 'Talent Density & Energy',\n    text: 'Every leader in a critical seat is someone this company would <strong>confidently re-hire today<\/strong> for the same role.'\n  },\n  {\n    zone: 'Talent Density & Energy',\n    reverse: true,\n    text: 'At least one strong performer is currently <strong>carrying a weaker colleague<\/strong> while leadership describes the team as fine.'\n  },\n  {\n    zone: 'Talent Density & Energy',\n    text: 'Recent senior hires were made from <strong>conviction and standard<\/strong>, not desperation because a seat stayed open too long.'\n  },\n  {\n    zone: 'Talent Density & Energy',\n    reverse: true,\n    text: 'We are currently <strong>over-tolerating at least one seat<\/strong> everyone knows is below standard.'\n  },\n  {\n    zone: 'Talent Density & Energy',\n    text: 'Difficult people decisions get made <strong>before strong performers<\/strong> start questioning whether leadership is serious.'\n  },\n  {\n    zone: 'Leadership Courage & Cultural Integrity',\n    text: 'People tell the CEO the truth <strong>before it is safe<\/strong> \u2014 not the edited version once the problem is undeniable.'\n  },\n  {\n    zone: 'Leadership Courage & Cultural Integrity',\n    text: 'When a commercially valuable or politically connected leader underperforms, it is <strong>confronted directly and promptly<\/strong>.'\n  },\n  {\n    zone: 'Leadership Courage & Cultural Integrity',\n    text: 'Hard conversations happen <strong>in the meeting<\/strong>, not in corridor conversations after it ends.'\n  },\n  {\n    zone: 'Leadership Courage & Cultural Integrity',\n    reverse: true,\n    text: 'At least one person, process, or legacy habit here is <strong>exempt from honest scrutiny<\/strong> because of history, ego, or revenue.'\n  },\n  {\n    zone: 'Leadership Courage & Cultural Integrity',\n    text: \"If this company were rebuilt from scratch, the <strong>courage standard<\/strong> of today's leadership culture would be worth deliberately recreating.\"\n  }\n];\n\nconst DRAG_QUESTIONS = [\n  {\n    text: 'If you disappeared for 2 weeks tomorrow, would your company continue operating at full capacity?',\n    options: [\n      { text: 'Yes \u2014 it runs without me', score: 0 },\n      { text: 'Partially \u2014 some things would slip', score: 1 },\n      { text: 'No \u2014 it would struggle significantly', score: 2 }\n    ]\n  },\n  {\n    text: 'What percentage of decisions in your company require your <strong>direct input<\/strong>?',\n    options: [\n      { text: 'Less than 20%', score: 0 },\n      { text: '20\u201350%', score: 1 },\n      { text: 'More than 50%', score: 2 }\n    ]\n  },\n  {\n    text: 'How many times per day are you interrupted for things your team <strong>should be able to handle<\/strong>?',\n    options: [\n      { text: 'Fewer than 3 times', score: 0 },\n      { text: '3\u201310 times', score: 1 },\n      { text: 'More than 10 times', score: 2 }\n    ]\n  },\n  {\n    text: 'When did you last take a <strong>full week off<\/strong> without checking messages?',\n    options: [\n      { text: 'Less than 6 months ago', score: 0 },\n      { text: '6\u201318 months ago', score: 1 },\n      { text: \"I honestly can't remember\", score: 2 }\n    ]\n  },\n  {\n    text: 'Do your senior leaders make decisions <strong>confidently without you in the room<\/strong>?',\n    options: [\n      { text: 'Usually \u2014 they own it', score: 0 },\n      { text: 'Sometimes \u2014 it depends on the topic', score: 1 },\n      { text: 'Rarely \u2014 they wait for me', score: 2 }\n    ]\n  },\n  {\n    text: 'How many meetings in the last week actually <strong>required your presence<\/strong>?',\n    options: [\n      { text: 'Less than half', score: 0 },\n      { text: 'About half', score: 1 },\n      { text: 'Most of them', score: 2 }\n    ]\n  },\n  {\n    text: 'Is your inbox a <strong>decision queue disguised as communication<\/strong>?',\n    options: [\n      { text: \"No \u2014 I'm not the bottleneck\", score: 0 },\n      { text: 'Sometimes \u2014 certain areas pile up', score: 1 },\n      { text: \"Yes \u2014 it's relentless\", score: 2 }\n    ]\n  },\n  {\n    text: 'If your best operations person left tomorrow, would the company <strong>know what to do<\/strong>?',\n    options: [\n      { text: 'Yes \u2014 systems and people are in place', score: 0 },\n      { text: 'Probably \u2014 with some scrambling', score: 1 },\n      { text: \"No \u2014 we'd be exposed\", score: 2 }\n    ]\n  },\n  {\n    text: 'Are you the last person to know about problems, or the first?',\n    options: [\n      { text: 'Last \u2014 problems surface before they reach me', score: 0 },\n      { text: 'Sometimes first, sometimes last', score: 1 },\n      { text: \"First \u2014 I'm always the one who finds out\", score: 2 }\n    ]\n  },\n  {\n    text: 'Honest self-assessment: are you running the company, or is <strong>the company running you<\/strong>?',\n    options: [\n      { text: \"I'm running it \u2014 clear, intentional, in control\", score: 0 },\n      { text: \"It's mixed \u2014 some days I lead, some days I react\", score: 1 },\n      { text: \"The company is running me \u2014 I'm constantly reactive\", score: 2 }\n    ]\n  }\n];\n\n\/\/ Team-voice drag set \u2014 the team observes the CEO. Same scoring.\nconst TEAM_DRAG_QUESTIONS = [\n  {\n    text: 'If your CEO disappeared for 2 weeks tomorrow, would the company continue operating at full capacity?',\n    options: [\n      { text: 'Yes \u2014 it runs without them', score: 0 },\n      { text: 'Partially \u2014 some things would slip', score: 1 },\n      { text: 'No \u2014 it would struggle significantly', score: 2 }\n    ]\n  },\n  {\n    text: \"What percentage of meaningful decisions here require the CEO's <strong>direct input<\/strong> before anything moves?\",\n    options: [\n      { text: 'Less than 20%', score: 0 },\n      { text: '20\u201350%', score: 1 },\n      { text: 'More than 50%', score: 2 }\n    ]\n  },\n  {\n    text: 'How often do people take things to the CEO that the team <strong>should be able to handle<\/strong>?',\n    options: [\n      { text: 'Rarely \u2014 we solve our own problems', score: 0 },\n      { text: 'Sometimes \u2014 certain topics always go up', score: 1 },\n      { text: 'Constantly \u2014 the path of least resistance is the CEO', score: 2 }\n    ]\n  },\n  {\n    text: 'When did the CEO last take a <strong>full week off<\/strong> without staying plugged in?',\n    options: [\n      { text: 'Within the last 6 months', score: 0 },\n      { text: '6\u201318 months ago', score: 1 },\n      { text: \"Honestly, I can't remember it happening\", score: 2 }\n    ]\n  },\n  {\n    text: 'Do senior leaders make decisions <strong>confidently when the CEO is not in the room<\/strong>?',\n    options: [\n      { text: 'Usually \u2014 they own it', score: 0 },\n      { text: 'Sometimes \u2014 depends on the topic', score: 1 },\n      { text: 'Rarely \u2014 things wait for the CEO', score: 2 }\n    ]\n  },\n  {\n    text: \"How many meetings does the CEO attend that <strong>don't actually require them<\/strong>?\",\n    options: [\n      { text: 'Few \u2014 their calendar is disciplined', score: 0 },\n      { text: 'Some \u2014 they are in more than they need to be', score: 1 },\n      { text: 'Most \u2014 they are in everything', score: 2 }\n    ]\n  },\n  {\n    text: \"Do decisions stall while they sit in the CEO's <strong>inbox or queue<\/strong>?\",\n    options: [\n      { text: 'No \u2014 decisions move without bottlenecking there', score: 0 },\n      { text: 'Sometimes \u2014 certain areas pile up', score: 1 },\n      { text: 'Yes \u2014 constantly', score: 2 }\n    ]\n  },\n  {\n    text: 'If your best operations person left tomorrow, would the company <strong>know what to do<\/strong>?',\n    options: [\n      { text: 'Yes \u2014 systems and people are in place', score: 0 },\n      { text: 'Probably \u2014 with some scrambling', score: 1 },\n      { text: \"No \u2014 we'd be exposed\", score: 2 }\n    ]\n  },\n  {\n    text: 'Is the CEO the last person to hear about problems, or the first?',\n    options: [\n      { text: 'Last \u2014 problems get solved before they reach the top', score: 0 },\n      { text: 'Sometimes first, sometimes last', score: 1 },\n      { text: 'First \u2014 everything lands on the CEO', score: 2 }\n    ]\n  },\n  {\n    text: 'Honest read: is the CEO running the company, or is <strong>the company running the CEO<\/strong>?',\n    options: [\n      { text: 'Running it \u2014 clear, intentional, in control', score: 0 },\n      { text: 'Mixed \u2014 some days leading, some days reacting', score: 1 },\n      { text: 'The company is running the CEO \u2014 constantly reactive', score: 2 }\n    ]\n  }\n];\n\n\/\/ ===== RECOMMENDATION ENGINE DATA =====\nconst SIG_SALT = 'RIS-FS-2026-v3';\n\nconst REVENUE_MIDPOINTS = { 'under5m': 3, '5-20m': 12, '20-50m': 35, '50-100m': 75, '100-200m': 150, '200-500m': 350, '500m+': 600 };\n\nconst ZONE_LABELS = { alignment: 'Leadership Alignment', decision: 'Decision & Execution', accountability: 'Accountability Rigor', talent: 'Talent Density', culture: 'Leadership Courage' };\n\nconst REC_BLOCKS = {\n  alignment: {\n    strength: 'Your leadership team is pulling in one direction \u2014 rare and valuable at your scale. Protect it: codify the priority stack in writing, revisit it quarterly, and make it the first filter for every new initiative. Alignment decays silently under growth; what preserves it is subtraction discipline \u2014 every added priority must displace one.',\n    friction: \"Your leaders agree in the meeting and diverge in the corridor. The cost is duplicated effort and functional turf wars that never surface as open conflict \u2014 they surface as missed quarters. 14-day move: have each senior leader write the company's top priority independently, then compare the answers in the room. The spread you see is your alignment tax, made visible.\",\n    critical: 'At this level your company is effectively running several competing strategies at once \u2014 each function optimising for itself while the enterprise pays. Expect execution to die at director level, because nobody below you can resolve conflicts you have not resolved at the top. 14-day move: one working session, one written priority stack, one explicit list of what you are STOPPING. Nothing else works until this exists.'\n  },\n  decision: {\n    strength: 'Decisions move at the speed of facts, not fear \u2014 a structural advantage most companies never build. Guard the two failure points that arrive with scale: new leaders importing escalation habits, and your own availability quietly re-centralising decisions. Write decision rights down before your next senior hire.',\n    friction: \"Decisions are being made, then informally re-approved, then quietly re-litigated. Every loop adds days and teaches your best people that the meeting is not where truth happens. 14-day move: pick the three most consequential recurring decision types and assign each a single named owner \u2014 not a committee. Announce that reversing a decision now requires a meeting, not a corridor.\",\n    critical: \"Decision-making has collapsed upward. Escalation is being used as insurance, and delay has become the organisation's way of saying no without saying it. This is the pattern that caps companies at their CEO's personal bandwidth. 14-day move: log every decision that reaches you for one week and mark which ones a named subordinate could have made. Then hand those decision rights back \u2014 in writing, in public.\"\n  },\n  accountability: {\n    strength: 'Commitments here mean something \u2014 missed outcomes trigger real conversations, and bad news travels fast enough to be cheap. Sustain it by keeping consequence visible: when a hard call is made, let the leadership team see that it was made, and why.',\n    friction: 'Deadlines are being politely reset, and problems are arriving after the cheap window to fix them has closed. Your real standard is drifting toward what you tolerate, not what you preach. 14-day move: revisit the last three missed commitments and hold the conversation that should have happened \u2014 not as punishment, but so the team relearns that commitments are contracts.',\n    critical: 'Accountability has become optional for the protected. Your strongest performers noticed \u2014 they always notice first \u2014 and they are quietly recalibrating their own effort against what leadership tolerates. This is how A-players leave and B-players settle in. 14-day move: identify the single most visible tolerated underperformance and act on it. One visible act of consequence resets more culture than a year of values talk.'\n  },\n  talent: {\n    strength: 'You would rehire your critical seats today \u2014 that puts you in a small minority of companies at your scale. Keep the bar where it is: hire from conviction, act early on drift, and re-ask the rehire question quarterly. Talent density is a standard, not an event.',\n    friction: \"At least one seat is below standard and everyone knows it \u2014 including the people carrying the extra weight. The cost is not just that seat's output; it is the message your tolerance sends to your best people. 14-day move: run the rehire test on every critical seat, in writing. Any 'no' gets a plan with a date: coach up, move, or move out.\",\n    critical: 'Your best people are subsidising your weakest, and leadership has been describing the team as fine. That subsidy always ends the same way \u2014 the strong leave, the weak stay, and the CEO wonders when the culture changed. 14-day move: the two hardest people decisions you have been deferring go on the table with dates attached. Deferred people decisions are the most expensive line item you do not track.'\n  },\n  culture: {\n    strength: \"Truth moves faster than politics in your company \u2014 the rarest cultural asset there is. It survives only as long as the CEO visibly rewards the bearer of bad news. Keep doing that publicly, and keep the 'no exemptions' rule absolute \u2014 one protected person is all it takes to retrain everyone.\",\n    friction: 'Truth is arriving edited. Hard conversations are happening in corridors instead of the room, and at least one topic has become quietly undiscussable. Every undiscussable charges you the compound interest of unspoken problems. 14-day move: name the undiscussable yourself, in the room, first. The CEO going first is the only known cure.',\n    critical: \"Your company has learned that honesty is unsafe and silence is free. You are now making decisions on filtered information \u2014 the most expensive kind there is. Expect surprises 'nobody saw coming' that everybody saw coming. 14-day move: bring in a forcing mechanism \u2014 an anonymous team read (this tool's Team Mode exists for exactly this) \u2014 then respond to what surfaces without punishing a single messenger.\"\n  }\n};\n\nconst DRAG_FLAGS = [\n  'The company cannot run two weeks without you. Whatever you believe you own, this means the company owns you \u2014 and any acquirer, lender, or investor will price that dependency in.',\n  'More than half of all decisions route through you. You are not operating as the CEO; you are operating as the chief approval officer. Decision rights, not effort, are your constraint.',\n  \"Ten-plus interruptions a day for things the team should handle is roughly a full working day per week spent being your company's help desk.\",\n  'If you cannot remember your last real week off, you do not have a vacation problem \u2014 you have an architecture problem. Rest is a stress test your company is currently failing.',\n  'Your leaders wait for you. Every hour they wait is paid hesitation \u2014 and it compounds down every layer beneath them.',\n  'Most of your meetings do not need you. Your presence is either a habit or a comfort blanket for the team. Reclaim the calendar first; it is the cheapest win available.',\n  'Your inbox is a decision queue. Every unanswered email is a stalled workstream wearing a disguise.',\n  \"One resignation away from exposure means your systems live in people's heads. Documentation feels slow until the day it is the only thing that matters.\",\n  'Problems reach you first \u2014 meaning your organisation escalates before it solves. You built that muscle; only you can retire it.',\n  'You said it yourself: the company is running you. That answer, from the person with the most power to change it, is the diagnosis.'\n];\n\nfunction zoneSeverity(score) {\n  if (score <= 10) return 'strength';\n  if (score <= 17) return 'friction';\n  return 'critical';\n}\n\nfunction formatMoney(m) {\n  return m >= 1 ? '$' + m.toFixed(1).replace(\/\\.0$\/, '') + 'M' : '$' + Math.round(m * 1000) + 'K';\n}\n\nfunction frictionTax(scores) {\n  const mid = REVENUE_MIDPOINTS[state.respondent.revenue];\n  if (!mid) return null;\n  const cfPct = Math.max(0, (scores.cf.total - 25) \/ 100);\n  const dragPct = scores.drag.total \/ 20;\n  const combined = cfPct * 0.6 + dragPct * 0.4;\n  if (combined < 0.05) return null;\n  const low = mid * combined * 0.02;\n  const high = mid * combined * 0.05;\n  return { low, high, text: formatMoney(low) + '\u2013' + formatMoney(high) + ' per year' };\n}\n\nfunction buildRecommendations(scores) {\n  const sorted = Object.entries(scores.cf.zoneScores).sort((a, b) => b[1] - a[1]); \/\/ worst first\n  const worst = sorted.slice(0, 2);\n  const best = sorted.slice(-2).reverse();\n  const tax = state.mode === 'ceo' ? frictionTax(scores) : null;\n\n  let html = '<div class=\"score-card\" style=\"text-align:left;\">';\n  html += '<h3 style=\"margin-bottom:16px;\">Your Tailored Read \u2014 And What To Do About It<\/h3>';\n  let text = '';\n\n  if (tax) {\n    html += '<div style=\"background:var(--bg-primary);border:1px solid var(--border-light);border-radius:12px;padding:16px;margin-bottom:20px;\"><strong style=\"color:var(--accent-gold);\">Estimated Friction Tax: ' + tax.text + '<\/strong><div style=\"font-size:12px;color:var(--text-muted);margin-top:6px;\">A conservative estimate of execution capacity lost to the friction patterns in your answers, scaled to your revenue band. Directional, not an audit.<\/div><\/div>';\n    text += 'ESTIMATED FRICTION TAX: ' + tax.text + '\\n(Conservative, directional estimate based on your answers and revenue band.)\\n\\n';\n  }\n\n  html += '<h4 style=\"margin-bottom:12px;\">Your two priority zones<\/h4>';\n  text += 'YOUR TWO PRIORITY ZONES\\n';\n  worst.forEach(function (entry) {\n    const key = entry[0], score = entry[1];\n    const sev = zoneSeverity(score);\n    const block = REC_BLOCKS[key][sev];\n    const sevLabel = sev === 'critical' ? 'CRITICAL' : sev === 'friction' ? 'FRICTION' : 'STRENGTH';\n    html += '<div style=\"margin-bottom:16px;\"><strong>' + ZONE_LABELS[key] + ' \u2014 ' + score + '\/25 (' + sevLabel + ')<\/strong><p style=\"color:var(--text-muted);font-size:14px;line-height:1.7;margin-top:6px;\">' + block + '<\/p><\/div>';\n    text += '\\n' + ZONE_LABELS[key] + ' \u2014 ' + score + '\/25 (' + sevLabel + ')\\n' + block + '\\n';\n  });\n\n  html += '<h4 style=\"margin:20px 0 12px;\">Where you are strongest<\/h4>';\n  text += '\\nWHERE YOU ARE STRONGEST\\n';\n  best.forEach(function (entry) {\n    const key = entry[0], score = entry[1];\n    if (zoneSeverity(score) === 'strength') {\n      html += '<div style=\"margin-bottom:12px;\"><strong>' + ZONE_LABELS[key] + ' \u2014 ' + score + '\/25<\/strong><p style=\"color:var(--text-muted);font-size:14px;line-height:1.7;margin-top:6px;\">' + REC_BLOCKS[key].strength + '<\/p><\/div>';\n      text += '\\n' + ZONE_LABELS[key] + ' \u2014 ' + score + '\/25\\n' + REC_BLOCKS[key].strength + '\\n';\n    } else {\n      html += '<div style=\"margin-bottom:12px;\"><strong>' + ZONE_LABELS[key] + ' \u2014 ' + score + '\/25<\/strong><p style=\"color:var(--text-muted);font-size:14px;line-height:1.7;margin-top:6px;\">Your relative strongest zone \u2014 but at ' + score + '\/25 it still carries friction. Stabilise the priority zones above first.<\/p><\/div>';\n      text += '\\n' + ZONE_LABELS[key] + ' \u2014 ' + score + '\/25 (relative strength, still carrying friction)\\n';\n    }\n  });\n\n  if (state.mode === 'ceo') {\n    const flags = [];\n    (scores.dragAnswers || []).forEach(function (ansIdx, i) {\n      if (ansIdx !== null && ansIdx !== undefined && DRAG_QUESTIONS[i].options[ansIdx].score === 2) flags.push(DRAG_FLAGS[i]);\n    });\n    if (flags.length) {\n      html += '<h4 style=\"margin:20px 0 12px;\">Red flags from your own answers<\/h4>';\n      text += '\\nRED FLAGS FROM YOUR OWN ANSWERS\\n';\n      flags.forEach(function (f) {\n        html += '<p style=\"color:var(--text-muted);font-size:14px;line-height:1.7;margin-bottom:10px;\">\u2022 ' + f + '<\/p>';\n        text += '\\n\u2022 ' + f + '\\n';\n      });\n    }\n  }\n\n  html += '<div style=\"margin-top:24px;padding-top:16px;border-top:1px solid var(--border-light);font-size:14px;color:var(--text-muted);\">This read is generated from your specific answers \u2014 different answers produce a different read. To pressure-test it against reality, the next step is a confidential <strong>Leadership Risk Audit<\/strong>: <a href=\"mailto:phill@rismethod.com\" style=\"color:var(--accent-gold);\">phill@rismethod.com<\/a><\/div>';\n  html += '<\/div>';\n\n  return { html: html, text: text, taxText: tax ? tax.text : '' };\n}\n\nfunction simpleSig(str) {\n  let h = 5381;\n  for (let i = 0; i < str.length; i++) { h = ((h << 5) + h + str.charCodeAt(i)) | 0; }\n  return (h >>> 0).toString(36);\n}\n\nfunction runQA(profile) {\n  state.mode = 'ceo';\n  state.qaMode = true;\n  state.respondent = { name: 'QA ' + String(profile).toUpperCase(), email: '', role: 'QA', company: 'QA Test Co', revenue: '20-50m', industry: 'technology', size: '101-300' };\n  if (profile === 'low') {\n    state.answers = Array(25).fill(1).concat(Array(10).fill(0));\n  } else if (profile === 'high') {\n    state.answers = Array(25).fill(5).concat(Array(10).fill(2));\n  } else {\n    const cf = []; for (let i = 0; i < 25; i++) cf.push(i % 2 ? 5 : 1);\n    const dr = []; for (let i = 0; i < 10; i++) dr.push(i % 3);\n    state.answers = cf.concat(dr);\n  }\n  showResults();\n}\n\n\/\/ ===== UTILITIES =====\n\/\/ ===== UTILITIES =====\nfunction getStore() {\n  try {\n    const data = localStorage.getItem('ris_v2_data');\n    return data ? JSON.parse(data) : { results: [], sessions: [] };\n  } catch (e) {\n    return { results: [], sessions: [] };\n  }\n}\n\nfunction saveStore(data) {\n  try {\n    localStorage.setItem('ris_v2_data', JSON.stringify(data));\n  } catch (e) {\n    console.error('Storage error', e);\n  }\n}\n\nfunction generateSessionId() {\n  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';\n  let id = 'RIS-';\n  for (let i = 0; i < 12; i++) {\n    id += chars.charAt(Math.floor(Math.random() * chars.length));\n  }\n  return id;\n}\n\nfunction showToast(message, type = 'success') {\n  const container = document.getElementById('toastContainer');\n  const icon = type === 'success' ? '\u2713' : '\u26a0';\n  const toast = document.createElement('div');\n  toast.className = `toast ${type}`;\n  toast.innerHTML = `<span class=\"toast-icon\">${icon}<\/span><span>${message}<\/span>`;\n  container.appendChild(toast);\n  setTimeout(() => {\n    toast.style.animation = 'slideInRight 0.3s ease-out reverse';\n    setTimeout(() => toast.remove(), 300);\n  }, 3500);\n}\n\nfunction closeModal() {\n  document.getElementById('detailModal').classList.remove('active');\n}\n\n\/\/ ===== ROUTING & TAB MANAGEMENT =====\nfunction switchTab(tabName) {\n  document.querySelectorAll('.tab-btn').forEach(btn => btn.classList.remove('active'));\n  document.querySelector(`[data-tab=\"${tabName}\"]`).classList.add('active');\n  document.querySelectorAll('#app .screen').forEach(s => s.classList.remove('active'));\n\n  if (tabName === 'ceo') {\n    document.getElementById('ceoScreen').classList.add('active');\n  } else if (tabName === 'team') {\n    document.getElementById('teamScreen').classList.add('active');\n    checkTeamSession();\n  } else if (tabName === 'admin') {\n    if (state.isAdminLoggedIn) {\n      renderAdminDashboard();\n    } else {\n      showAdminLogin();\n    }\n  }\n}\n\nfunction showLanding() {\n  document.getElementById('landingScreen').style.display = 'flex';\n  document.getElementById('app').classList.remove('active');\n  document.getElementById('surveyContainer').style.display = 'none';\n  document.getElementById('resultsContainer').style.display = 'none';\n  document.getElementById('adminLoginContainer').style.display = 'none';\n  document.getElementById('adminDashboardContainer').style.display = 'none';\n}\n\nfunction showApp() {\n  document.getElementById('landingScreen').style.display = 'none';\n  document.getElementById('app').classList.add('active');\n  document.getElementById('surveyContainer').style.display = 'none';\n  document.getElementById('resultsContainer').style.display = 'none';\n  document.getElementById('adminLoginContainer').style.display = 'none';\n  document.getElementById('adminDashboardContainer').style.display = 'none';\n}\n\nfunction showSurvey() {\n  document.getElementById('landingScreen').style.display = 'none';\n  document.getElementById('app').classList.remove('active');\n  document.getElementById('surveyContainer').style.display = 'flex';\n  document.getElementById('resultsContainer').style.display = 'none';\n  document.getElementById('adminLoginContainer').style.display = 'none';\n  document.getElementById('adminDashboardContainer').style.display = 'none';\n  renderQuestion();\n}\n\nfunction showResults() {\n  document.getElementById('landingScreen').style.display = 'none';\n  document.getElementById('app').classList.remove('active');\n  document.getElementById('surveyContainer').style.display = 'none';\n  document.getElementById('resultsContainer').style.display = 'flex';\n  document.getElementById('adminLoginContainer').style.display = 'none';\n  document.getElementById('adminDashboardContainer').style.display = 'none';\n  renderResults();\n}\n\nfunction showAdminLogin() {\n  document.getElementById('landingScreen').style.display = 'none';\n  document.getElementById('app').classList.remove('active');\n  document.getElementById('surveyContainer').style.display = 'none';\n  document.getElementById('resultsContainer').style.display = 'none';\n  document.getElementById('adminLoginContainer').style.display = 'flex';\n  document.getElementById('adminDashboardContainer').style.display = 'none';\n}\n\nfunction showAdminDashboard() {\n  document.getElementById('landingScreen').style.display = 'none';\n  document.getElementById('app').classList.remove('active');\n  document.getElementById('surveyContainer').style.display = 'none';\n  document.getElementById('resultsContainer').style.display = 'none';\n  document.getElementById('adminLoginContainer').style.display = 'none';\n  document.getElementById('adminDashboardContainer').style.display = 'flex';\n}\n\n\/\/ ===== CEO DIAGNOSTIC FLOW =====\nfunction startCEODiagnostic() {\n  const form = document.getElementById('ceoIntakeForm');\n  if (!form.checkValidity()) {\n    form.reportValidity();\n    return;\n  }\n\n  state.mode = 'ceo';\n  state.respondent = {\n    name: document.getElementById('ceoName').value,\n    email: document.getElementById('ceoEmail').value,\n    role: document.getElementById('ceoRole').value,\n    company: document.getElementById('ceoCompany').value,\n    revenue: document.getElementById('ceoRevenue').value,\n    industry: document.getElementById('ceoIndustry').value,\n    size: document.getElementById('ceoEmployees').value\n  };\n  state.currentQuestion = 0;\n  state.answers = new Array(35).fill(null);\n  showSurvey();\n}\n\n\/\/ ===== TEAM SURVEY FLOW =====\nfunction checkTeamSession() {\n  const params = new URLSearchParams(window.location.search);\n  const sessionId = params.get('session');\n  const company = params.get('company');\n  const leader = params.get('leader');\n  const exp = params.get('exp');\n  const sig = params.get('sig');\n\n  if (!sessionId || !company) return;\n\n  let valid = false;\n  if (exp && sig) {\n    \/\/ Signed portable link \u2014 works on any device, no local storage required.\n    const expected = simpleSig(sessionId + '|' + exp + '|' + SIG_SALT);\n    valid = (sig === expected) && (Date.now() < parseInt(exp, 10));\n  } else {\n    \/\/ Legacy links: fall back to local session store (same-device only).\n    const store = getStore();\n    const session = store.sessions.find(s => s.id === sessionId);\n    valid = !!(session && new Date(session.expiresAt) > new Date());\n  }\n\n  const statusEl = document.getElementById('sessionStatus');\n  if (valid) {\n    statusEl.style.display = 'block';\n    document.getElementById('teamCompany').value = decodeURIComponent(company);\n    document.getElementById('startTeamBtn').disabled = false;\n    state.session = { id: sessionId, company: decodeURIComponent(company), leaderName: leader ? decodeURIComponent(leader) : '' };\n  } else {\n    statusEl.style.display = 'block';\n    statusEl.innerHTML = '<div style=\"color: #dc4a39; font-weight: 600;\">\u23f0 This session link has expired or is invalid. Ask your leader for a fresh link.<\/div>';\n    document.getElementById('startTeamBtn').disabled = true;\n  }\n}\n\nfunction startTeamDiagnostic() {\n  const role = document.getElementById('teamRole').value.trim();\n  if (!role) {\n    showToast('Please enter your role', 'error');\n    return;\n  }\n\n  const teamEmail = document.getElementById('teamEmail').value.trim();\n  if (!teamEmail || !teamEmail.includes('@')) {\n    showToast('Please enter a valid email', 'error');\n    return;\n  }\n\n  state.mode = 'team';\n  state.respondent = {\n    name: 'Team Member',\n    email: teamEmail,\n    role: role,\n    company: document.getElementById('teamCompany').value\n  };\n  state.currentQuestion = 0;\n  state.answers = new Array(35).fill(null);\n  showSurvey();\n}\n\n\/\/ ===== SURVEY RENDERING & LOGIC =====\nfunction getAllQuestions() {\n  if (state.mode === 'team') return [...TEAM_CF_QUESTIONS, ...TEAM_DRAG_QUESTIONS];\n  return [...CF_QUESTIONS, ...DRAG_QUESTIONS];\n}\n\nfunction isPartOne(questionIndex) {\n  return questionIndex < 25;\n}\n\nfunction renderQuestion() {\n  const allQuestions = getAllQuestions();\n  const q = allQuestions[state.currentQuestion];\n  const isScale = isPartOne(state.currentQuestion);\n\n  const part = isScale ? 'Part 1 \u00b7 Cultural Friction' : 'Part 2 \u00b7 CEO Drag';\n  const qNum = isScale ? (state.currentQuestion + 1) : (state.currentQuestion - 24);\n  const qTotal = isScale ? 25 : 10;\n\n  document.getElementById('progressLabel').innerHTML = `${part} \u2014 Question ${qNum} of ${qTotal}`;\n  document.getElementById('zonePill').textContent = q.zone || 'CEO Drag';\n  document.getElementById('zonePill').className = isScale ? 'zone-pill cf' : 'zone-pill drag';\n  document.getElementById('questionCounter').textContent = `Question ${state.currentQuestion + 1} of 35`;\n  document.getElementById('questionText').innerHTML = q.text;\n\n  const progress = ((state.currentQuestion + 1) \/ 35) * 100;\n  document.getElementById('progressFill').style.width = progress + '%';\n\n  const answerGrid = document.getElementById('answerGrid');\n  answerGrid.innerHTML = '';\n\n  if (isScale) {\n    const scaleButtons = document.createElement('div');\n    scaleButtons.className = 'scale-buttons';\n    for (let i = 1; i <= 5; i++) {\n      const btn = document.createElement('button');\n      btn.type = 'button';\n      btn.className = `btn btn-circle ${state.answers[state.currentQuestion] === i ? 'btn-primary' : 'btn-secondary'}`;\n      btn.textContent = i;\n      btn.onclick = () => selectScale(i);\n      scaleButtons.appendChild(btn);\n    }\n    answerGrid.appendChild(scaleButtons);\n\n    const labels = document.createElement('div');\n    labels.style.display = 'flex';\n    labels.style.justifyContent = 'space-between';\n    labels.style.marginTop = '12px';\n    labels.innerHTML = `\n      <span class=\"scale-label left\">1 = Strongly Agree \u2014 true of us<\/span>\n      <span class=\"scale-label center\">3 = Neutral<\/span>\n      <span class=\"scale-label right\">5 = Strongly Disagree \u2014 not true of us<\/span>\n    `;\n    answerGrid.appendChild(labels);\n  } else {\n    const optionBtns = document.createElement('div');\n    optionBtns.className = 'option-buttons';\n    q.options.forEach((opt, idx) => {\n      const btn = document.createElement('button');\n      btn.type = 'button';\n      btn.className = `option-btn ${state.answers[state.currentQuestion] === idx ? 'selected' : ''}`;\n      btn.innerHTML = `<span class=\"option-radio\"><\/span><span>${opt.text}<\/span>`;\n      btn.onclick = () => selectOption(idx);\n      optionBtns.appendChild(btn);\n    });\n    answerGrid.appendChild(optionBtns);\n  }\n\n  document.getElementById('backBtn').style.display = state.currentQuestion === 0 ? 'none' : 'block';\n  const nextBtn = document.getElementById('nextBtn');\n  nextBtn.textContent = state.currentQuestion === 34 ? 'Generate My Report \u2192' : 'Next \u2192';\n  nextBtn.disabled = state.answers[state.currentQuestion] === null;\n}\n\nfunction selectScale(value) {\n  state.answers[state.currentQuestion] = value;\n  document.getElementById('nextBtn').disabled = false;\n\n  setTimeout(() => {\n    nextQuestion();\n  }, 320);\n}\n\nfunction selectOption(index) {\n  state.answers[state.currentQuestion] = index;\n  document.getElementById('nextBtn').disabled = false;\n  renderQuestion();\n}\n\nfunction nextQuestion() {\n  if (state.currentQuestion < 34) {\n    state.currentQuestion++;\n    renderQuestion();\n  } else {\n    showResults();\n  }\n}\n\nfunction previousQuestion() {\n  if (state.currentQuestion > 0) {\n    state.currentQuestion--;\n    renderQuestion();\n  }\n}\n\n\/\/ ===== SCORING =====\nfunction calculateScores() {\n  const qSet = state.mode === 'team' ? TEAM_CF_QUESTIONS : CF_QUESTIONS;\n  const dSet = state.mode === 'team' ? TEAM_DRAG_QUESTIONS : DRAG_QUESTIONS;\n\n  const cfRaw = state.answers.slice(0, 25);\n  \/\/ Reverse-keyed items: agreement means friction, so the scale inverts (6 - answer).\n  const cfAnswers = cfRaw.map((a, i) => (a === null || a === undefined) ? 0 : (qSet[i].reverse ? 6 - a : a));\n  const cfTotal = cfAnswers.reduce((sum, a) => sum + a, 0);\n\n  const zones = [\n    { name: 'Alignment', indices: [0, 1, 2, 3, 4] },\n    { name: 'Decision', indices: [5, 6, 7, 8, 9] },\n    { name: 'Accountability', indices: [10, 11, 12, 13, 14] },\n    { name: 'Talent', indices: [15, 16, 17, 18, 19] },\n    { name: 'Culture', indices: [20, 21, 22, 23, 24] }\n  ];\n\n  const zoneScores = {};\n  zones.forEach(z => {\n    zoneScores[z.name.toLowerCase()] = z.indices.reduce((sum, i) => sum + (cfAnswers[i] || 0), 0);\n  });\n\n  const dragAnswers = state.answers.slice(25, 35);\n  let dragTotal = 0;\n  for (let i = 0; i < dragAnswers.length; i++) {\n    if (dragAnswers[i] !== null && dragAnswers[i] !== undefined) {\n      dragTotal += dSet[i].options[dragAnswers[i]].score;\n    }\n  }\n\n  return {\n    cf: { total: cfTotal, zoneScores: zoneScores },\n    drag: { total: dragTotal },\n    dragAnswers: dragAnswers\n  };\n}\n\nfunction getCFLevel(total) {\n  if (total <= 50) return { name: 'Friction-Free', color: 'green', summary: 'Your leadership culture is operating with exceptional alignment and courage. A rare result \u2014 protect and codify it.' };\n  if (total <= 75) return { name: 'Low Friction', color: 'green', summary: 'Strong alignment with manageable friction. Targeted improvements in your highest-scoring zones will compound over time.' };\n  if (total <= 95) return { name: 'Friction Zone', color: 'gold', summary: 'Noticeable cultural friction is quietly taxing execution. Leadership gaps in key zones need deliberate attention now.' };\n  if (total <= 110) return { name: 'Friction Tax', color: 'orange', summary: 'Cultural friction is actively draining growth capacity. The patterns are systemic \u2014 intervention required, not incremental improvement.' };\n  return { name: 'High Friction', color: 'red', summary: 'Critical leadership friction across multiple zones. Execution is compromised. This requires immediate, structured intervention.' };\n}\n\nfunction getDragLevel(total) {\n  if (total <= 4) return { name: 'Clear Leader', color: 'green', summary: 'You are operating with strong delegation and low personal drag. The company can run and grow without you as the bottleneck.' };\n  if (total <= 9) return { name: 'Friction Zone', color: 'gold', summary: 'Some personal operational drag is taxing your leadership capacity. Identifiable areas where you are still the constraint.' };\n  if (total <= 14) return { name: 'Bottleneck Risk', color: 'orange', summary: 'You are a meaningful constraint on company growth. Decision dependency, operational involvement, or both are limiting execution.' };\n  return { name: 'Full Drag', color: 'red', summary: 'The company is running you. Structural CEO dependency is actively capping scale. This requires decisive, immediate delegation work.' };\n}\n\nfunction getCombinedRead(cfLevel, dragLevel) {\n  const cf = cfLevel.name;\n  const drag = dragLevel.name;\n\n  if ((cf.includes('High') || cf.includes('Tax')) && (drag.includes('Full') || drag.includes('Bottleneck') || drag.includes('Friction Zone'))) {\n    return 'Both the culture and the CEO are creating significant drag. Structural intervention is required \u2014 the organisation cannot outgrow its leadership constraints at this level.';\n  }\n  if ((cf.includes('High') || cf.includes('Tax')) && (drag.includes('Clear'))) {\n    return 'The culture carries significant friction, but you as a leader have strong delegation capacity. The opportunity is to apply that discipline systemically across the team.';\n  }\n  if ((cf.includes('Low') || cf.includes('Friction-Free')) && (drag.includes('Full') || drag.includes('Bottleneck'))) {\n    return 'The culture is relatively healthy, but the CEO is the constraint. The organisation has the talent \u2014 freeing it from operational dependency is the single highest-leverage move.';\n  }\n  return 'Both scores indicate a leadership environment with strong execution capacity and low drag. The priority is sustaining standards as the business scales.';\n}\n\n\/\/ ===== RESULTS RENDERING =====\nfunction renderResults() {\n  const scores = calculateScores();\n  const cfLevel = getCFLevel(scores.cf.total);\n  const dragLevel = getDragLevel(scores.drag.total);\n  const combinedRead = getCombinedRead(cfLevel, dragLevel);\n\n  const header = document.getElementById('resultsHeader');\n  header.innerHTML = `\n    <h1 class=\"results-title\">${state.respondent.name}'s Leadership Report<\/h1>\n    <div class=\"results-subtitle\">${state.respondent.company} \u00b7 ${state.respondent.role}<\/div>\n    <div class=\"results-meta\">\n      <span>${new Date().toLocaleDateString()}<\/span>\n      <span>${state.mode === 'ceo' ? 'CEO Diagnostic' : 'Team Survey'}<\/span>\n    <\/div>\n  `;\n\n  const content = document.getElementById('resultsContent');\n  content.innerHTML = '';\n\n  \/\/ CF Score\n  const cfSection = document.createElement('div');\n  cfSection.className = 'results-section';\n  cfSection.innerHTML = `\n    <div class=\"score-card\">\n      <div class=\"score-visualization\">\n        <svg viewBox=\"0 0 200 200\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n          <circle cx=\"100\" cy=\"100\" r=\"90\" fill=\"none\" stroke=\"var(--bg-primary)\" stroke-width=\"8\"\/>\n          <circle cx=\"100\" cy=\"100\" r=\"90\" fill=\"none\" stroke=\"url(#goldGrad)\" stroke-width=\"8\" stroke-dasharray=\"${(scores.cf.total \/ 125) * 565} 565\" stroke-linecap=\"round\" transform=\"rotate(-90 100 100)\"\/>\n          <defs>\n            <linearGradient id=\"goldGrad\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n              <stop offset=\"0%\" style=\"stop-color:var(--accent-gold);stop-opacity:1\" \/>\n              <stop offset=\"100%\" style=\"stop-color:var(--accent-gold-light);stop-opacity:1\" \/>\n            <\/linearGradient>\n          <\/defs>\n          <text x=\"100\" y=\"95\" text-anchor=\"middle\" font-size=\"32\" fill=\"var(--accent-gold)\" font-weight=\"bold\">${scores.cf.total}<\/text>\n          <text x=\"100\" y=\"115\" text-anchor=\"middle\" font-size=\"12\" fill=\"var(--text-muted)\">\/125<\/text>\n        <\/svg>\n      <\/div>\n      <div class=\"score-level-badge level-${cfLevel.color}\">${cfLevel.name}<\/div>\n      <h3 style=\"margin-bottom: 12px;\">${cfLevel.name}<\/h3>\n      <div class=\"score-summary\">${cfLevel.summary}<\/div>\n\n      <h4 style=\"margin-top: 32px; margin-bottom: 16px; font-size: 16px;\">Zone Breakdown<\/h4>\n      <div class=\"zone-breakdown\">\n        <div class=\"zone-card\">\n          <div class=\"zone-name\">Leadership Alignment<\/div>\n          <div class=\"zone-score\">\n            <span>${scores.cf.zoneScores.alignment}<\/span>\n            <span style=\"color: var(--text-muted);\">\/25<\/span>\n          <\/div>\n          <div class=\"zone-bar\">\n            <div class=\"zone-bar-fill\" style=\"width: ${(scores.cf.zoneScores.alignment \/ 25) * 100}%\"><\/div>\n          <\/div>\n        <\/div>\n        <div class=\"zone-card\">\n          <div class=\"zone-name\">Decision & Execution<\/div>\n          <div class=\"zone-score\">\n            <span>${scores.cf.zoneScores.decision}<\/span>\n            <span style=\"color: var(--text-muted);\">\/25<\/span>\n          <\/div>\n          <div class=\"zone-bar\">\n            <div class=\"zone-bar-fill\" style=\"width: ${(scores.cf.zoneScores.decision \/ 25) * 100}%\"><\/div>\n          <\/div>\n        <\/div>\n        <div class=\"zone-card\">\n          <div class=\"zone-name\">Accountability Rigor<\/div>\n          <div class=\"zone-score\">\n            <span>${scores.cf.zoneScores.accountability}<\/span>\n            <span style=\"color: var(--text-muted);\">\/25<\/span>\n          <\/div>\n          <div class=\"zone-bar\">\n            <div class=\"zone-bar-fill\" style=\"width: ${(scores.cf.zoneScores.accountability \/ 25) * 100}%\"><\/div>\n          <\/div>\n        <\/div>\n        <div class=\"zone-card\">\n          <div class=\"zone-name\">Talent Density<\/div>\n          <div class=\"zone-score\">\n            <span>${scores.cf.zoneScores.talent}<\/span>\n            <span style=\"color: var(--text-muted);\">\/25<\/span>\n          <\/div>\n          <div class=\"zone-bar\">\n            <div class=\"zone-bar-fill\" style=\"width: ${(scores.cf.zoneScores.talent \/ 25) * 100}%\"><\/div>\n          <\/div>\n        <\/div>\n        <div class=\"zone-card\">\n          <div class=\"zone-name\">Leadership Courage<\/div>\n          <div class=\"zone-score\">\n            <span>${scores.cf.zoneScores.culture}<\/span>\n            <span style=\"color: var(--text-muted);\">\/25<\/span>\n          <\/div>\n          <div class=\"zone-bar\">\n            <div class=\"zone-bar-fill\" style=\"width: ${(scores.cf.zoneScores.culture \/ 25) * 100}%\"><\/div>\n          <\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n  `;\n  content.appendChild(cfSection);\n\n  \/\/ Drag Score\n  const dragSection = document.createElement('div');\n  dragSection.className = 'results-section';\n  dragSection.innerHTML = `\n    <div class=\"score-card\">\n      <div class=\"score-visualization\">\n        <svg viewBox=\"0 0 200 200\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n          <circle cx=\"100\" cy=\"100\" r=\"90\" fill=\"none\" stroke=\"var(--bg-primary)\" stroke-width=\"8\"\/>\n          <circle cx=\"100\" cy=\"100\" r=\"90\" fill=\"none\" stroke=\"#dc4a39\" stroke-width=\"8\" stroke-dasharray=\"${(scores.drag.total \/ 20) * 565} 565\" stroke-linecap=\"round\" transform=\"rotate(-90 100 100)\"\/>\n          <text x=\"100\" y=\"95\" text-anchor=\"middle\" font-size=\"32\" fill=\"#dc4a39\" font-weight=\"bold\">${scores.drag.total}<\/text>\n          <text x=\"100\" y=\"115\" text-anchor=\"middle\" font-size=\"12\" fill=\"var(--text-muted)\">\/20<\/text>\n        <\/svg>\n      <\/div>\n      <div class=\"score-level-badge level-${dragLevel.color}\">${dragLevel.name}<\/div>\n      <h3 style=\"margin-bottom: 12px;\">${dragLevel.name}<\/h3>\n      <div class=\"score-summary\">${dragLevel.summary}<\/div>\n    <\/div>\n  `;\n  content.appendChild(dragSection);\n\n  \/\/ Combined Read\n  const combined = document.createElement('div');\n  combined.className = 'results-section';\n  combined.innerHTML = `\n    <div class=\"combined-read\">\n      <div class=\"combined-read-title\">Your Read<\/div>\n      <p>${combinedRead}<\/p>\n    <\/div>\n  `;\n  content.appendChild(combined);\n\n  \/\/ Tailored recommendations (generated from this respondent's specific answers)\n  const rec = buildRecommendations(scores);\n  const recSection = document.createElement('div');\n  recSection.className = 'results-section';\n  recSection.innerHTML = rec.html;\n  content.appendChild(recSection);\n\n  \/\/ Email confirmation\n  const email = document.createElement('div');\n  email.className = 'email-confirmation';\n  email.innerHTML = state.mode === 'ceo' && state.respondent.email\n    ? `\ud83d\udce7 Your full report has been sent to <strong>${state.respondent.email}<\/strong>`\n    : `\u2705 Your submission has been recorded. Thank you for your honesty.`;\n  content.appendChild(email);\n\n  \/\/ Another diagnostic button\n  const another = document.createElement('div');\n  another.style.textAlign = 'center';\n  another.innerHTML = '<button class=\"btn btn-primary\" onclick=\"showLanding()\">Take Another Diagnostic<\/button>';\n  content.appendChild(another);\n\n  \/\/ Save result\n  if (!state.qaMode) saveResult(scores, cfLevel, dragLevel);\n\n  \/\/ Send emails\n  if (!state.qaMode) sendResultEmails(scores, cfLevel, dragLevel, combinedRead, rec);\n}\n\nfunction saveResult(scores, cfLevel, dragLevel) {\n  const store = getStore();\n  const result = {\n    id: generateSessionId(),\n    timestamp: new Date().toISOString(),\n    mode: state.mode,\n    respondent: state.respondent,\n    session: state.session,\n    answers: state.answers,\n    cf: {\n      total: scores.cf.total,\n      level: cfLevel.name,\n      color: cfLevel.color,\n      summary: cfLevel.summary,\n      zoneScores: scores.cf.zoneScores\n    },\n    drag: {\n      total: scores.drag.total,\n      level: dragLevel.name,\n      color: dragLevel.color,\n      summary: dragLevel.summary\n    }\n  };\n\n  store.results.push(result);\n  if (state.session) {\n    const session = store.sessions.find(s => s.id === state.session.id);\n    if (session) session.completions = (session.completions || 0) + 1;\n  }\n  saveStore(store);\n}\n\n\/\/ ===== EMAIL SENDING =====\nfunction sendResultEmails(scores, cfLevel, dragLevel, combinedRead, rec) {\n  const zoneList = Object.entries(scores.cf.zoneScores).map(([k, v]) => `${k}: ${v}\/25`).join('\\n');\n  const dragSet = state.mode === 'team' ? TEAM_DRAG_QUESTIONS : DRAG_QUESTIONS;\n  const dragResponses = state.answers.slice(25, 35).map((ansIdx, qIdx) => {\n    if (ansIdx !== null) return dragSet[qIdx].options[ansIdx].text;\n    return '';\n  }).join('\\n');\n\n  const params = {\n    name: state.respondent.name,\n    cf_answers: state.answers.slice(0, 25).join(','),\n    recommendations: rec ? rec.text : '',\n    friction_tax: rec && rec.taxText ? rec.taxText : '',\n    respondent_name: state.respondent.name,\n    respondent_role: state.respondent.role,\n    respondent_email: state.respondent.email,\n    company: state.respondent.company,\n    revenue: state.respondent.revenue || '',\n    industry: state.respondent.industry || '',\n    size: state.respondent.size || '',\n    session_id: state.session?.id || 'Direct',\n    timestamp: new Date().toLocaleString(),\n    cf_total: scores.cf.total,\n    cf_level: cfLevel.name,\n    cf_summary: cfLevel.summary,\n    zone_breakdown: zoneList,\n    drag_total: scores.drag.total,\n    drag_level: dragLevel.name,\n    drag_summary: dragLevel.summary,\n    drag_responses: dragResponses,\n    combined_read: combinedRead,\n    mode: state.mode\n  };\n\n  \/\/ Alert email to admin\n  if (CONFIG.email.serviceId !== 'YOUR_EMAILJS_SERVICE_ID') {\n    emailjs.send(CONFIG.email.serviceId, CONFIG.email.templateIdAlert, {\n      ...params,\n      to_email: CONFIG.email.adminEmail\n    }).catch(e => console.log('Alert email failed:', e));\n  }\n\n  \/\/ Results email to respondent\n  if (state.mode === 'ceo' && state.respondent.email && CONFIG.email.serviceId !== 'YOUR_EMAILJS_SERVICE_ID') {\n    emailjs.send(CONFIG.email.serviceId, CONFIG.email.templateIdResults, {\n      ...params,\n      to_email: state.respondent.email\n    }).catch(e => console.log('Results email failed:', e));\n  }\n\n  \/\/ Sync to Google Sheets\n  if (CONFIG.sheetsWebhook) {\n    fetch(CONFIG.sheetsWebhook, {\n      method: 'POST',\n      mode: 'no-cors',\n      body: JSON.stringify(params)\n    }).catch(e => console.log('Sheet sync failed:', e));\n  }\n}\n\n\/\/ ===== ADMIN FUNCTIONS =====\nfunction showAdminLogin() {\n  document.getElementById('adminLoginContainer').style.display = 'flex';\n}\n\nasync function sha256Hex(str) {\n  const buf = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(str));\n  return Array.from(new Uint8Array(buf)).map(b => b.toString(16).padStart(2, '0')).join('');\n}\n\nasync function adminLogin(e) {\n  e.preventDefault();\n  const username = document.getElementById('adminUsername').value;\n  const password = document.getElementById('adminPassword').value;\n  const hashes = await Promise.all([sha256Hex(username), sha256Hex(password)]);\n\n  if (hashes[0] === CONFIG.admin.userHash && hashes[1] === CONFIG.admin.passHash) {\n    state.isAdminLoggedIn = true;\n    sessionStorage.setItem('adminLogged', 'true');\n    showAdminDashboard();\n    renderAdminDashboard();\n  } else {\n    const errorEl = document.getElementById('adminError');\n    errorEl.textContent = 'Invalid credentials. Try again.';\n    errorEl.classList.add('show');\n  }\n}\n\nfunction adminLogout() {\n  state.isAdminLoggedIn = false;\n  sessionStorage.removeItem('adminLogged');\n  showLanding();\n}\n\nfunction renderAdminDashboard() {\n  const store = getStore();\n\n  \/\/ Stats\n  const now = new Date();\n  const activeCount = store.sessions.filter(s => new Date(s.expiresAt) > now).length;\n  const avgCF = store.results.length > 0 ? Math.round(store.results.reduce((sum, r) => sum + r.cf.total, 0) \/ store.results.length) : 0;\n  const todayCount = store.results.filter(r => new Date(r.timestamp).toDateString() === now.toDateString()).length;\n\n  const statsGrid = document.getElementById('statsGrid');\n  statsGrid.innerHTML = `\n    <div class=\"stat-card\">\n      <div class=\"stat-label\">Total Completions<\/div>\n      <div class=\"stat-value\">${store.results.length}<\/div>\n    <\/div>\n    <div class=\"stat-card\">\n      <div class=\"stat-label\">Active Sessions<\/div>\n      <div class=\"stat-value\">${activeCount}<\/div>\n    <\/div>\n    <div class=\"stat-card\">\n      <div class=\"stat-label\">Avg CF Score<\/div>\n      <div class=\"stat-value\">${avgCF}<\/div>\n    <\/div>\n    <div class=\"stat-card\">\n      <div class=\"stat-label\">Submitted Today<\/div>\n      <div class=\"stat-value\">${todayCount}<\/div>\n    <\/div>\n  `;\n\n  \/\/ Sessions table\n  const sessionsTable = document.getElementById('sessionsTableContainer');\n  if (store.sessions.length === 0) {\n    sessionsTable.innerHTML = '<p style=\"color: var(--text-muted); text-align: center; padding: 40px 20px;\">No active sessions yet.<\/p>';\n  } else {\n    let html = `<table>\n      <thead>\n        <tr>\n          <th>Company<\/th>\n          <th>Leader<\/th>\n          <th>Created<\/th>\n          <th>Expires<\/th>\n          <th>Progress<\/th>\n          <th>Status<\/th>\n          <th>Actions<\/th>\n        <\/tr>\n      <\/thead>\n      <tbody>`;\n\n    store.sessions.forEach(s => {\n      const isActive = new Date(s.expiresAt) > now;\n      const status = isActive ? '<span class=\"badge badge-active\">Active<\/span>' : '<span class=\"badge badge-expired\">Expired<\/span>';\n      const completions = s.completions || 0;\n      const progress = s.teamSize ? Math.round((completions \/ s.teamSize) * 100) : 0;\n\n      html += `<tr>\n        <td>${s.company}<\/td>\n        <td>\n          <div>${s.leaderName}<\/div>\n          <div style=\"font-size: 12px; color: var(--text-muted);\">${s.leaderEmail}<\/div>\n        <\/td>\n        <td>${new Date(s.createdAt).toLocaleDateString()}<\/td>\n        <td>${new Date(s.expiresAt).toLocaleDateString()}<\/td>\n        <td>\n          <div style=\"font-size: 12px; color: var(--text-muted);\">${completions}\/${s.teamSize || '?'}<\/div>\n          <div class=\"progress-mini\">\n            <div class=\"progress-mini-fill\" style=\"width: ${progress}%\"><\/div>\n          <\/div>\n        <\/td>\n        <td>${status}<\/td>\n        <td>\n          <div class=\"table-actions\">\n            <button class=\"btn btn-secondary action-btn\" onclick=\"copySessLink('${s.id}')\">Copy<\/button>\n            <button class=\"btn btn-secondary action-btn\" onclick=\"deleteSession('${s.id}')\">Delete<\/button>\n          <\/div>\n        <\/td>\n      <\/tr>`;\n    });\n\n    html += '<\/tbody><\/table>';\n    sessionsTable.innerHTML = html;\n  }\n\n  \/\/ Results table\n  const resultsTable = document.getElementById('resultsTableContainer');\n  if (store.results.length === 0) {\n    resultsTable.innerHTML = '<p style=\"color: var(--text-muted); text-align: center; padding: 40px 20px;\">No results yet.<\/p>';\n  } else {\n    let html = `<table>\n      <thead>\n        <tr>\n          <th>Name \/ Role<\/th>\n          <th>Company<\/th>\n          <th>Date<\/th>\n          <th>CF Score<\/th>\n          <th>Drag Score<\/th>\n          <th>Level<\/th>\n          <th>Actions<\/th>\n        <\/tr>\n      <\/thead>\n      <tbody>`;\n\n    store.results.sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp)).forEach(r => {\n      html += `<tr>\n        <td>\n          <div>${r.respondent.name}<\/div>\n          <div style=\"font-size: 12px; color: var(--text-muted);\">${r.respondent.role}<\/div>\n        <\/td>\n        <td>${r.respondent.company}<\/td>\n        <td>${new Date(r.timestamp).toLocaleDateString()}<\/td>\n        <td>${r.cf.total}<\/td>\n        <td>${r.drag.total}<\/td>\n        <td><span class=\"badge level-${r.cf.color}\">${r.cf.level}<\/span><\/td>\n        <td><button class=\"btn btn-secondary action-btn\" onclick=\"showResultDetail('${r.id}')\">View<\/button><\/td>\n      <\/tr>`;\n    });\n\n    html += '<\/tbody><\/table>';\n    resultsTable.innerHTML = html;\n  }\n}\n\nfunction generateSessionLink(e) {\n  e.preventDefault();\n\n  const company = document.getElementById('sessionCompany').value;\n  const leader = document.getElementById('sessionLeader').value;\n  const email = document.getElementById('sessionLeaderEmail').value;\n  const phone = document.getElementById('sessionPhone').value;\n  const industry = document.getElementById('sessionIndustry').value;\n  const revenue = document.getElementById('sessionRevenue').value;\n  const teamSize = document.getElementById('sessionTeamSize').value;\n  const date = document.getElementById('sessionDate').value;\n\n  const sessionId = generateSessionId();\n  const now = new Date();\n  const expires = new Date(now.getTime() + 72 * 60 * 60 * 1000);\n\n  const store = getStore();\n  store.sessions.push({\n    id: sessionId,\n    company,\n    leaderName: leader,\n    leaderEmail: email,\n    phone,\n    industry,\n    revenue,\n    teamSize: parseInt(teamSize) || null,\n    sessionDate: date,\n    createdAt: now.toISOString(),\n    expiresAt: expires.toISOString(),\n    completions: 0\n  });\n  saveStore(store);\n\n  const linkExp = expires.getTime();\n  const url = `${CONFIG.appUrl}?session=${sessionId}&company=${encodeURIComponent(company)}&leader=${encodeURIComponent(leader)}&exp=${linkExp}&sig=${simpleSig(sessionId + '|' + linkExp + '|' + SIG_SALT)}`;\n  document.getElementById('generatedSessionUrl').textContent = url;\n  document.getElementById('sessionGenerated').classList.add('show');\n\n  \/\/ Save current session for later email use\n  state.currentSessionUrl = url;\n  state.currentSessionEmail = email;\n\n  showToast('Session link generated successfully');\n  renderAdminDashboard();\n}\n\nfunction copySessionLink() {\n  const url = document.getElementById('generatedSessionUrl').textContent;\n  navigator.clipboard.writeText(url).then(() => showToast('Link copied'));\n}\n\nfunction emailSessionLink() {\n  const url = document.getElementById('generatedSessionUrl').textContent;\n  const email = state.currentSessionEmail;\n\n  if (CONFIG.email.serviceId !== 'YOUR_EMAILJS_SERVICE_ID') {\n    emailjs.send(CONFIG.email.serviceId, CONFIG.email.templateIdLeader, {\n      to_email: email,\n      session_url: url,\n      company: document.getElementById('sessionCompany').value\n    }).then(() => {\n      showToast('Email sent successfully');\n    }).catch(() => {\n      showToast('Failed to send email', 'error');\n    });\n  }\n}\n\nfunction copySessLink(sessionId) {\n  const store = getStore();\n  const session = store.sessions.find(s => s.id === sessionId);\n  if (session) {\n    const linkExp = new Date(session.expiresAt).getTime();\n    const url = `${CONFIG.appUrl}?session=${sessionId}&company=${encodeURIComponent(session.company)}&leader=${encodeURIComponent(session.leaderName)}&exp=${linkExp}&sig=${simpleSig(sessionId + '|' + linkExp + '|' + SIG_SALT)}`;\n    navigator.clipboard.writeText(url).then(() => showToast('Link copied'));\n  }\n}\n\nfunction deleteSession(sessionId) {\n  if (confirm('Delete this session?')) {\n    const store = getStore();\n    store.sessions = store.sessions.filter(s => s.id !== sessionId);\n    saveStore(store);\n    renderAdminDashboard();\n    showToast('Session deleted');\n  }\n}\n\nfunction showResultDetail(resultId) {\n  const store = getStore();\n  const result = store.results.find(r => r.id === resultId);\n  if (!result) return;\n\n  const cfLevel = getCFLevel(result.cf.total);\n  const dragLevel = getDragLevel(result.drag.total);\n\n  const html = `\n    <div class=\"modal-header\">\n      <h2 class=\"modal-title\">${result.respondent.name}<\/h2>\n      <button class=\"modal-close\" onclick=\"closeModal()\">\u00d7<\/button>\n    <\/div>\n\n    <div style=\"margin-bottom: 24px;\">\n      <div style=\"font-size: 12px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 4px;\">Details<\/div>\n      <div style=\"font-size: 14px;\">${result.respondent.role} at ${result.respondent.company}<\/div>\n      <div style=\"font-size: 12px; color: var(--text-muted);\">${new Date(result.timestamp).toLocaleString()}<\/div>\n    <\/div>\n\n    <div style=\"margin-bottom: 32px;\">\n      <h3 style=\"margin-bottom: 16px;\">Cultural Friction<\/h3>\n      <div style=\"display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 16px;\">\n        <div style=\"background: var(--bg-primary); border: 1px solid var(--border-light); border-radius: 12px; padding: 16px; text-align: center;\">\n          <div style=\"font-size: 28px; color: var(--accent-gold); font-weight: 600;\">${result.cf.total}<\/div>\n          <div style=\"font-size: 12px; color: var(--text-muted);\">\/125<\/div>\n        <\/div>\n        <div style=\"background: var(--bg-primary); border: 1px solid var(--border-light); border-radius: 12px; padding: 16px; text-align: center;\">\n          <div class=\"score-level-badge level-${result.cf.color}\" style=\"display: inline-block;\">${result.cf.level}<\/div>\n        <\/div>\n      <\/div>\n      <div style=\"background: var(--bg-primary); border: 1px solid var(--border-light); border-radius: 12px; padding: 16px; font-size: 14px; line-height: 1.6; color: var(--text-muted);\">${result.cf.summary}<\/div>\n    <\/div>\n\n    <div style=\"margin-bottom: 32px;\">\n      <h3 style=\"margin-bottom: 16px;\">Zone Breakdown<\/h3>\n      <table style=\"width: 100%; font-size: 14px;\">\n        <tr>\n          <td style=\"border-bottom: 1px solid var(--border-light); padding: 12px 0;\">Leadership Alignment<\/td>\n          <td style=\"border-bottom: 1px solid var(--border-light); padding: 12px 0; text-align: right; color: var(--accent-gold);\">${result.cf.zoneScores.alignment}\/25<\/td>\n        <\/tr>\n        <tr>\n          <td style=\"border-bottom: 1px solid var(--border-light); padding: 12px 0;\">Decision & Execution<\/td>\n          <td style=\"border-bottom: 1px solid var(--border-light); padding: 12px 0; text-align: right; color: var(--accent-gold);\">${result.cf.zoneScores.decision}\/25<\/td>\n        <\/tr>\n        <tr>\n          <td style=\"border-bottom: 1px solid var(--border-light); padding: 12px 0;\">Accountability Rigor<\/td>\n          <td style=\"border-bottom: 1px solid var(--border-light); padding: 12px 0; text-align: right; color: var(--accent-gold);\">${result.cf.zoneScores.accountability}\/25<\/td>\n        <\/tr>\n        <tr>\n          <td style=\"border-bottom: 1px solid var(--border-light); padding: 12px 0;\">Talent Density<\/td>\n          <td style=\"border-bottom: 1px solid var(--border-light); padding: 12px 0; text-align: right; color: var(--accent-gold);\">${result.cf.zoneScores.talent}\/25<\/td>\n        <\/tr>\n        <tr>\n          <td style=\"padding: 12px 0;\">Leadership Courage<\/td>\n          <td style=\"padding: 12px 0; text-align: right; color: var(--accent-gold);\">${result.cf.zoneScores.culture}\/25<\/td>\n        <\/tr>\n      <\/table>\n    <\/div>\n\n    <div>\n      <h3 style=\"margin-bottom: 16px;\">CEO Drag<\/h3>\n      <div style=\"display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 16px;\">\n        <div style=\"background: var(--bg-primary); border: 1px solid var(--border-light); border-radius: 12px; padding: 16px; text-align: center;\">\n          <div style=\"font-size: 28px; color: #dc4a39; font-weight: 600;\">${result.drag.total}<\/div>\n          <div style=\"font-size: 12px; color: var(--text-muted);\">\/20<\/div>\n        <\/div>\n        <div style=\"background: var(--bg-primary); border: 1px solid var(--border-light); border-radius: 12px; padding: 16px; text-align: center;\">\n          <div class=\"score-level-badge level-${result.drag.color}\" style=\"display: inline-block;\">${result.drag.level}<\/div>\n        <\/div>\n      <\/div>\n      <div style=\"background: var(--bg-primary); border: 1px solid var(--border-light); border-radius: 12px; padding: 16px; font-size: 14px; line-height: 1.6; color: var(--text-muted);\">${result.drag.summary}<\/div>\n    <\/div>\n  `;\n\n  document.getElementById('modalContent').innerHTML = html;\n  document.getElementById('detailModal').classList.add('active');\n}\n\nfunction exportCSV() {\n  const store = getStore();\n  const headers = ['Date', 'Name', 'Role', 'Email', 'Company', 'Revenue', 'Industry', 'Employees', 'Mode', 'Session ID', 'CF Total', 'CF Level', 'Zone Alignment', 'Zone Decision', 'Zone Accountability', 'Zone Talent', 'Zone Culture', 'Drag Total', 'Drag Level'];\n\n  let csv = headers.join(',') + '\\n';\n  store.results.forEach(r => {\n    const row = [\n      new Date(r.timestamp).toLocaleDateString(),\n      `\"${r.respondent.name}\"`,\n      `\"${r.respondent.role}\"`,\n      r.respondent.email,\n      `\"${r.respondent.company}\"`,\n      r.respondent.revenue || '',\n      r.respondent.industry || '',\n      r.respondent.size || '',\n      r.mode,\n      r.session?.id || 'Direct',\n      r.cf.total,\n      r.cf.level,\n      r.cf.zoneScores.alignment,\n      r.cf.zoneScores.decision,\n      r.cf.zoneScores.accountability,\n      r.cf.zoneScores.talent,\n      r.cf.zoneScores.culture,\n      r.drag.total,\n      r.drag.level\n    ];\n    csv += row.join(',') + '\\n';\n  });\n\n  const blob = new Blob([csv], { type: 'text\/csv' });\n  const url = window.URL.createObjectURL(blob);\n  const a = document.createElement('a');\n  a.href = url;\n  a.download = `ris-friction-results-${new Date().toISOString().split('T')[0]}.csv`;\n  a.click();\n}\n\n\/\/ ===== INITIALIZATION =====\ndocument.addEventListener('DOMContentLoaded', () => {\n  \/\/ Tab switching\n  document.querySelectorAll('.tab-btn').forEach(btn => {\n    btn.addEventListener('click', () => switchTab(btn.dataset.tab));\n  });\n\n  \/\/ Check if admin logged in\n  if (sessionStorage.getItem('adminLogged')) {\n    state.isAdminLoggedIn = true;\n  }\n\n  \/\/ Check URL params\n  const params = new URLSearchParams(window.location.search);\n  if (params.has('qa')) {\n    runQA(params.get('qa'));\n    return;\n  }\n  if (params.has('session')) {\n    showApp();\n    document.querySelector('[data-tab=\"team\"]').click();\n  } else if (params.get('mode') === 'admin') {\n    if (state.isAdminLoggedIn) {\n      showAdminDashboard();\n      renderAdminDashboard();\n    } else {\n      showAdminLogin();\n    }\n  } else {\n    showLanding();\n  }\n});\n\ndocument.addEventListener('keypress', (e) => {\n  if (e.key === 'Enter' && document.getElementById('adminLoginForm') && document.activeElement.closest('#adminLoginForm')) {\n    adminLogin(e);\n  }\n});\n<\/script>\n\n<!--\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nSETUP INSTRUCTIONS\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n1. EMAILJS SETUP\n\n- Create a free EmailJS account at emailjs.com\n- Create 3 email templates:\n\n  TEMPLATE 1 (Alert Email to Admin)\n  Template Name: (anything, e.g., \"alert_template\")\n  Variables used: {{name}}, {{respondent_name}}, {{respondent_role}}, {{respondent_email}}, {{company}}, {{cf_total}}, {{cf_level}}, {{drag_total}}, {{drag_level}}, {{timestamp}}, {{recommendations}}, {{friction_tax}}, {{zone_breakdown}}, {{combined_read}}\n\n  TEMPLATE 2 (Results to Respondent - CEO Mode)\n  Template Name: (anything, e.g., \"results_template\")\n  Variables used: {{respondent_name}}, {{company}}, {{cf_total}}, {{cf_level}}, {{cf_summary}}, {{drag_total}}, {{drag_level}}, {{drag_summary}}, {{combined_read}}, {{recommendations}}, {{friction_tax}}, {{zone_breakdown}}\n\n  TEMPLATE 3 (Session Link to Leader)\n  Template Name: (anything, e.g., \"leader_template\")\n  Variables used: {{session_url}}, {{company}}\n\n- Copy your:\n  - Service ID (Account > Services)\n  - Public Key (Account > API Keys)\n  - Template IDs from each template\n\n- Update CONFIG object at top of this file:\n  CONFIG.email.serviceId = 'YOUR_SERVICE_ID'\n  CONFIG.email.templateIdAlert = 'ALERT_TEMPLATE_ID'\n  CONFIG.email.templateIdResults = 'RESULTS_TEMPLATE_ID'\n  CONFIG.email.templateIdLeader = 'LEADER_TEMPLATE_ID'\n  CONFIG.email.publicKey = 'YOUR_PUBLIC_KEY'\n\n2. ADMIN CREDENTIALS\n\n- Stored as SHA-256 hashes in CONFIG.admin (userHash \/ passHash) \u2014 no plaintext in this file.\n- To change: open the browser console on the app page and run:  await sha256Hex('newvalue')\n  then paste the resulting hex into userHash \/ passHash.\n\n3. GOOGLE SHEETS SYNC (Optional)\n\n- Create a new Google Apps Script project\n- Paste the code from the commented section at the end of this file into the editor\n- Deploy as web app (Execute as: your account, Who has access: Anyone)\n- Copy the deployment URL\n- Paste into CONFIG.sheetsWebhook = 'YOUR_WEBHOOK_URL'\n- Each submission will append a row to your sheet\n\n4. WORDPRESS EMBEDDING\n\n- Use the HTML\/Custom HTML widget\n- Paste this entire file content into the widget, OR\n- Use an iframe: <iframe src=\"path\/to\/ris-friction-suite.html\" width=\"100%\" height=\"800px\"><\/iframe>\n\n5. CUSTOMIZATION\n\n- Logo URL: Change the img src in the landing screen to your logo\n- App URL: CONFIG.appUrl auto-detects, but can be hardcoded to your domain\n- Accent color: Change --accent-gold in CSS (default #C9A84C)\n- Admin email for alerts: CONFIG.email.adminEmail\n\n6. TESTING\n\n- Open the file in a browser\n- Test CEO flow: Fill intake \u2192 answer questions \u2192 see results\n- Test team flow: Generate session link in admin \u2192 use URL param\n- Admin login: Click Admin tab, use credentials\n- Check localStorage in dev tools: Application > Local Storage > ris_v2_data\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nGOOGLE APPS SCRIPT CODE (Copy into Apps Script editor)\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nfunction doPost(e) {\n  const data = JSON.parse(e.postData.contents);\n  const sheet = SpreadsheetApp.getActiveSheet();\n\n  const row = [\n    data.timestamp,\n    data.respondent_name,\n    data.respondent_role,\n    data.respondent_email,\n    data.company,\n    data.revenue,\n    data.industry,\n    data.size,\n    data.mode,\n    data.session_id,\n    data.cf_total,\n    data.cf_level,\n    data.zone_breakdown,\n    data.drag_total,\n    data.drag_level,\n    data.drag_responses,\n    data.combined_read\n  ];\n\n  sheet.appendRow(row);\n\n  return ContentService.createTextOutput('OK');\n}\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n-->\n<\/body>\n<\/html>\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>RIS METHOD\u2122 \u00b7 Leadership Friction Autopsy\u2122<\/p>","protected":false},"author":1,"featured_media":1371,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_canvas","meta":{"_angie_page":false,"footnotes":""},"class_list":["post-1343","page","type-page","status-publish","has-post-thumbnail","hentry"],"blocksy_meta":[],"_hostinger_reach_plugin_has_subscription_block":false,"_hostinger_reach_plugin_is_elementor":false,"_links":{"self":[{"href":"https:\/\/rismethod.com\/fr\/wp-json\/wp\/v2\/pages\/1343","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rismethod.com\/fr\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/rismethod.com\/fr\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/rismethod.com\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rismethod.com\/fr\/wp-json\/wp\/v2\/comments?post=1343"}],"version-history":[{"count":35,"href":"https:\/\/rismethod.com\/fr\/wp-json\/wp\/v2\/pages\/1343\/revisions"}],"predecessor-version":[{"id":1449,"href":"https:\/\/rismethod.com\/fr\/wp-json\/wp\/v2\/pages\/1343\/revisions\/1449"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/rismethod.com\/fr\/wp-json\/wp\/v2\/media\/1371"}],"wp:attachment":[{"href":"https:\/\/rismethod.com\/fr\/wp-json\/wp\/v2\/media?parent=1343"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}