{% extends "base.html" %}
{% block title %}{{ recipe.code }} — {{ _('Editor Task') }} — TieMeasureFlow{% endblock %}

{% block extra_head %}
<style>
  /* ---- Drag & Drop visual feedback ---- */
  .task-card.dragging {
    opacity: 0.5;
    transform: scale(0.98);
  }
  .task-card.drag-over-above {
    border-top: 3px solid var(--color-primary);
  }
  .task-card.drag-over-below {
    border-bottom: 3px solid var(--color-primary);
  }

  /* ---- Drag handle cursor ---- */
  .drag-handle {
    cursor: grab;
    user-select: none;
    touch-action: none;
  }
  .drag-handle:active {
    cursor: grabbing;
  }

  /* ---- Tolerance bar mini-visualization ---- */
  .tolerance-bar {
    display: flex;
    align-items: center;
    height: 8px;
    border-radius: 4px;
    overflow: hidden;
    min-width: 120px;
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
  }
  .tolerance-bar .seg-fail-low {
    background: var(--color-fail);
    opacity: 0.6;
  }
  .tolerance-bar .seg-warn-low {
    background: var(--color-warning);
    opacity: 0.6;
  }
  .tolerance-bar .seg-nominal {
    background: var(--color-pass);
  }
  .tolerance-bar .seg-warn-high {
    background: var(--color-warning);
    opacity: 0.6;
  }
  .tolerance-bar .seg-fail-high {
    background: var(--color-fail);
    opacity: 0.6;
  }

  /* ---- Marker badge (coerente con annotation-editor.js) ---- */
  .marker-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: #2563EB;
    color: #FFFFFF;
    font-size: 0.75rem;
    font-weight: 700;
    line-height: 1;
    flex-shrink: 0;
  }

  /* ---- Subtask inline editing row ---- */
  .subtask-edit-row input,
  .subtask-edit-row select {
    font-size: 0.8125rem;
    padding: 0.3rem 0.5rem;
  }

  /* ---- Subtask table horizontal scroll on mobile ---- */
  .subtask-table-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  .subtask-table-wrap::-webkit-scrollbar {
    height: 4px;
  }
</style>
{% endblock %}

{% block content %}
<div class="container mx-auto px-4 sm:px-6 lg:px-8 py-8 max-w-5xl"
     x-data="taskEditor()"
     x-cloak>

  <!-- ============================================================
       Breadcrumb
       ============================================================ -->
  <nav class="mb-6" aria-label="Breadcrumb">
    <ol class="flex items-center gap-2 text-sm text-[var(--text-secondary)]">
      <li>
        <a href="{{ url_for('maker.recipe_list') }}"
           class="hover:text-primary transition-colors inline-flex items-center gap-1">
          <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="1.75" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round"
                  d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
          </svg>
          {{ _('Ricette') }}
        </a>
      </li>
      <li>
        <svg class="w-4 h-4 text-[var(--text-muted)]" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7"/>
        </svg>
      </li>
      <li>
        <a href="{{ url_for('maker.recipe_edit', recipe_id=recipe.id) }}"
           class="hover:text-primary transition-colors">
          {{ recipe.code }}
        </a>
      </li>
      <li>
        <svg class="w-4 h-4 text-[var(--text-muted)]" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7"/>
        </svg>
      </li>
      <li class="font-medium text-[var(--text-primary)]">
        {{ _('Task') }}
      </li>
    </ol>
  </nav>

  <!-- ============================================================
       Header + Action Buttons
       ============================================================ -->
  <div class="mb-8">
    <div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-3">
      <div>
        <h1 class="text-3xl font-bold text-[var(--text-primary)] mb-1">
          <span class="font-mono text-primary">{{ recipe.code }}</span>
          <span class="text-[var(--text-muted)] text-lg font-normal ml-2">
            {{ _('Task e Misurazioni') }}
          </span>
        </h1>
        <p class="text-sm text-[var(--text-secondary)]">
          {{ recipe.name }}
          {% if recipe.current_version %}
            <span class="ml-2 badge badge-neutral font-mono text-xs">v{{ recipe.current_version.version_number }}</span>
          {% endif %}
        </p>
      </div>

      <!-- Top action buttons -->
      <div class="flex items-center gap-2 shrink-0 flex-wrap">
        <a href="{{ url_for('maker.recipe_edit', recipe_id=recipe.id) }}"
           class="btn btn-secondary gap-1.5">
          <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round"
                  d="M11 17l-5-5m0 0l5-5m-5 5h12"/>
          </svg>
          {{ _('Torna a Ricetta') }}
        </a>

        <a href="{{ url_for('maker.recipe_preview', recipe_id=recipe.id) }}"
           class="btn btn-secondary gap-1.5">
          <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round"
                  d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
            <path stroke-linecap="round" stroke-linejoin="round"
                  d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"/>
          </svg>
          {{ _('Anteprima') }}
        </a>
      </div>
    </div>
  </div>

  <!-- ============================================================
       Error Banner
       ============================================================ -->
  <div x-show="errorMessage"
       x-transition
       class="mb-6 flex items-center gap-3 px-4 py-3 rounded-lg
              bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-800
              text-red-800 dark:text-red-200 text-sm">
    <svg class="w-5 h-5 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
            d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
    </svg>
    <span x-text="errorMessage"></span>
    <button @click="errorMessage = ''" class="ml-auto shrink-0 hover:opacity-70">
      <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
      </svg>
    </button>
  </div>

  <!-- ============================================================
       Success Banner
       ============================================================ -->
  <div x-show="successMessage"
       x-transition
       x-init="$watch('successMessage', v => { if (v) setTimeout(() => successMessage = '', 4000) })"
       class="mb-6 flex items-center gap-3 px-4 py-3 rounded-lg
              bg-emerald-50 dark:bg-emerald-900/30 border border-emerald-200 dark:border-emerald-800
              text-emerald-800 dark:text-emerald-200 text-sm">
    <svg class="w-5 h-5 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
            d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
    </svg>
    <span x-text="successMessage"></span>
  </div>

  <!-- ============================================================
       Add Task Button (top)
       ============================================================ -->
  <div class="mb-4 flex items-center justify-between">
    <p class="text-sm text-[var(--text-secondary)]">
      <span x-text="tasks.length"></span>
      <span x-text="tasks.length === 1 ? '{{ _('task') }}' : '{{ _('task') }}'"></span>
    </p>
    <div class="flex items-center gap-2">
      <button @click="showAddTask = true; $nextTick(() => $refs.newTaskTitle && $refs.newTaskTitle.focus())"
              x-show="!showAddTask"
              class="btn btn-primary gap-1.5">
        <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" d="M12 4v16m8-8H4"/>
        </svg>
        {{ _('Aggiungi Task') }}
      </button>
      <button @click="showAiImport = true"
              x-show="!showAddTask"
              class="btn btn-secondary gap-1.5">
        <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
        </svg>
        {{ _('Importa da PDF') }}
      </button>
    </div>
  </div>

  <!-- ============================================================
       Add Task Form (inline)
       ============================================================ -->
  <div x-show="showAddTask"
       x-transition:enter="transition ease-out duration-200"
       x-transition:enter-start="opacity-0 -translate-y-2"
       x-transition:enter-end="opacity-100 translate-y-0"
       x-transition:leave="transition ease-in duration-150"
       x-transition:leave-start="opacity-100 translate-y-0"
       x-transition:leave-end="opacity-0 -translate-y-2"
       class="tmf-card mb-6">
    <div class="tmf-card-header flex items-center gap-2">
      <svg class="w-4 h-4 text-[var(--text-muted)]" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
        <path stroke-linecap="round" stroke-linejoin="round" d="M12 4v16m8-8H4"/>
      </svg>
      {{ _('Nuovo Task') }}
    </div>
    <div class="tmf-card-body">
      <div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
        <!-- Titolo -->
        <div class="sm:col-span-2">
          <label class="tmf-label">{{ _('Titolo') }} <span class="text-red-500">*</span></label>
          <input type="text"
                 x-ref="newTaskTitle"
                 x-model="newTask.title"
                 @keydown.enter.prevent="addTask()"
                 class="tmf-input"
                 placeholder="{{ _('Es. Controllo dimensionale flangia') }}">
        </div>
        <!-- Direttiva -->
        <div>
          <label class="tmf-label">{{ _('Direttiva') }}</label>
          <input type="text"
                 x-model="newTask.directive"
                 class="tmf-input"
                 placeholder="{{ _('Es. Seguire procedura ISO 2768') }}">
        </div>
        <!-- Descrizione -->
        <div class="sm:col-span-2">
          <label class="tmf-label">{{ _('Descrizione') }}</label>
          <textarea x-model="newTask.description"
                    class="tmf-input text-sm"
                    rows="3"
                    placeholder="{{ _('Descrizione opzionale...') }}"></textarea>
        </div>
      </div>
    </div>
    <div class="tmf-card-footer flex items-center gap-2 justify-end">
      <button @click="showAddTask = false; resetNewTask()"
              class="btn btn-secondary">
        {{ _('Annulla') }}
      </button>
      <button @click="addTask()"
              :disabled="!newTask.title.trim() || saving"
              class="btn btn-primary gap-1.5">
        <svg x-show="!saving" class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/>
        </svg>
        <svg x-show="saving" class="w-4 h-4 animate-spin" fill="none" viewBox="0 0 24 24">
          <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"/>
          <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z"/>
        </svg>
        {{ _('Crea Task') }}
      </button>
    </div>
  </div>

  <!-- ============================================================
       Task List
       ============================================================ -->
  <div class="space-y-4">
    <template x-for="(task, taskIndex) in tasks" :key="task.id">
      <div class="tmf-card task-card transition-all duration-200"
           :class="{
             'dragging': dragState.dragging === task.id,
             'drag-over-above': dragState.over === task.id && dragState.position === 'above',
             'drag-over-below': dragState.over === task.id && dragState.position === 'below'
           }"
           draggable="true"
           @dragstart="handleDragStart($event, task)"
           @dragend="handleDragEnd($event)"
           @dragover.prevent="handleDragOver($event, task)"
           @dragleave="handleDragLeave($event, task)"
           @drop.prevent="handleDrop($event, task)">

        <!-- ========== Task Card Header ========== -->
        <div class="tmf-card-header flex items-center gap-3 cursor-pointer select-none"
             @click="toggleExpand(task.id)">

          <!-- Drag Handle -->
          <span class="drag-handle text-[var(--text-muted)] hover:text-[var(--text-secondary)] px-1"
                @click.stop
                title="{{ _('Trascina per riordinare') }}">
            <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
              <circle cx="9" cy="5" r="1.5"/>
              <circle cx="15" cy="5" r="1.5"/>
              <circle cx="9" cy="12" r="1.5"/>
              <circle cx="15" cy="12" r="1.5"/>
              <circle cx="9" cy="19" r="1.5"/>
              <circle cx="15" cy="19" r="1.5"/>
            </svg>
          </span>

          <!-- Order Number -->
          <span class="text-xs font-mono text-[var(--text-muted)] w-6 text-center"
                x-text="taskIndex + 1">
          </span>

          <!-- Task Title (view mode) -->
          <template x-if="editingTask !== task.id">
            <span class="flex-1 font-semibold text-[var(--text-primary)] truncate"
                  x-text="task.title">
            </span>
          </template>

          <!-- Task Title (edit mode) -->
          <template x-if="editingTask === task.id">
            <input type="text"
                   x-model="editTaskData.title"
                   @click.stop
                   @keydown.enter.prevent="updateTask(task.id)"
                   @keydown.escape.prevent="cancelEditTask()"
                   class="tmf-input flex-1 text-sm font-semibold"
                   x-ref="editTaskTitleInput">
          </template>

          <!-- Badge: N misurazioni -->
          <span class="badge badge-neutral text-xs shrink-0"
                x-text="(task.subtasks ? task.subtasks.length : 0) + ' {{ _('misurazioni') }}'">
          </span>

          <!-- Action Buttons -->
          <div class="flex items-center gap-1 shrink-0" @click.stop>

            <!-- Edit Task -->
            <template x-if="editingTask !== task.id">
              <button @click="startEditTask(task)"
                      class="p-2 rounded-md text-[var(--text-muted)] hover:text-primary hover:bg-[var(--bg-secondary)] transition-colors"
                      title="{{ _('Modifica task') }}">
                <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
                  <path stroke-linecap="round" stroke-linejoin="round"
                        d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/>
                </svg>
              </button>
            </template>

            <!-- Save / Cancel (edit mode) -->
            <template x-if="editingTask === task.id">
              <div class="flex items-center gap-1">
                <button @click="updateTask(task.id)"
                        :disabled="!editTaskData.title.trim() || saving"
                        class="p-2 rounded-md text-emerald-600 hover:bg-emerald-50 dark:hover:bg-emerald-900/30 transition-colors"
                        title="{{ _('Salva') }}">
                  <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/>
                  </svg>
                </button>
                <button @click="cancelEditTask()"
                        class="p-2 rounded-md text-[var(--text-muted)] hover:text-[var(--text-primary)] hover:bg-[var(--bg-secondary)] transition-colors"
                        title="{{ _('Annulla') }}">
                  <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/>
                  </svg>
                </button>
              </div>
            </template>

            <!-- Expand/Collapse -->
            <button @click.stop="toggleExpand(task.id)"
                    class="p-2 rounded-md text-[var(--text-muted)] hover:text-[var(--text-primary)] hover:bg-[var(--bg-secondary)] transition-colors"
                    title="{{ _('Espandi/Comprimi') }}">
              <svg class="w-4 h-4 transition-transform duration-200"
                   :class="{ 'rotate-180': expandedTask === task.id }"
                   fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7"/>
              </svg>
            </button>

            <!-- Delete Task -->
            <button @click="confirmDeleteTask(task)"
                    class="p-2 rounded-md text-[var(--text-muted)] hover:text-red-500 hover:bg-red-50 dark:hover:bg-red-900/20 transition-colors"
                    title="{{ _('Elimina task') }}">
              <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round"
                      d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
              </svg>
            </button>
          </div>
        </div>

        <!-- ========== Task Card Body (collapsible) ========== -->
        <div x-show="expandedTask === task.id"
             x-transition:enter="transition ease-out duration-200"
             x-transition:enter-start="opacity-0"
             x-transition:enter-end="opacity-100"
             x-transition:leave="transition ease-in duration-150"
             x-transition:leave-start="opacity-100"
             x-transition:leave-end="opacity-0">

          <div class="tmf-card-body space-y-4">

            <!-- ========== Task File Upload / Preview ========== -->
            <div class="p-3 rounded-lg bg-[var(--bg-secondary)] border border-[var(--border-color)]">
              <p class="text-xs font-semibold text-[var(--text-secondary)] uppercase tracking-wide mb-2">
                {{ _('Disegno Tecnico') }}
              </p>

              <!-- Preview if file exists -->
              <template x-if="task.file_path">
                <div class="space-y-2">
                  <div class="relative rounded-lg overflow-hidden bg-[var(--bg-secondary)] border border-[var(--border-color)]">
                    <canvas :id="'preview-' + task.id"
                            class="block mx-auto"
                            style="max-height: 192px;">
                    </canvas>
                  </div>
                  <!-- Action buttons -->
                  <div class="flex items-center gap-2 flex-wrap">
                    <a :href="'/maker/recipes/' + recipeId + '/tasks/' + task.id + '/drawing'"
                       class="btn btn-secondary text-xs gap-1.5">
                      <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/>
                      </svg>
                      {{ _('Modifica Disegno') }}
                    </a>
                    <label class="btn btn-secondary text-xs gap-1.5 cursor-pointer">
                      <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12"/>
                      </svg>
                      {{ _('Sostituisci') }}
                      <input type="file"
                             accept="image/*,application/pdf"
                             class="hidden"
                             @change="uploadTaskFile(task.id, $event.target.files[0], task); $event.target.value = ''">
                    </label>
                  </div>
                </div>
              </template>

              <!-- Upload zone if no file -->
              <template x-if="!task.file_path">
                <label class="flex flex-col items-center gap-2 p-4 rounded-lg border-2 border-dashed border-[var(--border-color)] hover:border-primary/50 cursor-pointer transition-colors">
                  <svg class="w-8 h-8 text-[var(--text-muted)]" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5"/>
                  </svg>
                  <span class="text-xs text-[var(--text-secondary)]">{{ _('Carica immagine o PDF') }}</span>
                  <input type="file"
                         accept="image/*,application/pdf"
                         class="hidden"
                         @change="uploadTaskFile(task.id, $event.target.files[0], task); $event.target.value = ''">
                </label>
              </template>
            </div>

            <!-- Task Directive / Description (read-only display) -->
            <template x-if="task.directive || task.description">
              <div class="flex flex-col gap-2 p-3 rounded-lg bg-[var(--bg-secondary)] border border-[var(--border-color)]">
                <template x-if="task.directive">
                  <div class="flex items-start gap-2">
                    <span class="text-xs font-semibold text-[var(--text-muted)] uppercase tracking-wide shrink-0 mt-0.5">{{ _('Direttiva') }}:</span>
                    <span class="text-sm text-[var(--text-secondary)]" x-text="task.directive"></span>
                  </div>
                </template>
                <template x-if="task.description">
                  <div class="flex items-start gap-2">
                    <span class="text-xs font-semibold text-[var(--text-muted)] uppercase tracking-wide shrink-0 mt-0.5">{{ _('Descrizione') }}:</span>
                    <span class="text-sm text-[var(--text-secondary)] whitespace-pre-wrap" x-text="task.description"></span>
                  </div>
                </template>
              </div>
            </template>

            <!-- Edit Task Extra Fields (when in edit mode) -->
            <template x-if="editingTask === task.id">
              <div class="grid grid-cols-1 sm:grid-cols-2 gap-3 p-3 rounded-lg bg-blue-50 dark:bg-blue-900/10 border border-blue-200 dark:border-blue-800">
                <div>
                  <label class="tmf-label">{{ _('Direttiva') }}</label>
                  <input type="text"
                         x-model="editTaskData.directive"
                         class="tmf-input text-sm"
                         placeholder="{{ _('Direttiva opzionale...') }}">
                </div>
                <div class="sm:col-span-2">
                  <label class="tmf-label">{{ _('Descrizione') }}</label>
                  <textarea x-model="editTaskData.description"
                            class="tmf-input text-sm"
                            rows="3"
                            placeholder="{{ _('Descrizione opzionale...') }}"></textarea>
                </div>
              </div>
            </template>

            <!-- ========== Subtask Table ========== -->
            <div class="subtask-table-wrap">
              <table class="tmf-table" x-show="task.subtasks && task.subtasks.length > 0">
                <thead>
                  <tr>
                    <th class="w-16 text-center">{{ _('#') }}</th>
                    <th>{{ _('Descrizione') }}</th>
                    <th class="w-24">{{ _('Tipo') }}</th>
                    <th class="w-20 text-right">{{ _('Nominale') }}</th>
                    <th class="w-20 text-right">{{ _('UTL') }}</th>
                    <th class="w-20 text-right">{{ _('UWL') }}</th>
                    <th class="w-20 text-right">{{ _('LWL') }}</th>
                    <th class="w-20 text-right">{{ _('LTL') }}</th>
                    <th class="w-16 text-center">{{ _('Unita') }}</th>
                    <th class="w-32">{{ _('Tolleranze') }}</th>
                    <th class="w-20 text-center">{{ _('Azioni') }}</th>
                  </tr>
                </thead>
                <tbody>
                <template x-for="subtask in task.subtasks" :key="subtask.id">
                    <tr class="hover:bg-[var(--bg-card-hover)]">
                      <td class="text-center">
                        <span class="marker-badge" x-text="subtask.marker_number"></span>
                      </td>
                      <td>
                        <span class="text-sm" x-text="subtask.description"></span>
                      </td>
                      <td>
                        <span class="text-xs badge badge-neutral" x-text="subtask.measurement_type || '-'"></span>
                      </td>
                      <td class="text-right">
                        <span class="measure-value text-sm" x-text="subtask.nominal != null ? subtask.nominal : '-'"></span>
                      </td>
                      <td class="text-right">
                        <span class="measure-value text-sm text-red-500" x-text="subtask.utl != null ? subtask.utl : '-'"></span>
                      </td>
                      <td class="text-right">
                        <span class="measure-value text-sm text-amber-500" x-text="subtask.uwl != null ? subtask.uwl : '-'"></span>
                      </td>
                      <td class="text-right">
                        <span class="measure-value text-sm text-amber-500" x-text="subtask.lwl != null ? subtask.lwl : '-'"></span>
                      </td>
                      <td class="text-right">
                        <span class="measure-value text-sm text-red-500" x-text="subtask.ltl != null ? subtask.ltl : '-'"></span>
                      </td>
                      <td class="text-center">
                        <span class="text-xs text-[var(--text-muted)]" x-text="subtask.unit || 'mm'"></span>
                      </td>
                      <td>
                        <template x-if="subtask.nominal != null && subtask.ltl != null && subtask.utl != null">
                          <div class="tolerance-bar" :title="toleranceTitle(subtask)">
                            <div class="seg-fail-low h-full" :style="toleranceSegStyle(subtask, 'fail-low')"></div>
                            <div class="seg-warn-low h-full" :style="toleranceSegStyle(subtask, 'warn-low')"></div>
                            <div class="seg-nominal h-full" :style="toleranceSegStyle(subtask, 'nominal')"></div>
                            <div class="seg-warn-high h-full" :style="toleranceSegStyle(subtask, 'warn-high')"></div>
                            <div class="seg-fail-high h-full" :style="toleranceSegStyle(subtask, 'fail-high')"></div>
                          </div>
                        </template>
                        <template x-if="subtask.nominal == null || subtask.ltl == null || subtask.utl == null">
                          <span class="text-xs text-[var(--text-muted)]">-</span>
                        </template>
                      </td>
                      <td class="text-center">
                        <div class="flex items-center justify-center gap-1">
                          <button @click.stop="startEditSubtask(subtask, task.id)"
                                  class="p-1.5 rounded text-[var(--text-muted)] hover:text-primary hover:bg-[var(--bg-secondary)] transition-colors"
                                  title="{{ _('Modifica') }}">
                            <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
                              <path stroke-linecap="round" stroke-linejoin="round"
                                    d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/>
                            </svg>
                          </button>
                          <button @click.stop="confirmDeleteSubtask(subtask, task.id)"
                                  class="p-1.5 rounded text-[var(--text-muted)] hover:text-red-500 hover:bg-red-50 dark:hover:bg-red-900/20 transition-colors"
                                  title="{{ _('Elimina') }}">
                            <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
                              <path stroke-linecap="round" stroke-linejoin="round"
                                    d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
                            </svg>
                          </button>
                        </div>
                      </td>
                    </tr>
                </template>
                </tbody>
              </table>
            </div>

            <!-- ========== Empty Subtask State ========== -->
            <div x-show="!task.subtasks || task.subtasks.length === 0"
                 class="text-center py-8">
              <div class="inline-flex items-center justify-center w-14 h-14 rounded-full
                          bg-[var(--bg-secondary)] mb-3">
                <svg class="w-7 h-7 text-[var(--text-muted)]" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24">
                  <path stroke-linecap="round" stroke-linejoin="round"
                        d="M9 7h6m0 10v-3m-3 3h.01M9 17h.01M9 14h.01M12 14h.01M15 11h.01M12 11h.01M9 11h.01M7 21h10a2 2 0 002-2V5a2 2 0 00-2-2H7a2 2 0 00-2 2v14a2 2 0 002 2z"/>
                </svg>
              </div>
              <p class="text-sm text-[var(--text-secondary)] mb-1">
                {{ _('Nessuna misurazione definita') }}
              </p>
              <p class="text-xs text-[var(--text-muted)]">
                {{ _('Aggiungi la prima misurazione per questo task') }}
              </p>
            </div>

            <!-- ========== Add Subtask Inline Form ========== -->
            <div x-show="addingSubtaskForTask === task.id"
                 x-transition
                 class="p-3 rounded-lg bg-[var(--bg-secondary)] border border-[var(--border-color)]">
              <p class="text-xs font-semibold text-[var(--text-secondary)] uppercase tracking-wide mb-3"
                 x-text="editingSubtaskId ? '{{ _('Modifica Misurazione') }}' : '{{ _('Nuova Misurazione') }}'">
              </p>
              <div class="grid grid-cols-2 sm:grid-cols-4 lg:grid-cols-6 gap-3">
                <!-- Marker Number -->
                <div>
                  <label class="tmf-label text-xs">{{ _('Marker #') }}</label>
                  <input type="number"
                         x-model.number="newSubtask.marker_number"
                         min="1"
                         class="tmf-input measure-value text-center">
                </div>
                <!-- Description -->
                <div class="col-span-2 sm:col-span-3 lg:col-span-2">
                  <label class="tmf-label text-xs">{{ _('Descrizione') }} <span class="text-red-500">*</span></label>
                  <input type="text"
                         x-model="newSubtask.description"
                         @keydown.enter.prevent="editingSubtaskId ? updateSubtask(editingSubtaskId, task.id) : addSubtask(task.id)"
                         class="tmf-input"
                         placeholder="{{ _('Es. Diametro foro principale') }}">
                </div>
                <!-- Measurement Type -->
                <div>
                  <label class="tmf-label text-xs">{{ _('Tipo') }}</label>
                  <select x-model="newSubtask.measurement_type"
                          class="tmf-input">
                    <option value="">-</option>
                    <option value="linear">{{ _('Lineare') }}</option>
                    <option value="diameter">{{ _('Diametro') }}</option>
                    <option value="radius">{{ _('Raggio') }}</option>
                    <option value="angle">{{ _('Angolo') }}</option>
                    <option value="roughness">{{ _('Rugosita') }}</option>
                    <option value="torque">{{ _('Coppia') }}</option>
                    <option value="force">{{ _('Forza') }}</option>
                    <option value="weight">{{ _('Peso') }}</option>
                    <option value="other">{{ _('Altro') }}</option>
                  </select>
                </div>
                <!-- Nominal -->
                <div>
                  <label class="tmf-label text-xs">{{ _('Nominale') }}</label>
                  <input type="number" step="any"
                         x-model.number="newSubtask.nominal"
                         class="tmf-input measure-value text-right"
                         placeholder="0.000">
                </div>
                <!-- Unit -->
                <div>
                  <label class="tmf-label text-xs">{{ _('Unita') }}</label>
                  <select x-model="newSubtask.unit"
                          class="tmf-input">
                    <option value="mm">mm</option>
                    <option value="cm">cm</option>
                    <option value="m">m</option>
                    <option value="μm">μm</option>
                    <option value="in">in</option>
                    <option value="°">°</option>
                    <option value="g">g</option>
                    <option value="kg">kg</option>
                    <option value="N">N</option>
                    <option value="Nm">Nm</option>
                  </select>
                </div>
              </div>

              <!-- Tolerance Fields -->
              <div class="grid grid-cols-2 sm:grid-cols-4 gap-3 mt-3">
                <div>
                  <label class="tmf-label text-xs text-red-500">{{ _('LTL') }}</label>
                  <input type="number" step="any"
                         x-model.number="newSubtask.ltl"
                         class="tmf-input measure-value text-right"
                         placeholder="{{ _('Lim. Tol. Inf.') }}">
                </div>
                <div>
                  <label class="tmf-label text-xs text-amber-500">{{ _('LWL') }}</label>
                  <input type="number" step="any"
                         x-model.number="newSubtask.lwl"
                         class="tmf-input measure-value text-right"
                         placeholder="{{ _('Lim. Warn. Inf.') }}">
                </div>
                <div>
                  <label class="tmf-label text-xs text-amber-500">{{ _('UWL') }}</label>
                  <input type="number" step="any"
                         x-model.number="newSubtask.uwl"
                         class="tmf-input measure-value text-right"
                         placeholder="{{ _('Lim. Warn. Sup.') }}">
                </div>
                <div>
                  <label class="tmf-label text-xs text-red-500">{{ _('UTL') }}</label>
                  <input type="number" step="any"
                         x-model.number="newSubtask.utl"
                         class="tmf-input measure-value text-right"
                         placeholder="{{ _('Lim. Tol. Sup.') }}">
                </div>
              </div>

              <!-- Form Actions -->
              <div class="flex items-center gap-2 justify-end mt-4">
                <button @click="cancelSubtaskForm(task.id)"
                        class="btn btn-secondary text-xs">
                  {{ _('Annulla') }}
                </button>
                <button @click="editingSubtaskId ? updateSubtask(editingSubtaskId, task.id) : addSubtask(task.id)"
                        :disabled="!newSubtask.description.trim() || saving"
                        class="btn btn-primary text-xs gap-1.5">
                  <svg x-show="!saving" class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/>
                  </svg>
                  <svg x-show="saving" class="w-3.5 h-3.5 animate-spin" fill="none" viewBox="0 0 24 24">
                    <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"/>
                    <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z"/>
                  </svg>
                  <span x-text="editingSubtaskId ? '{{ _('Aggiorna Misurazione') }}' : '{{ _('Aggiungi Misurazione') }}'"></span>
                </button>
              </div>
            </div>
          </div>

          <!-- ========== Task Card Footer ========== -->
          <div class="tmf-card-footer flex items-center justify-end">
            <button @click="openAddSubtask(task)"
                    x-show="addingSubtaskForTask !== task.id"
                    class="btn btn-secondary text-xs gap-1.5">
              <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" d="M12 4v16m8-8H4"/>
              </svg>
              {{ _('Aggiungi Misurazione') }}
            </button>
          </div>
        </div>
      </div>
    </template>
  </div>

  <!-- ============================================================
       Empty State (no tasks)
       ============================================================ -->
  <div x-show="tasks.length === 0 && !showAddTask"
       class="text-center py-16">
    <div class="inline-flex items-center justify-center w-20 h-20 rounded-full
                bg-[var(--bg-secondary)] mb-5">
      <svg class="w-10 h-10 text-[var(--text-muted)]" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24">
        <path stroke-linecap="round" stroke-linejoin="round"
              d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"/>
      </svg>
    </div>
    <h3 class="text-lg font-semibold text-[var(--text-primary)] mb-2">
      {{ _('Nessun task definito') }}
    </h3>
    <p class="text-sm text-[var(--text-secondary)] max-w-md mx-auto mb-6">
      {{ _('Inizia aggiungendo il primo task di misurazione per questa ricetta') }}
    </p>
    <button @click="showAddTask = true; $nextTick(() => $refs.newTaskTitle && $refs.newTaskTitle.focus())"
            class="btn btn-primary gap-2 inline-flex">
      <svg class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
        <path stroke-linecap="round" stroke-linejoin="round" d="M12 4v16m8-8H4"/>
      </svg>
      {{ _('Aggiungi Primo Task') }}
    </button>
  </div>

  <!-- ============================================================
       Delete Task Confirmation Modal
       ============================================================ -->
  <div x-show="deleteTaskModal"
       x-cloak
       @keydown.escape.window="deleteTaskModal = false"
       class="fixed inset-0 z-50 overflow-y-auto"
       role="dialog"
       aria-modal="true">
    <!-- Backdrop -->
    <div x-show="deleteTaskModal"
         x-transition:enter="transition ease-out duration-300"
         x-transition:enter-start="opacity-0"
         x-transition:enter-end="opacity-100"
         x-transition:leave="transition ease-in duration-200"
         x-transition:leave-start="opacity-100"
         x-transition:leave-end="opacity-0"
         @click="deleteTaskModal = false"
         class="fixed inset-0 bg-black/50 backdrop-blur-sm transition-opacity">
    </div>
    <!-- Modal Content -->
    <div class="flex min-h-full items-center justify-center p-4">
      <div x-show="deleteTaskModal"
           x-transition:enter="transition ease-out duration-300"
           x-transition:enter-start="opacity-0 translate-y-4 sm:scale-95"
           x-transition:enter-end="opacity-100 translate-y-0 sm:scale-100"
           x-transition:leave="transition ease-in duration-200"
           x-transition:leave-start="opacity-100 translate-y-0 sm:scale-100"
           x-transition:leave-end="opacity-0 translate-y-4 sm:scale-95"
           class="tmf-card max-w-lg w-full relative">
        <div class="p-6">
          <!-- Icon -->
          <div class="mx-auto flex items-center justify-center w-12 h-12 rounded-full bg-red-100 dark:bg-red-900/30 mb-4">
            <svg class="w-6 h-6 text-red-600 dark:text-red-400" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round"
                    d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/>
            </svg>
          </div>
          <h3 class="text-lg font-semibold text-[var(--text-primary)] text-center mb-2">
            {{ _('Conferma Eliminazione Task') }}
          </h3>
          <template x-if="deleteTargetTask">
            <div>
              <p class="text-sm text-[var(--text-secondary)] text-center mb-2">
                {{ _('Sei sicuro di voler eliminare il task') }}
                <span class="font-semibold text-[var(--text-primary)]" x-text="deleteTargetTask.title"></span>?
              </p>
              <p class="text-xs text-[var(--text-muted)] text-center mb-6"
                 x-show="deleteTargetTask.subtasks && deleteTargetTask.subtasks.length > 0">
                {{ _('Verranno eliminate anche') }}
                <span class="font-semibold" x-text="deleteTargetTask.subtasks.length"></span>
                {{ _('misurazioni associate.') }}
              </p>
            </div>
          </template>
          <div class="flex flex-col sm:flex-row gap-3">
            <button @click="deleteTaskModal = false"
                    class="btn btn-secondary flex-1 justify-center">
              {{ _('Annulla') }}
            </button>
            <button @click="deleteTask(deleteTargetTask.id)"
                    class="btn btn-danger flex-1 justify-center">
              {{ _('Elimina Task') }}
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>

  <!-- ============================================================
       Delete Subtask Confirmation Modal
       ============================================================ -->
  <div x-show="deleteSubtaskModal"
       x-cloak
       @keydown.escape.window="deleteSubtaskModal = false"
       class="fixed inset-0 z-50 overflow-y-auto"
       role="dialog"
       aria-modal="true">
    <!-- Backdrop -->
    <div x-show="deleteSubtaskModal"
         x-transition:enter="transition ease-out duration-300"
         x-transition:enter-start="opacity-0"
         x-transition:enter-end="opacity-100"
         x-transition:leave="transition ease-in duration-200"
         x-transition:leave-start="opacity-100"
         x-transition:leave-end="opacity-0"
         @click="deleteSubtaskModal = false"
         class="fixed inset-0 bg-black/50 backdrop-blur-sm transition-opacity">
    </div>
    <!-- Modal Content -->
    <div class="flex min-h-full items-center justify-center p-4">
      <div x-show="deleteSubtaskModal"
           x-transition:enter="transition ease-out duration-300"
           x-transition:enter-start="opacity-0 translate-y-4 sm:scale-95"
           x-transition:enter-end="opacity-100 translate-y-0 sm:scale-100"
           x-transition:leave="transition ease-in duration-200"
           x-transition:leave-start="opacity-100 translate-y-0 sm:scale-100"
           x-transition:leave-end="opacity-0 translate-y-4 sm:scale-95"
           class="tmf-card max-w-lg w-full relative">
        <div class="p-6">
          <!-- Icon -->
          <div class="mx-auto flex items-center justify-center w-12 h-12 rounded-full bg-red-100 dark:bg-red-900/30 mb-4">
            <svg class="w-6 h-6 text-red-600 dark:text-red-400" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round"
                    d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
            </svg>
          </div>
          <h3 class="text-lg font-semibold text-[var(--text-primary)] text-center mb-2">
            {{ _('Conferma Eliminazione Misurazione') }}
          </h3>
          <template x-if="deleteTargetSubtask">
            <p class="text-sm text-[var(--text-secondary)] text-center mb-6">
              {{ _('Sei sicuro di voler eliminare la misurazione') }}
              <span class="font-semibold text-[var(--text-primary)]">
                #<span x-text="deleteTargetSubtask.marker_number"></span>
              </span>
              — <span x-text="deleteTargetSubtask.description"></span>?
            </p>
          </template>
          <div class="flex flex-col sm:flex-row gap-3">
            <button @click="deleteSubtaskModal = false"
                    class="btn btn-secondary flex-1 justify-center">
              {{ _('Annulla') }}
            </button>
            <button @click="deleteSubtask(deleteTargetSubtask.id, deleteSubtaskParentId)"
                    class="btn btn-danger flex-1 justify-center">
              {{ _('Elimina Misurazione') }}
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>

  {# ================================================================
     AI IMPORT MODAL — Upload PDF + preview suggested tasks
     ================================================================ #}
  <div x-show="showAiImport"
       x-transition:enter="transition ease-out duration-200"
       x-transition:enter-start="opacity-0"
       x-transition:enter-end="opacity-100"
       x-transition:leave="transition ease-in duration-150"
       x-transition:leave-start="opacity-100"
       x-transition:leave-end="opacity-0"
       x-cloak
       class="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm"
       @click.self="showAiImport = false">
    <div class="bg-[var(--bg-card)] rounded-2xl shadow-2xl max-w-2xl w-full mx-4 max-h-[85vh] flex flex-col border border-[var(--border-color)]">

      {# Header #}
      <div class="p-5 border-b border-[var(--border-color)] shrink-0">
        <div class="flex items-center gap-3">
          <div class="w-10 h-10 rounded-full bg-primary-50 dark:bg-primary-900/30 flex items-center justify-center">
            <svg class="w-5 h-5 text-primary" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
            </svg>
          </div>
          <div>
            <h3 class="text-lg font-bold text-[var(--text-primary)]">{{ _('Importa da Scheda Tecnica') }}</h3>
            <p class="text-xs text-[var(--text-secondary)]">{{ _('Carica un PDF e l\'AI estrarrà i task automaticamente') }}</p>
          </div>
        </div>
      </div>

      {# Body #}
      <div class="p-5 overflow-y-auto flex-1">
        {# Upload area (before analysis) #}
        <div x-show="!aiSuggestions.length && !aiParsing">
          <label class="flex flex-col items-center justify-center w-full h-40 border-2 border-dashed border-[var(--border-color)] rounded-xl cursor-pointer
                        hover:border-primary hover:bg-primary-50/50 dark:hover:bg-primary-900/10 transition-colors">
            <svg class="w-10 h-10 text-[var(--text-muted)] mb-2" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5"/>
            </svg>
            <span class="text-sm font-medium text-[var(--text-secondary)]">{{ _('Clicca per caricare un PDF') }}</span>
            <span class="text-xs text-[var(--text-muted)] mt-1">{{ _('Max 20MB') }}</span>
            <input type="file" accept=".pdf,application/pdf" class="hidden" @change="uploadAndParse($event)">
          </label>
        </div>

        {# Loading #}
        <div x-show="aiParsing" class="flex flex-col items-center justify-center py-12">
          <svg class="w-10 h-10 animate-spin text-primary mb-3" fill="none" viewBox="0 0 24 24">
            <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"/>
            <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z"/>
          </svg>
          <p class="text-sm font-medium text-[var(--text-secondary)]">{{ _('Analisi in corso con AI...') }}</p>
          <p class="text-xs text-[var(--text-muted)] mt-1">{{ _('Potrebbe richiedere fino a 30 secondi') }}</p>
        </div>

        {# Error #}
        <div x-show="aiError" class="p-3 rounded-lg bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 mb-4">
          <p class="text-sm text-red-700 dark:text-red-300" x-text="aiError"></p>
          <button @click="aiError = ''; aiSuggestions = []" class="text-xs text-red-600 underline mt-1">{{ _('Riprova') }}</button>
        </div>

        {# Suggested tasks (editable preview) #}
        <div x-show="aiSuggestions.length > 0" class="space-y-3">
          <p class="text-sm font-medium text-[var(--text-secondary)] mb-2">
            <span x-text="aiSuggestions.length"></span> {{ _('task suggeriti — modifica o rimuovi prima di confermare') }}
          </p>
          <template x-for="(suggestion, idx) in aiSuggestions" :key="idx">
            <div class="tmf-card">
              <div class="p-4 space-y-2">
                <div class="flex items-center justify-between gap-2">
                  <span class="text-xs font-bold text-primary">Task <span x-text="idx + 1"></span></span>
                  <button @click="aiSuggestions.splice(idx, 1)" class="text-xs text-red-500 hover:text-red-700">
                    <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
                      <path stroke-linecap="round" stroke-linejoin="round" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
                    </svg>
                  </button>
                </div>
                <input type="text" x-model="suggestion.title" class="tmf-input text-sm font-semibold"
                       placeholder="{{ _('Titolo') }}">
                <input type="text" x-model="suggestion.directive" class="tmf-input text-sm"
                       placeholder="{{ _('Direttiva') }}">
                <textarea x-model="suggestion.description" class="tmf-input text-sm" rows="3"
                          placeholder="{{ _('Descrizione') }}"></textarea>
              </div>
            </div>
          </template>
        </div>
      </div>

      {# Footer #}
      <div class="p-4 border-t border-[var(--border-color)] shrink-0 flex items-center justify-between gap-2">
        <button @click="showAiImport = false; aiSuggestions = []; aiError = ''"
                class="btn btn-secondary text-sm">
          {{ _('Annulla') }}
        </button>
        <button x-show="aiSuggestions.length > 0"
                @click="createTasksFromSuggestions()"
                :disabled="aiCreating"
                class="btn btn-primary text-sm gap-1.5">
          <svg x-show="!aiCreating" class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/>
          </svg>
          <svg x-show="aiCreating" class="w-4 h-4 animate-spin" fill="none" viewBox="0 0 24 24">
            <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"/>
            <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z"/>
          </svg>
          {{ _('Crea') }} <span x-text="aiSuggestions.length"></span> {{ _('task') }}
        </button>
      </div>
    </div>
  </div>

</div>
{% endblock %}

{% block extra_js %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js"></script>
<script>if(typeof pdfjsLib!=='undefined')pdfjsLib.GlobalWorkerOptions.workerSrc='https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js';</script>
<script src="{{ url_for('static', filename='js/annotation-viewer.js') }}?v=6"></script>
<script>
// Force reload when page is restored from browser bfcache (back/forward navigation).
// This ensures fresh data is displayed after editing annotations in task_drawing.
window.addEventListener('pageshow', function (event) {
  if (event.persisted) { window.location.reload(); }
});
</script>
<script>
function taskEditor() {
  return {
    // ---- Recipe context ----
    recipeId: {{ recipe.id|tojson }},

    // ---- Task list ----
    tasks: {{ recipe.tasks|tojson }},

    // ---- UI state ----
    expandedTask: null,
    showAddTask: false,
    saving: false,
    errorMessage: '',
    successMessage: '',

    // ---- Task CRUD state ----
    editingTask: null,
    editTaskData: { title: '', directive: '', description: '' },
    newTask: { title: '', directive: '', description: '' },

    // ---- Subtask CRUD state ----
    editingSubtaskId: null,
    addingSubtaskForTask: null,
    newSubtask: {
      marker_number: 1, description: '', measurement_type: '',
      nominal: null, utl: null, uwl: null, lwl: null, ltl: null, unit: 'mm'
    },

    // ---- Delete modals ----
    deleteTaskModal: false,
    deleteTargetTask: null,
    deleteSubtaskModal: false,
    deleteTargetSubtask: null,
    deleteSubtaskParentId: null,

    // ---- Drag & Drop state ----
    dragState: { dragging: null, over: null, position: null },

    // ---- AI Import ----
    showAiImport: false,
    aiParsing: false,
    aiCreating: false,
    aiSuggestions: [],
    aiError: '',

    // ============================================================
    // Init
    // ============================================================
    init() {
      // Sort tasks by order_index on load
      this.tasks.sort((a, b) => (a.order_index || 0) - (b.order_index || 0));

      // Check if returning from task_drawing with updated annotations
      try {
        var updatedRaw = sessionStorage.getItem('taskDrawingUpdated');
        if (updatedRaw) {
          sessionStorage.removeItem('taskDrawingUpdated');
          var updated = JSON.parse(updatedRaw);
          if (updated.taskId) {
            var task = this.tasks.find(function(t) { return t.id === updated.taskId; });
            if (task) {
              // Merge updated annotations into local state
              if (updated.annotations_json) {
                task.annotations_json = (typeof updated.annotations_json === 'string')
                  ? JSON.parse(updated.annotations_json) : updated.annotations_json;
              }
              // Auto-expand the edited task and render preview
              this.expandedTask = task.id;
              this.renderTaskPreview(task);
              return; // skip default expansion logic
            }
          }
        }
      } catch (_e) { /* sessionStorage parse error - ignore */ }

      // Auto-expand the first task if there is only one
      if (this.tasks.length === 1) {
        this.expandedTask = this.tasks[0].id;
        this.renderTaskPreview(this.tasks[0]);
      }
    },

    // ============================================================
    // CSRF Helper
    // ============================================================
    csrfToken() {
      return document.querySelector('meta[name="csrf-token"]')?.content || '';
    },

    // ============================================================
    // Render Task Preview (deferred)
    // ============================================================
    renderTaskPreview(task) {
      if (!task || !task.file_path) return;
      if (typeof renderAnnotationPreview !== 'function') {
        // Fallback: show image via <img> tag if viewer script not loaded
        this.$nextTick(() => {
          const canvas = document.getElementById('preview-' + task.id);
          if (canvas && canvas.parentElement) {
            const img = document.createElement('img');
            img.src = '/maker/api/files/' + task.file_path;
            img.className = 'block mx-auto max-h-48 object-contain';
            img.loading = 'lazy';
            canvas.parentElement.replaceChild(img, canvas);
          }
        });
        return;
      }
      this.$nextTick(() => {
        setTimeout(() => {
          const canvas = document.getElementById('preview-' + task.id);
          if (canvas) {
            renderAnnotationPreview(canvas, '/maker/api/files/' + task.file_path, task.annotations_json);
          }
        }, 50);
      });
    },

    // ============================================================
    // Toggle Expand
    // ============================================================
    toggleExpand(taskId) {
      this.expandedTask = this.expandedTask === taskId ? null : taskId;
      // Render preview when expanding
      if (this.expandedTask === taskId) {
        const task = this.tasks.find(t => t.id === taskId);
        if (task) this.renderTaskPreview(task);
      }
      // Reset inline editors when collapsing
      if (this.expandedTask !== taskId) {
        this.editingSubtaskId = null;
        this.addingSubtaskForTask = null;
      }
    },

    // ============================================================
    // TASK CRUD
    // ============================================================

    resetNewTask() {
      this.newTask = { title: '', directive: '', description: '' };
    },

    // ============================================================
    // AI Import
    // ============================================================
    async uploadAndParse(event) {
      var file = event.target.files[0];
      if (!file) return;
      this.aiParsing = true;
      this.aiError = '';
      this.aiSuggestions = [];

      try {
        var formData = new FormData();
        formData.append('file', file);
        var resp = await fetch('/maker/api/recipes/' + this.recipeId + '/parse-technical-sheet', {
          method: 'POST',
          headers: { 'X-CSRFToken': this.csrfToken() },
          body: formData
        });
        var data = await resp.json();

        if (!resp.ok || data.error) {
          this.aiError = data.detail || {{ _("Errore nell'analisi del PDF")|tojson }};
        } else {
          this.aiSuggestions = data.suggested_tasks || [];
          if (!this.aiSuggestions.length) {
            this.aiError = {{ _("Nessun task identificato nel PDF")|tojson }};
          }
        }
      } catch (err) {
        console.error('AI parse error:', err);
        this.aiError = {{ _("Errore di connessione al server")|tojson }};
      }

      this.aiParsing = false;
      event.target.value = '';
    },

    async createTasksFromSuggestions() {
      this.aiCreating = true;
      var created = 0;

      for (var i = 0; i < this.aiSuggestions.length; i++) {
        var s = this.aiSuggestions[i];
        if (!s.title || !s.title.trim()) continue;

        try {
          var resp = await fetch('/maker/api/recipes/' + this.recipeId + '/tasks', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json', 'X-CSRFToken': this.csrfToken() },
            body: JSON.stringify({
              title: s.title.trim(),
              directive: (s.directive || '').trim() || null,
              description: (s.description || '').trim() || null
            })
          });
          var data = await resp.json();
          if (!data.error) {
            if (!data.subtasks) data.subtasks = [];
            this.tasks.push(data);
            created++;
          }
        } catch (err) {
          console.error('Create task error:', err);
        }
      }

      this.aiCreating = false;
      this.showAiImport = false;
      this.aiSuggestions = [];
      if (created > 0) {
        this.successMessage = created + ' ' + {{ _("task creati dalla scheda tecnica")|tojson }};
      }
    },

    async addTask() {
      if (!this.newTask.title.trim()) return;
      this.saving = true;
      this.errorMessage = '';

      try {
        const resp = await fetch(`/maker/api/recipes/${this.recipeId}/tasks`, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'X-CSRFToken': this.csrfToken()
          },
          body: JSON.stringify({
            title: this.newTask.title.trim(),
            directive: this.newTask.directive.trim() || null,
            description: this.newTask.description.trim() || null
          })
        });

        const data = await resp.json();

        if (data.error) {
          this.errorMessage = data.detail || {{ _("Errore nella creazione del task")|tojson }};
        } else {
          // Ensure subtasks array exists
          if (!data.subtasks) data.subtasks = [];
          this.tasks.push(data);
          this.resetNewTask();
          this.showAddTask = false;
          this.expandedTask = data.id;
          this.successMessage = {{ _("Task creato con successo")|tojson }};
        }
      } catch (err) {
        console.error('addTask error:', err);
        this.errorMessage = {{ _("Errore di connessione al server")|tojson }};
      }

      this.saving = false;
    },

    startEditTask(task) {
      this.editingTask = task.id;
      this.editTaskData = {
        title: task.title,
        directive: task.directive || '',
        description: task.description || ''
      };
      // Ensure expanded
      this.expandedTask = task.id;
    },

    cancelEditTask() {
      this.editingTask = null;
      this.editTaskData = { title: '', directive: '', description: '' };
    },

    async updateTask(taskId) {
      if (!this.editTaskData.title.trim()) return;
      this.saving = true;
      this.errorMessage = '';

      try {
        const resp = await fetch(`/maker/api/tasks/${taskId}`, {
          method: 'PUT',
          headers: {
            'Content-Type': 'application/json',
            'X-CSRFToken': this.csrfToken()
          },
          body: JSON.stringify({
            title: this.editTaskData.title.trim(),
            directive: this.editTaskData.directive.trim() || null,
            description: this.editTaskData.description.trim() || null
          })
        });

        const data = await resp.json();

        if (data.error) {
          this.errorMessage = data.detail || {{ _("Errore nel salvataggio del task")|tojson }};
        } else {
          // Update local state
          const idx = this.tasks.findIndex(t => t.id === taskId);
          if (idx !== -1) {
            // Preserve subtasks from local state since PUT may not return them
            const existingSubtasks = this.tasks[idx].subtasks;
            this.tasks[idx] = { ...this.tasks[idx], ...data };
            if (!this.tasks[idx].subtasks) {
              this.tasks[idx].subtasks = existingSubtasks || [];
            }
          }
          this.cancelEditTask();
          this.successMessage = {{ _("Task aggiornato")|tojson }};
        }
      } catch (err) {
        console.error('updateTask error:', err);
        this.errorMessage = {{ _("Errore di connessione al server")|tojson }};
      }

      this.saving = false;
    },

    confirmDeleteTask(task) {
      this.deleteTargetTask = task;
      this.deleteTaskModal = true;
    },

    async deleteTask(taskId) {
      this.saving = true;
      this.errorMessage = '';

      try {
        const resp = await fetch(`/maker/api/tasks/${taskId}`, {
          method: 'DELETE',
          headers: { 'X-CSRFToken': this.csrfToken() }
        });

        if (resp.ok || resp.status === 204) {
          this.tasks = this.tasks.filter(t => t.id !== taskId);
          this.deleteTaskModal = false;
          this.deleteTargetTask = null;
          if (this.expandedTask === taskId) this.expandedTask = null;
          this.successMessage = {{ _("Task eliminato")|tojson }};
        } else {
          const data = await resp.json();
          this.errorMessage = data.detail || {{ _("Errore nell'eliminazione del task")|tojson }};
        }
      } catch (err) {
        console.error('deleteTask error:', err);
        this.errorMessage = {{ _("Errore di connessione al server")|tojson }};
      }

      this.saving = false;
    },

    // ============================================================
    // DRAG & DROP REORDER
    // ============================================================

    handleDragStart(event, task) {
      this.dragState.dragging = task.id;
      event.dataTransfer.effectAllowed = 'move';
      // Required for Firefox
      event.dataTransfer.setData('text/plain', String(task.id));
    },

    handleDragEnd(event) {
      this.dragState = { dragging: null, over: null, position: null };
    },

    handleDragOver(event, task) {
      if (this.dragState.dragging === task.id) return;
      event.dataTransfer.dropEffect = 'move';

      // Determine above/below based on mouse position
      const rect = event.currentTarget.getBoundingClientRect();
      const midY = rect.top + rect.height / 2;
      this.dragState.over = task.id;
      this.dragState.position = event.clientY < midY ? 'above' : 'below';
    },

    handleDragLeave(event, task) {
      // Only clear if leaving the card entirely
      if (!event.currentTarget.contains(event.relatedTarget)) {
        if (this.dragState.over === task.id) {
          this.dragState.over = null;
          this.dragState.position = null;
        }
      }
    },

    async handleDrop(event, targetTask) {
      const draggedId = this.dragState.dragging;
      const targetId = targetTask.id;

      if (draggedId === targetId) {
        this.dragState = { dragging: null, over: null, position: null };
        return;
      }

      // Reorder locally
      const draggedIdx = this.tasks.findIndex(t => t.id === draggedId);
      const targetIdx = this.tasks.findIndex(t => t.id === targetId);

      if (draggedIdx === -1 || targetIdx === -1) return;

      // Remove dragged task
      const [dragged] = this.tasks.splice(draggedIdx, 1);

      // Recalculate target index after removal
      let insertIdx = this.tasks.findIndex(t => t.id === targetId);
      if (this.dragState.position === 'below') insertIdx += 1;

      // Insert at new position
      this.tasks.splice(insertIdx, 0, dragged);

      this.dragState = { dragging: null, over: null, position: null };

      // Persist to server
      await this.reorderTasks();
    },

    async reorderTasks() {
      this.errorMessage = '';

      const taskIds = this.tasks.map(t => t.id);

      try {
        const resp = await fetch('/maker/api/tasks/reorder', {
          method: 'PUT',
          headers: {
            'Content-Type': 'application/json',
            'X-CSRFToken': this.csrfToken()
          },
          body: JSON.stringify({ task_ids: taskIds })
        });

        const data = await resp.json();

        if (data.error) {
          this.errorMessage = data.detail || {{ _("Errore nel riordinamento")|tojson }};
        }
      } catch (err) {
        console.error('reorderTasks error:', err);
        this.errorMessage = {{ _("Errore di connessione al server")|tojson }};
      }
    },

    // ============================================================
    // SUBTASK CRUD
    // ============================================================

    nextMarkerNumber(task) {
      if (!task.subtasks || task.subtasks.length === 0) return 1;
      return Math.max(...task.subtasks.map(s => s.marker_number || 0)) + 1;
    },

    resetNewSubtask(taskId) {
      const task = this.tasks.find(t => t.id === taskId);
      this.newSubtask = {
        marker_number: task ? this.nextMarkerNumber(task) : 1,
        description: '',
        measurement_type: '',
        nominal: null,
        utl: null,
        uwl: null,
        lwl: null,
        ltl: null,
        unit: 'mm'
      };
    },

    openAddSubtask(task) {
      this.editingSubtaskId = null;
      this.addingSubtaskForTask = task.id;
      this.resetNewSubtask(task.id);
    },

    async addSubtask(taskId) {
      if (!this.newSubtask.description.trim()) return;
      this.saving = true;
      this.errorMessage = '';

      const payload = {
        marker_number: this.newSubtask.marker_number || 1,
        description: this.newSubtask.description.trim(),
        measurement_type: this.newSubtask.measurement_type || null,
        nominal: this.newSubtask.nominal,
        utl: this.newSubtask.utl,
        uwl: this.newSubtask.uwl,
        lwl: this.newSubtask.lwl,
        ltl: this.newSubtask.ltl,
        unit: this.newSubtask.unit || 'mm'
      };

      try {
        const resp = await fetch(`/maker/api/tasks/${taskId}/subtasks`, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'X-CSRFToken': this.csrfToken()
          },
          body: JSON.stringify(payload)
        });

        const data = await resp.json();

        if (data.error) {
          this.errorMessage = data.detail || {{ _("Errore nella creazione della misurazione")|tojson }};
        } else {
          const task = this.tasks.find(t => t.id === taskId);
          if (task) {
            if (!task.subtasks) task.subtasks = [];
            task.subtasks.push(data);
          }
          this.resetNewSubtask(taskId);
          this.successMessage = {{ _("Misurazione aggiunta")|tojson }};
        }
      } catch (err) {
        console.error('addSubtask error:', err);
        this.errorMessage = {{ _("Errore di connessione al server")|tojson }};
      }

      this.saving = false;
    },

    startEditSubtask(subtask, taskId) {
      // Open the same form used for adding, but pre-filled with existing data
      this.editingSubtaskId = subtask.id;
      this.addingSubtaskForTask = taskId;
      this.newSubtask = {
        marker_number: subtask.marker_number,
        description: subtask.description || '',
        measurement_type: subtask.measurement_type || '',
        nominal: subtask.nominal,
        utl: subtask.utl,
        uwl: subtask.uwl,
        lwl: subtask.lwl,
        ltl: subtask.ltl,
        unit: subtask.unit || 'mm'
      };
    },

    cancelSubtaskForm(taskId) {
      this.editingSubtaskId = null;
      this.addingSubtaskForTask = null;
      this.resetNewSubtask(taskId);
    },

    async updateSubtask(subtaskId, taskId) {
      if (!this.newSubtask.description.trim()) return;
      this.saving = true;
      this.errorMessage = '';

      const payload = {
        marker_number: this.newSubtask.marker_number || 1,
        description: this.newSubtask.description.trim(),
        measurement_type: this.newSubtask.measurement_type || null,
        nominal: this.newSubtask.nominal,
        utl: this.newSubtask.utl,
        uwl: this.newSubtask.uwl,
        lwl: this.newSubtask.lwl,
        ltl: this.newSubtask.ltl,
        unit: this.newSubtask.unit || 'mm'
      };

      try {
        const resp = await fetch(`/maker/api/subtasks/${subtaskId}`, {
          method: 'PUT',
          headers: {
            'Content-Type': 'application/json',
            'X-CSRFToken': this.csrfToken()
          },
          body: JSON.stringify(payload)
        });

        const data = await resp.json();

        if (data.error) {
          this.errorMessage = data.detail || {{ _("Errore nel salvataggio della misurazione")|tojson }};
        } else {
          // Update local state
          const task = this.tasks.find(t => t.id === taskId);
          if (task && task.subtasks) {
            const idx = task.subtasks.findIndex(s => s.id === subtaskId);
            if (idx !== -1) {
              task.subtasks[idx] = { ...task.subtasks[idx], ...data };
            }
          }
          this.cancelSubtaskForm(taskId);
          this.successMessage = {{ _("Misurazione aggiornata")|tojson }};
        }
      } catch (err) {
        console.error('updateSubtask error:', err);
        this.errorMessage = {{ _("Errore di connessione al server")|tojson }};
      }

      this.saving = false;
    },

    confirmDeleteSubtask(subtask, taskId) {
      this.deleteTargetSubtask = subtask;
      this.deleteSubtaskParentId = taskId;
      this.deleteSubtaskModal = true;
    },

    async deleteSubtask(subtaskId, taskId) {
      this.saving = true;
      this.errorMessage = '';

      try {
        const resp = await fetch(`/maker/api/subtasks/${subtaskId}`, {
          method: 'DELETE',
          headers: { 'X-CSRFToken': this.csrfToken() }
        });

        if (resp.ok || resp.status === 204) {
          const task = this.tasks.find(t => t.id === taskId);
          if (task && task.subtasks) {
            task.subtasks = task.subtasks.filter(s => s.id !== subtaskId);
          }
          this.deleteSubtaskModal = false;
          this.deleteTargetSubtask = null;
          this.deleteSubtaskParentId = null;
          this.successMessage = {{ _("Misurazione eliminata")|tojson }};
        } else {
          const data = await resp.json();
          this.errorMessage = data.detail || {{ _("Errore nell'eliminazione della misurazione")|tojson }};
        }
      } catch (err) {
        console.error('deleteSubtask error:', err);
        this.errorMessage = {{ _("Errore di connessione al server")|tojson }};
      }

      this.saving = false;
    },

    // ============================================================
    // TASK FILE UPLOAD
    // ============================================================

    async uploadTaskFile(taskId, file, task) {
      if (!file) return;

      const allowedTypes = ['image/png', 'image/jpeg', 'image/jpg', 'image/webp', 'application/pdf'];
      if (!allowedTypes.includes(file.type)) {
        this.errorMessage = {{ _("Formato file non supportato. Usa PNG, JPG o PDF.")|tojson }};
        return;
      }

      if (file.size > 20 * 1024 * 1024) {
        this.errorMessage = {{ _("File troppo grande. Dimensione massima: 20MB.")|tojson }};
        return;
      }

      this.saving = true;
      this.errorMessage = '';

      try {
        // 1. Upload file
        const formData = new FormData();
        formData.append('file', file);
        formData.append('recipe_id', this.recipeId);

        const uploadResp = await fetch('/maker/api/upload', {
          method: 'POST',
          headers: { 'X-CSRFToken': this.csrfToken() },
          body: formData
        });

        const uploadData = await uploadResp.json();
        if (uploadData.error) {
          this.errorMessage = uploadData.detail || {{ _("Errore durante il caricamento del file")|tojson }};
          this.saving = false;
          return;
        }

        // Determine file type
        const fileType = file.type === 'application/pdf' ? 'pdf' : 'image';

        // 2. Update task with file_path
        const updateResp = await fetch(`/maker/api/tasks/${taskId}`, {
          method: 'PUT',
          headers: {
            'Content-Type': 'application/json',
            'X-CSRFToken': this.csrfToken()
          },
          body: JSON.stringify({
            file_path: uploadData.file_path,
            file_type: fileType
          })
        });

        const updateData = await updateResp.json();
        if (updateData.error) {
          this.errorMessage = updateData.detail || {{ _("Errore nel salvataggio del task")|tojson }};
          this.saving = false;
          return;
        }

        // 3. Update local state
        task.file_path = uploadData.file_path;
        task.file_type = fileType;
        this.successMessage = {{ _("File caricato con successo")|tojson }};

        // Re-render preview canvas with new image
        this.renderTaskPreview(task);

      } catch (err) {
        console.error('uploadTaskFile error:', err);
        this.errorMessage = {{ _("Errore di connessione al server")|tojson }};
      }

      this.saving = false;
    },

    // ============================================================
    // TOLERANCE BAR VISUALIZATION
    // ============================================================

    toleranceTitle(s) {
      return `LTL: ${s.ltl} | LWL: ${s.lwl ?? '-'} | Nom: ${s.nominal} | UWL: ${s.uwl ?? '-'} | UTL: ${s.utl}`;
    },

    toleranceSegStyle(s, segment) {
      // Compute proportional widths for tolerance bar segments.
      // Full range: LTL to UTL. Nominal sits in the middle.
      const ltl = s.ltl ?? s.nominal;
      const utl = s.utl ?? s.nominal;
      const lwl = s.lwl ?? ltl;
      const uwl = s.uwl ?? utl;
      const nom = s.nominal;
      const range = utl - ltl;

      if (range <= 0) return 'width: 20%';

      const pct = (v) => ((v - ltl) / range) * 100;

      switch (segment) {
        case 'fail-low':
          return `width: ${pct(lwl)}%`;
        case 'warn-low':
          return `width: ${pct(nom) - pct(lwl)}%`;
        case 'nominal':
          // Small central band around nominal
          return `width: ${Math.max(pct(uwl) - pct(nom), 0)}%`;
        case 'warn-high':
          // From UWL towards nominal already covered; this is UWL to UTL gap
          // Re-compute: fail-low = 0..lwl, warn-low = lwl..nom, nominal = nom..uwl, warn-high = uwl..utl, fail-high = utl..end
          // Since range = utl-ltl and pct(utl)=100, we use:
          return `width: ${100 - pct(uwl)}%`;
        case 'fail-high':
          // Already at utl which is 100%, so no extra fail-high in simple model.
          // Instead, restructure: LTL..LWL | LWL..NOM | NOM..UWL | UWL..UTL
          return 'width: 0%';
        default:
          return 'width: 0%';
      }
    }
  };
}
</script>
{% endblock %}
