<!-- ═══ Prompts View ═══ -->
<div
  x-show="activeView === 'prompts'"
  x-cloak
  style="height: calc(100vh - 3.5rem); overflow-y: auto"
>
  <div style="max-width: 1100px; margin: 0 auto; padding: 20px 24px 24px">
    <div style="margin-bottom: 14px">
      <h2
        class="gf-text-primary"
        style="font-size: 18px; font-weight: 600; margin-bottom: 4px"
      >
        Prompts
      </h2>
      <p class="gf-text-muted" style="font-size: 14px; max-width: 760px">
        Ready-made prompts for goat-flow skills. Pick one, optionally add
        context, and launch it in the Runner selected above.
      </p>
    </div>

    <div style="position: relative; margin-bottom: 10px">
      <svg
        style="
          position: absolute;
          left: 14px;
          top: 50%;
          transform: translateY(-50%);
          color: var(--text-dim);
        "
        width="14"
        height="14"
        fill="none"
        stroke="currentColor"
        stroke-width="2"
        viewBox="0 0 24 24"
      >
        <path
          stroke-linecap="round"
          stroke-linejoin="round"
          d="M21 21l-4.35-4.35M11 19a8 8 0 100-16 8 8 0 000 16z"
        />
      </svg>
      <input
        x-model="presetSearch"
        x-ref="presetSearchInput"
        class="gf-input"
        style="
          width: 100%;
          box-sizing: border-box;
          padding: 9px 14px 9px 38px;
          border-radius: 6px;
          font-size: 14px;
        "
        placeholder="Search name, description, or prompt text..."
      />
    </div>

    <div
      style="
        display: flex;
        flex-wrap: wrap;
        gap: 6px;
        align-items: center;
        margin-bottom: 14px;
      "
    >
      <button
        @click="openNewCustomPrompt()"
        class="gf-btn gf-btn-sm gf-btn-primary"
      >
        New Custom
      </button>
      <button
        class="gf-btn gf-btn-sm"
        :style="presetFilter === 'favorites' ? { background: 'var(--accent-bg)', borderColor: 'var(--accent-border)', color: 'var(--accent)' } : {}"
        @click="presetFilter = 'favorites'"
      >
        ★ Favorites
        <span
          x-text="allPresets.filter(p => !p.qualityMode && !p.internalOnly && presetFavorites.includes(p.id)).length"
        ></span>
      </button>
      <template x-for="cat in presetCats" :key="'mock-cat-' + cat.id">
        <button
          x-show="cat.id !== 'favorites'"
          class="gf-btn gf-btn-sm"
          @click="presetFilter = cat.id"
          :style="presetFilter === cat.id
            ? { background: { all: 'var(--accent-bg)', debug: 'rgba(96,165,250,0.15)', review: 'rgba(45,212,191,0.15)', plan: 'rgba(251,191,36,0.15)', critique: 'rgba(167,139,250,0.15)', qa: 'rgba(244,114,182,0.15)', security: 'rgba(248,113,113,0.15)' }[cat.id] || 'rgba(148,163,184,0.08)',
                color: { all: 'var(--accent)', debug: '#60a5fa', review: '#2dd4bf', plan: '#fbbf24', critique: '#a78bfa', qa: '#f472b6', security: '#f87171' }[cat.id] || 'var(--text-primary)',
                borderColor: { all: 'var(--accent-border)', debug: 'rgba(96,165,250,0.3)', review: 'rgba(45,212,191,0.3)', plan: 'rgba(251,191,36,0.3)', critique: 'rgba(167,139,250,0.3)', qa: 'rgba(244,114,182,0.3)', security: 'rgba(248,113,113,0.3)' }[cat.id] || 'var(--border-default)' }
            : {}"
          x-text="cat.id === 'all' ? `All ${allPresets.filter(p => !p.qualityMode && !p.internalOnly).length}` : `${cat.label} ${allPresets.filter(p => p.cat === cat.id && !p.qualityMode && !p.internalOnly).length}`"
        ></button>
      </template>
    </div>

    <div
      class="gf-prompts-layout"
      style="
        display: grid;
        grid-template-columns: minmax(0, 290px) minmax(0, 1fr);
        gap: 12px;
      "
    >
      <!-- Left prompt list -->
      <div
        style="
          display: flex;
          flex-direction: column;
          gap: 6px;
          max-height: 680px;
          overflow-y: auto;
          padding-right: 4px;
        "
      >
        <template x-for="p in filteredPresets" :key="'mock-preset-' + p.id">
          <div
            @click="selectPreset(p)"
            class="gf-card gf-prompt-list-card"
            :style="{
	              ...(selectedPreset?.id === p.id ? { borderColor: 'var(--accent-border)', background: 'var(--accent-bg)' } : {}),
	              borderLeftColor: presetCategoryAccent(p)
	            }"
          >
            <button
              @click.stop="toggleFavorite(p.id)"
              class="gf-prompt-favorite"
              :style="isFavorite(p.id) ? { color: 'var(--amber-400)' } : {}"
              :title="isFavorite(p.id) ? 'Remove from favorites' : 'Add to favorites'"
              x-text="isFavorite(p.id) ? '★' : '☆'"
            ></button>
            <div class="gf-prompt-card-content">
              <div
                class="gf-text-primary gf-prompt-card-title"
                x-text="p.name"
              ></div>
              <p class="gf-text-muted gf-prompt-card-desc" x-text="p.desc"></p>
              <div class="gf-prompt-card-meta">
                <span
                  class="gf-text-secondary gf-prompt-route-chip"
                  x-text="presetRouteLabel(p)"
                ></span>
                <span
                  class="gf-text-muted gf-prompt-category-label"
                  x-text="p.cat"
                ></span>
                <template
                  x-for="badge in presetBadges(p).slice(0, 3)"
                  :key="p.id + '-' + badge.label"
                >
                  <span
                    :class="'gf-preset-badge gf-preset-badge-' + badge.tone"
                    :title="badge.title"
                    x-text="badge.label"
                  ></span>
                </template>
              </div>
            </div>
          </div>
        </template>
      </div>

      <!-- Right preview -->
      <div
        class="gf-card"
        style="padding: 18px 20px; min-width: 0"
        x-data="{ extraContext: '' }"
      >
        <template x-if="showCustomPromptEditor">
          <form
            class="gf-custom-prompt-form"
            novalidate
            @submit.prevent="saveCustomPrompt()"
          >
            <div class="gf-custom-form-head">
              <div>
                <div class="section-label">Custom prompt</div>
                <h3
                  class="gf-text-primary"
                  x-text="editingCustomPromptId ? 'Edit custom prompt' : 'New custom prompt'"
                ></h3>
              </div>
              <div class="gf-custom-form-head-actions">
                <div class="gf-start-picker">
                  <button
                    type="button"
                    class="gf-btn gf-btn-sm gf-btn-text gf-start-picker-trigger"
                    @click="showPromptStartPicker = !showPromptStartPicker"
                    aria-controls="custom-prompt-start-picker"
                    :aria-expanded="showPromptStartPicker ? 'true' : 'false'"
                  >
                    Start from existing prompt ▾
                  </button>
                  <div
                    x-show="showPromptStartPicker"
                    x-cloak
                    id="custom-prompt-start-picker"
                    class="gf-start-picker-panel"
                  >
                    <label class="sr-only" for="custom-prompt-start">
                      Existing prompt
                    </label>
                    <select
                      id="custom-prompt-start"
                      x-model="customPromptStartId"
                      class="gf-input"
                    >
                      <option value="">Choose a prompt...</option>
                      <template
                        x-for="p in allPresets.filter(p => !p.qualityMode && !p.internalOnly)"
                        :key="'start-' + p.id"
                      >
                        <option :value="p.id" x-text="p.name"></option>
                      </template>
                    </select>
                    <button
                      type="button"
                      class="gf-btn gf-btn-sm gf-btn-secondary"
                      @click="startCustomPromptFromPreset()"
                      :disabled="!customPromptStartId"
                    >
                      Use prompt
                    </button>
                  </div>
                </div>
                <div class="gf-custom-form-actions">
                  <button
                    type="button"
                    @click="cancelCustomPromptEdit()"
                    class="gf-btn gf-btn-md gf-btn-text"
                  >
                    Cancel
                  </button>
                  <button
                    type="submit"
                    class="gf-btn gf-btn-md gf-btn-secondary gf-custom-save-secondary"
                  >
                    Save
                  </button>
                  <button
                    type="button"
                    @click="saveAndRunCustomPrompt()"
                    :disabled="!activeRunner || launching || serverSessions.length >= serverMaxSessions"
                    :title="!activeRunner ? 'Select a runner before launching' : (serverSessions.length >= serverMaxSessions ? 'Maximum sessions reached' : '')"
                    class="gf-btn gf-btn-md gf-btn-primary gf-custom-run-primary"
                  >
                    Save and run with <span x-text="activeRunner"></span>
                  </button>
                </div>
              </div>
            </div>

            <div
              x-show="customPromptSubmitAttempted && customPromptErrors().length > 0"
              x-cloak
              class="gf-validation-summary"
              aria-live="polite"
            >
              <div class="gf-validation-title">Fix these fields</div>
              <template
                x-for="error in customPromptErrors()"
                :key="'custom-error-' + error.field + '-' + error.message"
              >
                <a
                  href="#"
                  @click.prevent="focusCustomPromptField(error.anchor)"
                  x-text="error.message"
                ></a>
              </template>
            </div>

            <div class="gf-custom-form-body">
              <div class="gf-custom-form-main">
                <section class="gf-custom-section">
                  <h4 class="gf-custom-section-title">Identity</h4>
                  <div class="gf-custom-grid-2">
                    <label class="gf-field" for="custom-prompt-name">
                      <span class="section-label">Name <span>*</span></span>
                      <input
                        id="custom-prompt-name"
                        x-model="customPromptDraft.name"
                        class="gf-input"
                        placeholder="Custom review prompt"
                        required
                        aria-required="true"
                        :aria-invalid="customPromptFieldError('name') ? 'true' : 'false'"
                        aria-describedby="custom-prompt-name-help custom-prompt-name-error"
                      />
                      <span id="custom-prompt-name-help" class="gf-field-help">
                        Used as the display name. The stored id is generated
                        from it.
                      </span>
                      <span
                        id="custom-prompt-name-error"
                        class="gf-field-error"
                        x-show="customPromptFieldError('name') && (customPromptSubmitAttempted || customPromptDraft.name.trim())"
                        x-text="customPromptFieldError('name')"
                      ></span>
                    </label>

                    <div
                      class="gf-field"
                      id="custom-prompt-route"
                      tabindex="-1"
                    >
                      <span class="section-label">Route <span>*</span></span>
                      <div
                        class="gf-route-pills"
                        role="radiogroup"
                        aria-label="Custom prompt route"
                        aria-required="true"
                        aria-describedby="custom-prompt-route-help custom-prompt-route-error"
                      >
                        <template
                          x-for="route in customPromptRouteOptions()"
                          :key="'route-' + route.id"
                        >
                          <button
                            type="button"
                            class="gf-route-pill"
                            :class="customPromptDraft.route === route.id ? 'is-active' : ''"
                            :aria-pressed="customPromptDraft.route === route.id ? 'true' : 'false'"
                            @click="customPromptDraft.route = route.id"
                            x-text="route.label"
                          ></button>
                        </template>
                      </div>
                      <span
                        id="custom-prompt-route-help"
                        class="gf-field-help"
                        x-text="selectedCustomPromptRoute().desc"
                      ></span>
                      <span
                        id="custom-prompt-route-error"
                        class="gf-field-error"
                        x-show="customPromptSubmitAttempted && customPromptFieldError('route')"
                        x-text="customPromptFieldError('route')"
                      ></span>
                    </div>
                  </div>

                  <label class="gf-field" for="custom-prompt-desc">
                    <span class="section-label">Description (optional)</span>
                    <input
                      id="custom-prompt-desc"
                      x-model="customPromptDraft.desc"
                      class="gf-input"
                      placeholder="Short note shown in the prompt list"
                      aria-describedby="custom-prompt-desc-help"
                    />
                    <span id="custom-prompt-desc-help" class="gf-field-help">
                      Shown under the name in the prompt list - keep to one
                      line.
                    </span>
                  </label>
                </section>

                <section class="gf-custom-section">
                  <h4
                    id="custom-prompt-body-heading"
                    class="gf-custom-section-title"
                  >
                    Prompt <span>*</span>
                  </h4>
                  <div class="gf-field">
                    <textarea
                      id="custom-prompt-body"
                      x-model="customPromptDraft.prompt"
                      class="gf-input gf-custom-prompt-textarea"
                      placeholder="/goat-review review the selected target project..."
                      required
                      aria-required="true"
                      aria-labelledby="custom-prompt-body-heading"
                      :aria-invalid="customPromptFieldError('prompt') ? 'true' : 'false'"
                      aria-describedby="custom-prompt-body-error custom-prompt-body-count custom-prompt-body-warning"
                    ></textarea>
                    <span
                      id="custom-prompt-body-error"
                      class="gf-field-error"
                      x-show="customPromptSubmitAttempted && customPromptFieldError('prompt')"
                      x-text="customPromptFieldError('prompt')"
                    ></span>
                    <span
                      id="custom-prompt-body-warning"
                      class="gf-field-warning"
                      x-show="customPromptWarning()"
                      x-text="customPromptWarning()"
                    ></span>
                    <span
                      id="custom-prompt-body-count"
                      class="gf-count-line"
                      x-text="`${customPromptDraft.prompt.length} chars · ${customPromptDraft.prompt ? customPromptDraft.prompt.split('\n').length : 0} lines`"
                    ></span>
                  </div>
                </section>

                <section class="gf-custom-section">
                  <h4 class="gf-custom-section-title">Behaviour</h4>
                  <div class="gf-flag-groups">
                    <template
                      x-for="group in customPromptFlagGroups()"
                      :key="'flag-group-' + group.id"
                    >
                      <div class="gf-flag-group">
                        <div
                          class="gf-flag-group-title"
                          x-text="group.label"
                        ></div>
                        <div class="gf-flag-grid">
                          <template
                            x-for="flag in group.flags"
                            :key="'flag-' + flag.field"
                          >
                            <div class="gf-flag-row">
                              <label
                                class="gf-check-row"
                                :for="'custom-flag-' + flag.field"
                              >
                                <input
                                  type="checkbox"
                                  :id="'custom-flag-' + flag.field"
                                  x-model="customPromptDraft[flag.field]"
                                  :disabled="customPromptFlagDisabled(flag)"
                                  :aria-describedby="'custom-flag-tip-' + flag.field"
                                  @change="syncCustomPromptFlag(flag)"
                                />
                                <span x-text="flag.label"></span>
                                <span
                                  x-show="flag.field === 'globalSafe' && !customPromptFlagDisabled(flag)"
                                  class="gf-flag-default-badge"
                                  >default</span
                                >
                              </label>
                              <span class="gf-tooltip-wrap">
                                <button
                                  type="button"
                                  class="gf-info-button"
                                  @click.stop
                                  :aria-label="flag.label + ' information'"
                                  :aria-describedby="'custom-flag-tip-' + flag.field"
                                >
                                  ?
                                </button>
                                <span
                                  class="gf-tooltip"
                                  role="tooltip"
                                  :id="'custom-flag-tip-' + flag.field"
                                  x-text="flag.title"
                                ></span>
                              </span>
                            </div>
                          </template>
                        </div>
                      </div>
                    </template>
                  </div>

                  <div class="gf-custom-grid-2">
                    <div class="gf-field">
                      <span
                        id="custom-prompt-surfaces-label"
                        class="section-label"
                        >Target surfaces (optional)</span
                      >
                      <div
                        class="gf-tag-input"
                        id="custom-prompt-surfaces"
                        role="group"
                        aria-labelledby="custom-prompt-surfaces-label"
                        aria-describedby="custom-prompt-surfaces-help"
                      >
                        <template
                          x-for="surface in customPromptSurfaceTags()"
                          :key="'surface-' + surface"
                        >
                          <span class="gf-tag-chip">
                            <span x-text="surface"></span>
                            <button
                              type="button"
                              @click="removeCustomPromptSurface(surface)"
                              :aria-label="'Remove ' + surface"
                            >
                              ×
                            </button>
                          </span>
                        </template>
                        <input
                          id="custom-prompt-surface-entry"
                          x-model="customPromptSurfaceDraft"
                          @keydown="if ($event.key === 'Enter' || $event.key === ',') { $event.preventDefault(); commitCustomPromptSurfaceDraft(); }"
                          @blur="commitCustomPromptSurfaceDraft()"
                          placeholder="Add surface"
                          aria-label="Add target surface"
                          aria-describedby="custom-prompt-surfaces-help"
                        />
                      </div>
                      <span
                        id="custom-prompt-surfaces-help"
                        class="gf-field-help"
                      >
                        Where this prompt is appropriate. Type to add a new
                        surface or pick from suggestions.
                      </span>
                      <div class="gf-surface-suggestions">
                        <template
                          x-for="surface in customPromptSurfaceSuggestions().slice(0, 8)"
                          :key="'surface-suggestion-' + surface"
                        >
                          <button
                            type="button"
                            class="gf-suggestion-chip"
                            @click="addCustomPromptSurface(surface)"
                            x-text="surface"
                          ></button>
                        </template>
                      </div>
                    </div>

                    <label class="gf-field" for="custom-prompt-notes">
                      <span class="section-label">Notes (optional)</span>
                      <textarea
                        id="custom-prompt-notes"
                        x-model="customPromptDraft.notes"
                        class="gf-input gf-custom-notes"
                        placeholder="Fallbacks or launch notes"
                        aria-describedby="custom-prompt-notes-help"
                      ></textarea>
                      <span id="custom-prompt-notes-help" class="gf-field-help">
                        Internal fallback notes - not appended before launch.
                      </span>
                    </label>
                  </div>
                </section>
              </div>

              <aside class="gf-custom-preview-pane" aria-label="Live preview">
                <div class="section-label">Live preview</div>
                <div
                  class="gf-card gf-prompt-list-card gf-custom-preview-card"
                  :style="{
	                    borderLeftColor: presetCategoryAccent(customPromptPreview())
	                  }"
                >
                  <span
                    class="gf-prompt-favorite gf-prompt-favorite-preview"
                    aria-hidden="true"
                    >☆</span
                  >
                  <div class="gf-prompt-card-content">
                    <div
                      class="gf-prompt-card-title"
                      :class="customPromptDraft.name.trim() ? 'gf-text-primary' : 'gf-text-muted gf-prompt-placeholder'"
                      x-text="customPromptPreviewName()"
                    ></div>
                    <p
                      class="gf-text-muted gf-prompt-card-desc"
                      :class="customPromptDraft.desc.trim() ? '' : 'gf-prompt-placeholder'"
                      x-text="customPromptPreviewDescription()"
                    ></p>
                    <div class="gf-prompt-card-meta">
                      <span
                        class="gf-text-secondary gf-prompt-route-chip"
                        x-text="presetRouteLabel(customPromptPreview())"
                      ></span>
                      <span
                        class="gf-text-muted gf-prompt-category-label"
                        x-text="customPromptPreview().cat"
                      ></span>
                      <template
                        x-for="badge in presetBadges(customPromptPreview()).slice(0, 3)"
                        :key="'preview-' + badge.label"
                      >
                        <span
                          :class="'gf-preset-badge gf-preset-badge-' + badge.tone"
                          :title="badge.title"
                          x-text="badge.label"
                        ></span>
                      </template>
                    </div>
                  </div>
                </div>
              </aside>
            </div>
          </form>
        </template>

        <template x-if="!showCustomPromptEditor && selectedPreset">
          <div>
            <div
              style="
                display: flex;
                gap: 8px;
                padding-bottom: 12px;
                border-bottom: 1px solid var(--border-subtle);
              "
            >
              <button
                x-data="{ copied: false }"
                @click="copyPreset(selectedPreset.prompt); copied = true; setTimeout(() => copied = false, 1200)"
                class="gf-btn gf-btn-md gf-btn-secondary"
              >
                <span x-text="copied ? 'Copied' : 'Copy'"></span>
              </button>
              <button
                @click="duplicateSelectedCustomPrompt()"
                class="gf-btn gf-btn-md gf-btn-secondary"
              >
                Duplicate
              </button>
              <template x-if="selectedPreset.source === 'custom'">
                <div style="display: flex; gap: 6px">
                  <button
                    @click="editSelectedCustomPrompt()"
                    class="gf-btn gf-btn-md gf-btn-secondary"
                  >
                    Edit
                  </button>
                  <button
                    @click="deleteSelectedCustomPrompt()"
                    class="gf-btn gf-btn-md gf-btn-secondary"
                  >
                    Delete
                  </button>
                </div>
              </template>
              <div style="flex: 1"></div>
              <button
                @click="launchPreset(extraContext.trim() ? selectedPreset.prompt + '\n\n' + extraContext.trim() : selectedPreset.prompt, activeRunner, selectedPreset.name, { presetId: selectedPreset.id })"
                :disabled="launching || serverSessions.length >= 10"
                class="gf-btn gf-btn-md gf-btn-primary"
              >
                Launch with <span x-text="activeRunner"></span>
              </button>
            </div>

            <div
              style="
                display: flex;
                justify-content: space-between;
                gap: 12px;
                margin-top: 16px;
              "
            >
              <div style="min-width: 0; flex: 1">
                <h3
                  class="gf-text-primary"
                  style="font-size: 16px; font-weight: 600; margin-bottom: 8px"
                  x-text="selectedPreset.name"
                ></h3>
                <div
                  style="
                    display: flex;
                    gap: 6px;
                    align-items: center;
                    flex-wrap: wrap;
                  "
                >
                  <span
                    style="
                      font-family: var(--font-mono);
                      font-size: 10px;
                      padding: 1px 6px;
                      border-radius: 3px;
                      background: var(--accent-bg);
                      color: var(--accent);
                      border: 1px solid var(--accent-border);
                    "
                    x-text="presetRouteLabel(selectedPreset)"
                  ></span>
                  <span
                    class="gf-text-muted"
                    style="
                      font-size: 11px;
                      padding: 2px 10px;
                      border-radius: 999px;
                      background: rgba(148, 163, 184, 0.08);
                    "
                    x-text="selectedPreset.cat"
                  ></span>
                  <template
                    x-for="badge in presetBadges(selectedPreset)"
                    :key="selectedPreset.id + '-' + badge.label"
                  >
                    <span
                      :class="'gf-preset-badge gf-preset-badge-' + badge.tone"
                      :title="badge.title"
                      x-text="badge.label"
                    ></span>
                  </template>
                </div>
              </div>
              <button
                @click="toggleFavorite(selectedPreset.id)"
                style="
                  background: transparent;
                  border: none;
                  color: var(--amber-400);
                  cursor: pointer;
                "
                :title="isFavorite(selectedPreset.id) ? 'Remove from favorites' : 'Add to favorites'"
              >
                <span
                  x-text="isFavorite(selectedPreset.id) ? '★' : '☆'"
                  style="font-size: 18px"
                ></span>
              </button>
            </div>

            <p
              class="gf-text-muted"
              style="font-size: 14px; margin-top: 14px; line-height: 1.6"
              x-text="selectedPreset.desc"
            ></p>

            <div style="margin-top: 16px">
              <div class="section-label" style="margin-bottom: 8px">Prompt</div>
              <pre
                class="gf-prompt-body"
                style="max-height: 260px; overflow-y: auto"
                x-text="adaptPrompt(selectedPreset.prompt)"
              ></pre>
            </div>

            <div style="margin-top: 14px">
              <div
                style="
                  display: flex;
                  justify-content: space-between;
                  align-items: baseline;
                  margin-bottom: 8px;
                "
              >
                <div class="section-label">
                  Extra context
                  <span
                    style="
                      text-transform: none;
                      letter-spacing: 0;
                      color: var(--text-dim);
                      font-weight: 400;
                    "
                    >(optional)</span
                  >
                </div>
                <span style="font-size: 11px; color: var(--text-dim)"
                  >Appended before launch</span
                >
              </div>
              <textarea
                x-model="extraContext"
                class="gf-input"
                style="
                  width: 100%;
                  min-height: 92px;
                  padding: 10px 12px;
                  resize: vertical;
                  font-family: var(--font-mono);
                  font-size: 12.5px;
                "
                placeholder="e.g. Focus on dispatcher routes and ignore integration tests for now..."
              ></textarea>
            </div>
          </div>
        </template>

        <template x-if="!showCustomPromptEditor && !selectedPreset">
          <div
            style="
              height: 100%;
              min-height: 420px;
              display: flex;
              align-items: center;
              justify-content: center;
            "
          >
            <p class="gf-text-muted">Select a prompt to preview it.</p>
          </div>
        </template>
      </div>
    </div>
  </div>
</div>
