<%!-- MediaBrowser LiveComponent template.
     All phx-* events route to the component via phx-target={@myself} on the root div. --%>
<div id={@id} phx-target={@myself} phx-hook="MediaDragDrop">
  <style>
    @keyframes rename-pulse {
      0%, 100% { opacity: 1; }
      50% { opacity: 0.5; }
    }
    .renaming-preview {
      animation: rename-pulse 1.5s ease-in-out infinite;
      color: oklch(var(--p));
      font-style: italic;
    }

    /* Compact-mode overrides for the Comments component when embedded
       inside the modal viewer's narrow sidebar. The component itself is
       designed for full-width post-detail pages; here we shrink the
       internal typography, paddings, avatars, and button gaps so the
       author/actions row stops truncating in ~360px of space. */
    .leaf-comments-compact h2 { font-size: 1rem; line-height: 1.5rem; }
    .leaf-comments-compact h3 { font-size: 0.8125rem; line-height: 1.25rem; }
    .leaf-comments-compact .text-sm { font-size: 0.75rem; line-height: 1rem; }
    .leaf-comments-compact .text-xs { font-size: 0.6875rem; line-height: 0.95rem; }
    .leaf-comments-compact .p-3 { padding: 0.5rem; }
    .leaf-comments-compact .p-4 { padding: 0.625rem; }
    .leaf-comments-compact .gap-2 { gap: 0.25rem; }
    .leaf-comments-compact .gap-4 { gap: 0.5rem; }
    .leaf-comments-compact .mb-2 { margin-bottom: 0.25rem; }
    .leaf-comments-compact .mt-4 { margin-top: 0.5rem; }
    .leaf-comments-compact .w-5 { width: 1rem; }
    .leaf-comments-compact .h-5 { height: 1rem; }
    .leaf-comments-compact .w-4 { width: 0.875rem; }
    .leaf-comments-compact .h-4 { height: 0.875rem; }
    .leaf-comments-compact .btn-xs { min-height: 1.5rem; height: 1.5rem; padding: 0 0.4rem; font-size: 0.6875rem; }
    .leaf-comments-compact .btn-sm { min-height: 1.75rem; height: 1.75rem; font-size: 0.75rem; }
  </style>

  <%!-- Scope-invalid guard: scope folder was deleted --%>
  <%= if @scope_invalid do %>
    <div role="alert" class="alert alert-warning mb-4">
      <.icon name="hero-exclamation-triangle" class="w-5 h-5 shrink-0" />
      <span>
        {gettext(
          "The configured scope folder no longer exists. The media browser is disabled until the scope is reconfigured."
        )}
      </span>
    </div>
  <% else %>
    <%!-- Upload Section --%>
    <%= if @show_upload and assigns[:parent_uploads] do %>
      <div class="card bg-base-100 shadow-xl mb-6">
        <div class="card-body">
          <div class="flex items-center gap-3 mb-4">
            <h2 class="card-title text-xl">{gettext("Upload Media")}</h2>
            <button
              phx-click="toggle_upload"
              phx-target={@myself}
              class="btn btn-sm btn-error gap-2"
            >
              <.icon name="hero-x-mark" class="w-4 h-4" /> {gettext("Cancel")}
            </button>
          </div>
          <%= if @has_buckets do %>
            <.file_upload
              upload={@parent_uploads.media_files}
              label={gettext("Upload Media Files")}
              icon="hero-cloud-arrow-up"
              accept_description={gettext("All file types supported")}
              max_size_description={gettext("%{mb}MB per file", mb: @max_upload_size_mb)}
            />
          <% else %>
            <div class="alert alert-warning">
              <.icon name="hero-exclamation-triangle" class="w-6 h-6" />
              <div>
                <h3 class="font-bold">{gettext("No Storage Buckets Configured")}</h3>
                <div class="text-sm mt-1">
                  <.link
                    navigate={PhoenixKit.Utils.Routes.path("/admin/settings/media")}
                    class="link link-primary font-semibold"
                  >
                    {gettext("Configure Storage Buckets")}
                  </.link>
                </div>
              </div>
            </div>
          <% end %>
        </div>
      </div>
    <% end %>

    <%!-- Main Layout: Sidebar + Content in a unified card --%>
    <div class="card bg-base-100 shadow-xl">
      <div class="card-body p-4 flex flex-row gap-0">
        <%!-- Folder Sidebar --%>
        <.folder_explorer
          id="media-browser-sidebar"
          myself={@myself}
          folder_tree={@folder_tree}
          current_folder={@current_folder}
          expanded_folders={@expanded_folders}
          scope_folder_id={@scope_folder_id}
          scope_folder_name={@scope_folder_name}
          renaming_folder={@renaming_folder}
          renaming_source={@renaming_source}
          renaming_text={@renaming_text}
          filter_trash={@filter_trash}
          file_view={@file_view}
          sidebar_collapsed={@sidebar_collapsed}
          trash_count={@trash_count}
        />

        <%!-- Main content area --%>
        <div class="flex-1 min-w-0 pl-4">
          <%!-- Hidden upload input for folder drag-drop (always in DOM when in a folder) --%>
          <%= if @has_buckets && !@show_upload && assigns[:parent_uploads] do %>
            <form
              phx-change="validate"
              id="folder-drop-upload-form"
              class="hidden"
            >
              <.live_file_input upload={@parent_uploads.media_files} />
            </form>
          <% end %>

          <div>
            <div
              class="p-2"
              id={if @has_buckets, do: "folder-drop-upload"}
              phx-hook={if @has_buckets, do: "FolderDropUpload"}
              phx-target={if @has_buckets, do: @myself}
            >
              <%!-- Inline upload progress for drag-drop (no modal) --%>
              <%= if !@show_upload && assigns[:parent_uploads] && length(@parent_uploads.media_files.entries) > 0 do %>
                <div class="space-y-2 mb-4">
                  <%= for entry <- @parent_uploads.media_files.entries do %>
                    <div class="flex items-center gap-3 p-3 border border-base-300 rounded-lg bg-base-100">
                      <div class="flex-1">
                        <p class="font-medium text-sm truncate">{entry.client_name}</p>
                        <div class="flex gap-2 items-center mt-1">
                          <progress
                            value={entry.progress}
                            max="100"
                            class="progress progress-primary progress-sm flex-1"
                          >
                            {entry.progress}%
                          </progress>
                          <span class="text-xs text-base-content/60 min-w-max">
                            {entry.progress}%
                          </span>
                        </div>
                      </div>
                    </div>
                  <% end %>
                </div>
              <% end %>

              <%!--
                Breadcrumbs. `@breadcrumbs` is the full ancestor chain INCLUDING
                the current folder (with the scope folder dropped when scoped),
                so we iterate `Enum.drop(@breadcrumbs, -1)` for the clickable
                middle and render the current folder once at the end. When
                scoped, the leading "root" button shows the scope folder's
                name (e.g. "banana") instead of "All Media".
              --%>
              <%= if @current_folder do %>
                <nav class="breadcrumbs text-sm mb-2">
                  <ul>
                    <li>
                      <button
                        phx-click="navigate_root"
                        phx-target={@myself}
                        class="hover:underline text-primary"
                      >
                        {if @scope_folder_id,
                          do: @scope_folder_name,
                          else: gettext("All Media")}
                      </button>
                    </li>
                    <%= for folder <- Enum.drop(@breadcrumbs, -1) do %>
                      <li>
                        <button
                          phx-click="navigate_folder"
                          phx-target={@myself}
                          phx-value-folder-uuid={folder.uuid}
                          class="hover:underline text-primary"
                        >
                          {folder.name}
                        </button>
                      </li>
                    <% end %>
                    <li>
                      {@current_folder.name}
                    </li>
                  </ul>
                </nav>
              <% end %>

              <%!-- Search Bar (toggleable) --%>
              <%= if @show_search or @search_query != "" do %>
                <form phx-change="search" phx-target={@myself} phx-submit="search" class="mb-4">
                  <label class="input input-bordered input-sm w-full flex items-center gap-2">
                    <.icon name="hero-magnifying-glass" class="w-4 h-4 text-base-content/40" />
                    <input
                      type="text"
                      name="q"
                      value={@search_query}
                      placeholder={gettext("Search files...")}
                      class="grow bg-transparent border-none outline-none focus:outline-none"
                      phx-debounce="300"
                      autocomplete="off"
                      phx-mounted={JS.focus()}
                    />
                    <%= if @search_query != "" do %>
                      <button
                        type="button"
                        phx-click="clear_search"
                        phx-target={@myself}
                        class="btn btn-ghost btn-xs btn-circle"
                      >
                        <.icon name="hero-x-mark" class="w-4 h-4" />
                      </button>
                    <% end %>
                  </label>
                </form>
              <% end %>

              <%!-- Header --%>
              <div class="flex justify-between items-center mb-4">
                <%= if @select_mode do %>
                  <%!-- Selection Mode Header --%>
                  <div class="flex items-center gap-2 flex-wrap">
                    <button
                      phx-click="toggle_select_mode"
                      phx-target={@myself}
                      class="btn btn-sm btn-error gap-2"
                    >
                      <.icon name="hero-x-mark" class="w-4 h-4" /> {gettext("Cancel")}
                    </button>
                    <span class="text-sm font-semibold">
                      {ngettext(
                        "%{count} selected",
                        "%{count} selected",
                        MapSet.size(@selected_files) + MapSet.size(@selected_folders)
                      )}
                    </span>
                    <button
                      phx-click="show_move_modal"
                      phx-target={@myself}
                      class="btn btn-sm btn-primary gap-1"
                    >
                      <.icon name="hero-folder-arrow-down" class="w-4 h-4" /> {gettext("Move")}
                    </button>
                    <%= if MapSet.size(@selected_files) + MapSet.size(@selected_folders) > 0 do %>
                      <div class="dropdown dropdown-end">
                        <label
                          tabindex="0"
                          class="btn btn-sm btn-ghost px-2"
                          title={gettext("More actions")}
                        >
                          <.icon name="hero-ellipsis-horizontal" class="w-5 h-5" />
                        </label>
                        <ul
                          tabindex="0"
                          class="dropdown-content menu bg-base-100 rounded-box z-[1] w-44 p-2 shadow-lg border border-base-200"
                        >
                          <%= if MapSet.size(@selected_files) > 0 do %>
                            <li>
                              <button phx-click="download_selected" phx-target={@myself}>
                                <.icon name="hero-arrow-down-tray" class="w-4 h-4" /> {gettext(
                                  "Download"
                                )}
                              </button>
                            </li>
                          <% end %>
                          <li>
                            <button
                              phx-click="delete_selected"
                              phx-target={@myself}
                              data-confirm={
                                delete_selected_confirm(
                                  @selected_files,
                                  @selected_folders,
                                  @filter_trash
                                )
                              }
                              class="text-error"
                            >
                              <.icon name="hero-trash" class="w-4 h-4" />
                              {if @filter_trash,
                                do: gettext("Delete permanently"),
                                else: gettext("Delete")}
                            </button>
                          </li>
                        </ul>
                      </div>
                    <% end %>
                    <button
                      phx-click="select_all"
                      phx-target={@myself}
                      class="btn btn-sm btn-ghost"
                    >
                      {gettext("Select all")}
                    </button>
                    <button
                      phx-click="deselect_all"
                      phx-target={@myself}
                      class="btn btn-sm btn-ghost"
                    >
                      {gettext("Clear")}
                    </button>
                  </div>
                <% else %>
                  <%!-- Normal Header --%>
                  <div class="flex items-center gap-3 flex-wrap">
                    <h2 class="card-title text-xl">
                      <%= cond do %>
                        <% @filter_trash -> %>
                          {gettext("Trash")}
                        <% @filter_orphaned -> %>
                          {gettext("Orphaned Files")}
                        <% @file_view == "all" -> %>
                          {gettext("All Files")}
                        <% @current_folder -> %>
                          {@current_folder.name}
                        <% true -> %>
                          {@scope_folder_name}
                      <% end %>
                    </h2>
                    <%= if @filter_trash do %>
                      <%= if @select_mode and MapSet.size(@selected_files) > 0 do %>
                        <button
                          phx-click="restore_selected"
                          phx-target={@myself}
                          class="btn btn-sm btn-success gap-1"
                        >
                          <.icon name="hero-arrow-uturn-left" class="w-4 h-4" /> {gettext(
                            "Restore"
                          )}
                        </button>
                      <% end %>
                      <%= if @total_count > 0 do %>
                        <button
                          phx-click="empty_trash"
                          phx-target={@myself}
                          data-confirm={
                            ngettext(
                              "Permanently delete %{count} trashed file?",
                              "Permanently delete all %{count} trashed files?",
                              @total_count
                            )
                          }
                          class="btn btn-sm btn-error gap-1"
                        >
                          <.icon name="hero-trash" class="w-4 h-4" /> {gettext("Empty Trash")}
                        </button>
                      <% end %>
                    <% end %>
                    <button
                      phx-click="toggle_search"
                      phx-target={@myself}
                      class={[
                        "btn btn-sm btn-circle",
                        if(@show_search or @search_query != "",
                          do: "btn-primary",
                          else: "btn-ghost"
                        )
                      ]}
                      title={gettext("Search")}
                    >
                      <.icon name="hero-magnifying-glass" class="w-4 h-4" />
                    </button>
                    <%= unless @show_upload or @filter_trash do %>
                      <button
                        phx-click="toggle_upload"
                        phx-target={@myself}
                        class="btn btn-sm btn-primary gap-2"
                      >
                        <.icon name="hero-plus" class="w-4 h-4" /> {gettext("Add Media")}
                      </button>
                    <% end %>
                    <button
                      phx-click="toggle_select_mode"
                      phx-target={@myself}
                      class="btn btn-sm btn-secondary btn-outline gap-2"
                      phx-disable-with={gettext("Select")}
                    >
                      <.icon name="hero-check-circle" class="w-4 h-4" /> {gettext("Select")}
                    </button>
                    <button
                      phx-click="create_untitled_folder"
                      phx-target={@myself}
                      class="btn btn-sm btn-ghost gap-2 lg:hidden"
                    >
                      <.icon name="hero-folder-plus" class="w-4 h-4" /> {gettext("New Folder")}
                    </button>
                    <%!-- Orphan filter is only meaningful at the global root (no scope set) --%>
                    <%= if is_nil(@scope_folder_id) do %>
                      <button
                        phx-click="toggle_orphan_filter"
                        phx-target={@myself}
                        class={[
                          "btn btn-sm gap-2",
                          if(@filter_orphaned, do: "btn-warning", else: "btn-ghost")
                        ]}
                      >
                        <.icon name="hero-funnel" class="w-4 h-4" />
                        <%= if @filter_orphaned do %>
                          {gettext("Showing orphaned (%{count})", count: @orphaned_count)}
                        <% else %>
                          {gettext("Find orphaned (%{count})", count: @orphaned_count)}
                        <% end %>
                      </button>
                      <%= if @filter_orphaned && @total_count > 0 do %>
                        <button
                          phx-click="delete_all_orphaned"
                          phx-target={@myself}
                          data-confirm={
                            ngettext(
                              "Delete %{count} orphaned file?",
                              "Delete all %{count} orphaned files?",
                              @total_count
                            )
                          }
                          class="btn btn-sm btn-error gap-2"
                        >
                          <.icon name="hero-trash" class="w-4 h-4" /> {gettext(
                            "Delete all orphaned"
                          )}
                        </button>
                      <% end %>
                    <% end %>
                  </div>
                <% end %>
                <div class="flex items-center gap-2">
                  <%= if @total_count > 0 do %>
                    <div class="join">
                      <button
                        phx-click="set_view_mode"
                        phx-target={@myself}
                        phx-value-mode="grid"
                        data-view-mode="grid"
                        class={[
                          "btn btn-xs join-item",
                          if(@view_mode == "grid", do: "btn-active")
                        ]}
                        title={gettext("Grid view")}
                      >
                        <.icon name="hero-squares-2x2" class="w-3 h-3" />
                      </button>
                      <button
                        phx-click="set_view_mode"
                        phx-target={@myself}
                        phx-value-mode="list"
                        data-view-mode="list"
                        class={[
                          "btn btn-xs join-item",
                          if(@view_mode == "list", do: "btn-active")
                        ]}
                        title={gettext("List view")}
                      >
                        <.icon name="hero-bars-3-bottom-left" class="w-3 h-3" />
                      </button>
                    </div>
                    <.pagination_info
                      page={@current_page}
                      per_page={@per_page}
                      total_count={@total_count}
                    />
                  <% end %>
                </div>
              </div>

              <%!--
                Main-area drop target. Dropping a folder or file onto the
                body wraps the move into `@current_folder` (or the scope
                root when at the top of a scoped browser). Outline-only
                via `data-drop-no-bg` — a 10% primary tint across the
                whole content area is overwhelming compared to the
                folder cards.

                Omitted in trash / all-files views: the `if` produces
                `nil` and `data-drop-folder={nil}` strips the attribute,
                so the wrapper isn't a drop target there.
              --%>
              <div
                class="rounded-lg"
                data-drop-folder={
                  if not @filter_trash and @file_view != "all" do
                    if @current_folder, do: @current_folder.uuid, else: "root"
                  end
                }
                data-drop-no-bg
              >
                <%= if @uploaded_files == [] && (@folders == [] or @file_view == "all") do %>
                  <%!-- Empty state --%>
                  <div class={[
                    "rounded-lg p-8 text-center",
                    if(@current_folder,
                      do: "border-2 border-dashed border-base-300 bg-base-200/50",
                      else: "bg-base-200"
                    )
                  ]}>
                    <%= cond do %>
                      <% @filter_trash -> %>
                        <.icon
                          name="hero-trash"
                          class="w-12 h-12 mx-auto text-base-content/30 mb-2"
                        />
                        <p class="text-base-content/70">{gettext("Trash is empty.")}</p>
                        <p class="text-base-content/50 text-sm mt-1">
                          {gettext("Deleted files will appear here")}
                        </p>
                      <% @current_folder -> %>
                        <.icon
                          name="hero-cloud-arrow-up"
                          class="w-12 h-12 mx-auto text-base-content/30 mb-2"
                        />
                        <p class="text-base-content/70">{gettext("This folder is empty.")}</p>
                        <p class="text-base-content/50 text-sm mt-1">
                          {gettext("Drop files here or click \"Add Media\" to upload")}
                        </p>
                      <% @file_view == "all" -> %>
                        <.icon
                          name="hero-folder-open"
                          class="w-12 h-12 mx-auto text-base-content/30 mb-2"
                        />
                        <p class="text-base-content/70">{gettext("No files found.")}</p>
                      <% true -> %>
                        <.icon
                          name="hero-folder-open"
                          class="w-12 h-12 mx-auto text-base-content/30 mb-2"
                        />
                        <p class="text-base-content/70">
                          {gettext("No media uploaded yet. Upload your first file above!")}
                        </p>
                    <% end %>
                  </div>
                <% else %>
                  <%= if @view_mode == "grid" do %>
                    <%!-- Grid View --%>
                    <div
                      data-media-grid
                      class="grid grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-3"
                    >
                      <%!-- Folders --%>
                      <%= for folder <- if(@file_view == "all", do: [], else: @folders) do %>
                        <div
                          data-drop-folder={folder.uuid}
                          data-draggable-folder={folder.uuid}
                          data-selected={
                            if @select_mode && MapSet.member?(@selected_folders, folder.uuid),
                              do: "true"
                          }
                          class={[
                            "group relative flex flex-col items-center justify-center aspect-square bg-base-200 rounded-lg cursor-pointer hover:bg-base-300 hover:shadow-lg transition-colors",
                            @select_mode && MapSet.member?(@selected_folders, folder.uuid) &&
                              "ring-2 ring-primary"
                          ]}
                          style={folder_bg_style(folder.color)}
                          phx-click={if @select_mode, do: "toggle_select_folder"}
                          phx-target={@myself}
                          phx-value-folder-uuid={if @select_mode, do: folder.uuid}
                        >
                          <%= if @select_mode do %>
                            <label class="absolute top-1 left-1 z-10 cursor-pointer">
                              <input
                                type="checkbox"
                                class="checkbox checkbox-primary checkbox-sm"
                                checked={MapSet.member?(@selected_folders, folder.uuid)}
                                phx-click="toggle_select_folder"
                                phx-target={@myself}
                                phx-value-folder-uuid={folder.uuid}
                              />
                            </label>
                          <% end %>
                          <%= if @renaming_folder == folder.uuid && @renaming_source == "content" do %>
                            <%!-- Inline rename --%>
                            <span style={folder_icon_style(folder.color)}>
                              <.icon name="hero-folder" class="w-20 h-20 mb-2" />
                            </span>
                            <form
                              phx-submit="rename_folder"
                              phx-target={@myself}
                              phx-change="rename_folder_input"
                              class="flex items-center gap-1 px-2 w-full"
                            >
                              <input type="hidden" name="folder_uuid" value={folder.uuid} />
                              <input
                                type="text"
                                name="name"
                                value={@renaming_text}
                                class="input input-bordered input-xs w-full text-center"
                                phx-mounted={JS.focus()}
                                required
                                phx-keydown="cancel_rename_folder"
                                phx-target={@myself}
                                phx-key="Escape"
                                phx-debounce="50"
                              />
                            </form>
                          <% else %>
                            <button
                              phx-click="navigate_folder"
                              phx-target={@myself}
                              phx-value-folder-uuid={folder.uuid}
                              class="flex flex-col items-center overflow-hidden w-full"
                            >
                              <span style={folder_icon_style(folder.color)}>
                                <.icon name="hero-folder" class="w-20 h-20 mb-1" />
                              </span>
                              <p class={[
                                "text-xs font-semibold text-center px-2 truncate w-full",
                                @renaming_folder == folder.uuid && @renaming_source != "content" &&
                                  "renaming-preview"
                              ]}>
                                <%= if @renaming_folder == folder.uuid && @renaming_text != "" do %>
                                  {@renaming_text}
                                <% else %>
                                  {folder.name}
                                <% end %>
                              </p>
                            </button>
                            <.table_row_menu
                              id={"folder-kebab-grid-#{folder.uuid}"}
                              class="!absolute top-1 right-1 opacity-0 group-hover:opacity-100"
                            >
                              <.table_row_menu_button
                                phx-click="start_rename_folder"
                                phx-target={@myself}
                                phx-value-folder-uuid={folder.uuid}
                                icon="hero-pencil"
                                label={gettext("Rename")}
                              />
                              <li role="none">
                                <div class="px-3 py-1.5">
                                  <span class="text-xs font-semibold text-base-content/50 mb-1 block">
                                    {gettext("Color")}
                                  </span>
                                  <div class="flex flex-wrap gap-1">
                                    <%= for color <- PhoenixKit.Modules.Storage.Folder.colors() do %>
                                      <button
                                        phx-click="change_folder_color"
                                        phx-target={@myself}
                                        phx-value-folder-uuid={folder.uuid}
                                        phx-value-color={color}
                                        class={[
                                          "w-4 h-4 rounded-full border-2 transition-transform hover:scale-125",
                                          if(
                                            folder.color == color ||
                                              (folder.color == nil && color == "default"),
                                            do: "border-base-content scale-110",
                                            else: "border-transparent"
                                          )
                                        ]}
                                        style={"background-color: #{folder_color_hex(color) || "oklch(var(--wa))"}"}
                                        title={color}
                                      >
                                      </button>
                                    <% end %>
                                  </div>
                                </div>
                              </li>
                              <.table_row_menu_button
                                phx-click="prepare_move_folder"
                                phx-target={@myself}
                                phx-value-folder-uuid={folder.uuid}
                                icon="hero-folder-arrow-down"
                                label={gettext("Move")}
                              />
                              <.table_row_menu_button
                                phx-click="delete_folder"
                                phx-target={@myself}
                                phx-value-id={folder.uuid}
                                data-confirm={
                                  gettext("Delete '%{name}'? Files move to parent.",
                                    name: folder.name
                                  )
                                }
                                icon="hero-trash"
                                label={gettext("Delete")}
                                variant="error"
                              />
                            </.table_row_menu>
                          <% end %>
                        </div>
                      <% end %>
                      <%!-- Files --%>
                      <%= for file <- @uploaded_files do %>
                        <div
                          data-draggable-file={file.file_uuid}
                          data-selected={
                            if @select_mode && MapSet.member?(@selected_files, file.file_uuid),
                              do: "true"
                          }
                          class={[
                            "group relative aspect-square bg-base-300 rounded-lg overflow-hidden hover:shadow-lg transition-shadow",
                            @select_mode && MapSet.member?(@selected_files, file.file_uuid) &&
                              "ring-2 ring-primary"
                          ]}
                        >
                          <%= if @select_mode do %>
                            <label class="absolute top-1 left-1 z-10 cursor-pointer">
                              <input
                                type="checkbox"
                                class="checkbox checkbox-primary checkbox-sm"
                                checked={MapSet.member?(@selected_files, file.file_uuid)}
                                phx-click="toggle_select"
                                phx-target={@myself}
                                phx-value-file-uuid={file.file_uuid}
                              />
                            </label>
                          <% end %>

                          <div
                            phx-click="click_file"
                            phx-target={@myself}
                            phx-value-file-uuid={file.file_uuid}
                            class="block w-full h-full cursor-pointer"
                          >
                            <.thumbnail_url :let={url} file={file} size={:small}>
                              <%= if url do %>
                                <img
                                  src={url}
                                  alt={file.filename}
                                  class="w-full h-full object-cover pointer-events-none group-hover:opacity-75 transition-opacity"
                                  onerror="this.parentElement.querySelector('.image-error-placeholder').style.display='grid';"
                                />
                                <div class="image-error-placeholder hidden absolute inset-0 bg-base-300 grid place-items-center text-base-content/50">
                                  <div class="flex flex-col items-center justify-center">
                                    <.icon name="hero-photo" class="w-12 h-12 mb-2 text-error" />
                                    <p class="text-xs font-semibold">
                                      {gettext("Image Missing")}
                                    </p>
                                  </div>
                                </div>
                              <% else %>
                                <div class="grid place-items-center w-full aspect-square text-base-content/50 group-hover:bg-base-200 transition-colors">
                                  <div class="flex flex-col items-center">
                                    <.icon
                                      name={file_icon(file.file_type)}
                                      class="w-12 h-12 mb-2"
                                    />
                                    <p class="text-sm font-semibold">
                                      {String.upcase(file.file_type)}
                                    </p>
                                  </div>
                                </div>
                              <% end %>
                            </.thumbnail_url>

                            <%= if file.file_type == "video" do %>
                              <div class="absolute top-2 left-2 bg-black/60 text-white p-1.5 rounded pointer-events-none flex items-center justify-center">
                                <.icon name="hero-play-solid" class="w-4 h-4" />
                              </div>
                            <% end %>

                            <%= if file.mime_type == "application/pdf" do %>
                              <div class="absolute top-2 left-2 bg-error/80 text-white px-2 py-0.5 rounded text-xs font-bold pointer-events-none">
                                PDF
                              </div>
                            <% end %>

                            <div class="absolute bottom-2 right-2 bg-black/60 text-white text-xs px-2 py-1 rounded pointer-events-none">
                              {format_file_size(file.size)}
                            </div>
                          </div>
                          <%!--
                          Per-file kebab menu. Sibling of the click target so
                          its buttons don't fire `click_file`. Mirrors the
                          folder kebab pattern: hidden by default, fades in
                          on hover. Always shows Delete; shows Download only
                          when an "original" URL is present.
                        --%>
                          <%= unless @select_mode do %>
                            <.table_row_menu
                              id={"file-kebab-grid-#{file.file_uuid}"}
                              class="!absolute top-1 right-1 opacity-0 group-hover:opacity-100"
                              trigger_class="!bg-black/40 hover:!bg-black/60 !text-white !border-0"
                            >
                              <.table_row_menu_button
                                :if={
                                  Map.get(file.urls || %{}, "original") ||
                                    Map.get(file.urls || %{}, :original)
                                }
                                phx-click="download_file"
                                phx-target={@myself}
                                phx-value-file-uuid={file.file_uuid}
                                icon="hero-arrow-down-tray"
                                label={gettext("Download")}
                              />
                              <.table_row_menu_button
                                phx-click="prepare_move_file"
                                phx-target={@myself}
                                phx-value-file-uuid={file.file_uuid}
                                icon="hero-folder-arrow-down"
                                label={gettext("Move")}
                              />
                              <.table_row_menu_button
                                phx-click="delete_file"
                                phx-target={@myself}
                                phx-value-file-uuid={file.file_uuid}
                                data-confirm={
                                  if @filter_trash,
                                    do:
                                      gettext(
                                        "Permanently delete '%{name}'? This cannot be undone.",
                                        name: file.filename
                                      )
                                }
                                icon="hero-trash"
                                label={
                                  if @filter_trash,
                                    do: gettext("Delete Permanently"),
                                    else: gettext("Move to Trash")
                                }
                                variant="error"
                              />
                            </.table_row_menu>
                          <% end %>
                        </div>
                      <% end %>
                    </div>
                  <% end %>
                  <%= if @view_mode == "list" do %>
                    <%!-- List View --%>
                    <div data-media-list class="overflow-x-auto">
                      <table class="table table-sm">
                        <thead>
                          <tr>
                            <%= if @select_mode do %>
                              <th class="w-8"></th>
                            <% end %>
                            <th class="w-12"></th>
                            <th>{gettext("Name")}</th>
                            <th>{gettext("Path")}</th>
                            <th>{gettext("Type")}</th>
                            <th>{gettext("Size")}</th>
                            <th>{gettext("Date")}</th>
                            <th class="w-10"></th>
                          </tr>
                        </thead>
                        <tbody>
                          <%!--
                          All folders rendered below share the same parent
                          (children of @current_folder, or of @scope when
                          we're at the scoped root), so the Path column
                          shows the same string for every row. Pre-compute
                          once per render — previously each row called the
                          breadcrumbs walk independently, an N+1 over
                          identical work.
                        --%>
                          <% folders_path = folder_list_path(@current_folder, @scope_folder_id) %>
                          <%!-- Folders --%>
                          <%= for folder <- if(@file_view == "all", do: [], else: @folders) do %>
                            <%= if @renaming_folder == folder.uuid && @renaming_source == "content" do %>
                              <tr style={
                                folder_bg_style(folder.color) ||
                                  "background-color: oklch(var(--b2))"
                              }>
                                <%= if @select_mode do %>
                                  <td></td>
                                <% end %>
                                <td>
                                  <div class="w-10 h-10 grid place-items-center">
                                    <span style={folder_icon_style(folder.color)}>
                                      <.icon name="hero-folder" class="w-10 h-10" />
                                    </span>
                                  </div>
                                </td>
                                <td colspan="5">
                                  <form
                                    phx-submit="rename_folder"
                                    phx-target={@myself}
                                    phx-change="rename_folder_input"
                                    class="flex items-center gap-2"
                                  >
                                    <input type="hidden" name="folder_uuid" value={folder.uuid} />
                                    <input
                                      type="text"
                                      name="name"
                                      value={@renaming_text}
                                      class="input input-bordered input-sm flex-1"
                                      phx-mounted={JS.focus()}
                                      required
                                      phx-keydown="cancel_rename_folder"
                                      phx-target={@myself}
                                      phx-key="Escape"
                                      phx-debounce="50"
                                    />
                                    <button type="submit" class="btn btn-sm btn-ghost">
                                      <.icon name="hero-check" class="w-4 h-4 text-success" />
                                    </button>
                                    <button
                                      type="button"
                                      phx-click="cancel_rename_folder"
                                      phx-target={@myself}
                                      class="btn btn-sm btn-ghost"
                                    >
                                      <.icon name="hero-x-mark" class="w-4 h-4" />
                                    </button>
                                  </form>
                                </td>
                                <td></td>
                              </tr>
                            <% else %>
                              <tr
                                phx-click={
                                  if @select_mode,
                                    do: "toggle_select_folder",
                                    else: "navigate_folder"
                                }
                                phx-target={@myself}
                                phx-value-folder-uuid={folder.uuid}
                                data-drop-folder={folder.uuid}
                                data-draggable-folder={folder.uuid}
                                data-selected={
                                  if @select_mode &&
                                       MapSet.member?(@selected_folders, folder.uuid),
                                     do: "true"
                                }
                                class={[
                                  "hover cursor-pointer",
                                  @select_mode && MapSet.member?(@selected_folders, folder.uuid) &&
                                    "bg-primary/10"
                                ]}
                                style={folder_bg_style(folder.color)}
                              >
                                <%= if @select_mode do %>
                                  <td>
                                    <input
                                      type="checkbox"
                                      class="checkbox checkbox-primary checkbox-xs"
                                      checked={MapSet.member?(@selected_folders, folder.uuid)}
                                      phx-click="toggle_select_folder"
                                      phx-target={@myself}
                                      phx-value-folder-uuid={folder.uuid}
                                    />
                                  </td>
                                <% end %>
                                <td>
                                  <div class="w-10 h-10 grid place-items-center">
                                    <span style={folder_icon_style(folder.color)}>
                                      <.icon name="hero-folder" class="w-10 h-10" />
                                    </span>
                                  </div>
                                </td>
                                <td>
                                  <span class={[
                                    "font-medium text-sm",
                                    @renaming_folder == folder.uuid &&
                                      @renaming_source != "content" &&
                                      "renaming-preview"
                                  ]}>
                                    <%= if @renaming_folder == folder.uuid && @renaming_text != "" do %>
                                      {@renaming_text}
                                    <% else %>
                                      {folder.name}
                                    <% end %>
                                  </span>
                                </td>
                                <td>
                                  <%= if folders_path do %>
                                    <span class="text-xs text-base-content/50">
                                      {folders_path}
                                    </span>
                                  <% else %>
                                    <span class="text-xs text-base-content/30">/</span>
                                  <% end %>
                                </td>
                                <td>
                                  <span class="badge badge-ghost badge-sm h-auto">
                                    {gettext("Folder")}
                                  </span>
                                </td>
                                <td></td>
                                <td class="text-sm text-base-content/70">
                                  {Calendar.strftime(folder.inserted_at, "%b %d, %Y")}
                                </td>
                                <td>
                                  <.table_row_menu id={"folder-kebab-list-#{folder.uuid}"}>
                                    <.table_row_menu_button
                                      phx-click="start_rename_folder"
                                      phx-target={@myself}
                                      phx-value-folder-uuid={folder.uuid}
                                      icon="hero-pencil"
                                      label={gettext("Rename")}
                                    />
                                    <li role="none">
                                      <div class="px-3 py-1.5">
                                        <span class="text-xs font-semibold text-base-content/50 mb-1 block">
                                          {gettext("Color")}
                                        </span>
                                        <div class="flex flex-wrap gap-1">
                                          <%= for color <- PhoenixKit.Modules.Storage.Folder.colors() do %>
                                            <button
                                              phx-click="change_folder_color"
                                              phx-target={@myself}
                                              phx-value-folder-uuid={folder.uuid}
                                              phx-value-color={color}
                                              class={[
                                                "w-4 h-4 rounded-full border-2 transition-transform hover:scale-125",
                                                if(
                                                  folder.color == color ||
                                                    (folder.color == nil && color == "default"),
                                                  do: "border-base-content scale-110",
                                                  else: "border-transparent"
                                                )
                                              ]}
                                              style={"background-color: #{folder_color_hex(color) || "oklch(var(--wa))"}"}
                                              title={color}
                                            >
                                            </button>
                                          <% end %>
                                        </div>
                                      </div>
                                    </li>
                                    <.table_row_menu_button
                                      phx-click="prepare_move_folder"
                                      phx-target={@myself}
                                      phx-value-folder-uuid={folder.uuid}
                                      icon="hero-folder-arrow-down"
                                      label={gettext("Move")}
                                    />
                                    <.table_row_menu_button
                                      phx-click="delete_folder"
                                      phx-target={@myself}
                                      phx-value-id={folder.uuid}
                                      data-confirm={
                                        gettext("Delete '%{name}'? Files move to parent.",
                                          name: folder.name
                                        )
                                      }
                                      icon="hero-trash"
                                      label={gettext("Delete")}
                                      variant="error"
                                    />
                                  </.table_row_menu>
                                </td>
                              </tr>
                            <% end %>
                          <% end %>
                          <%!-- Files --%>
                          <%= for file <- @uploaded_files do %>
                            <tr
                              data-draggable-file={file.file_uuid}
                              data-selected={
                                if @select_mode &&
                                     MapSet.member?(@selected_files, file.file_uuid),
                                   do: "true"
                              }
                              phx-click="click_file"
                              phx-target={@myself}
                              phx-value-file-uuid={file.file_uuid}
                              class={[
                                "hover cursor-pointer",
                                @select_mode &&
                                  MapSet.member?(@selected_files, file.file_uuid) &&
                                  "bg-primary/10"
                              ]}
                            >
                              <%= if @select_mode do %>
                                <td>
                                  <input
                                    type="checkbox"
                                    class="checkbox checkbox-primary checkbox-xs"
                                    checked={MapSet.member?(@selected_files, file.file_uuid)}
                                    phx-click="toggle_select"
                                    phx-target={@myself}
                                    phx-value-file-uuid={file.file_uuid}
                                  />
                                </td>
                              <% end %>
                              <td>
                                <div class="w-10 h-10 rounded overflow-hidden bg-base-300 shrink-0">
                                  <.thumbnail_url :let={url} file={file} size={:small}>
                                    <%= if url do %>
                                      <img
                                        src={url}
                                        class="w-full h-full object-cover"
                                        alt={file.filename}
                                      />
                                    <% else %>
                                      <div class="grid place-items-center w-full h-full text-base-content/40">
                                        <.icon name={file_icon(file.file_type)} class="w-5 h-5" />
                                      </div>
                                    <% end %>
                                  </.thumbnail_url>
                                </div>
                              </td>
                              <td>
                                <span class="font-medium text-sm">{file.filename}</span>
                              </td>
                              <td>
                                <%= if file.folder_path do %>
                                  <span class="text-xs text-base-content/50">
                                    {file.folder_path}
                                  </span>
                                <% else %>
                                  <span class="text-xs text-base-content/30">/</span>
                                <% end %>
                              </td>
                              <td>
                                <span class="badge badge-ghost badge-sm h-auto">
                                  {String.upcase(file.file_type)}
                                </span>
                              </td>
                              <td class="text-sm text-base-content/70">
                                {format_file_size(file.size)}
                              </td>
                              <td class="text-sm text-base-content/70">
                                {Calendar.strftime(file.inserted_at, "%b %d, %Y")}
                              </td>
                              <td>
                                <%!--
                                Per-file kebab. `phx-click="noop"` on the
                                wrapper intercepts the bubble so clicks
                                on the dropdown trigger don't also fire
                                the row's `click_file`. Same pattern the
                                folder list-view kebab uses above.
                              --%>
                                <%= unless @select_mode do %>
                                  <.table_row_menu id={"file-kebab-list-#{file.file_uuid}"}>
                                    <.table_row_menu_button
                                      :if={
                                        Map.get(file.urls || %{}, "original") ||
                                          Map.get(file.urls || %{}, :original)
                                      }
                                      phx-click="download_file"
                                      phx-target={@myself}
                                      phx-value-file-uuid={file.file_uuid}
                                      icon="hero-arrow-down-tray"
                                      label={gettext("Download")}
                                    />
                                    <.table_row_menu_button
                                      phx-click="prepare_move_file"
                                      phx-target={@myself}
                                      phx-value-file-uuid={file.file_uuid}
                                      icon="hero-folder-arrow-down"
                                      label={gettext("Move")}
                                    />
                                    <.table_row_menu_button
                                      phx-click="delete_file"
                                      phx-target={@myself}
                                      phx-value-file-uuid={file.file_uuid}
                                      data-confirm={
                                        if @filter_trash,
                                          do:
                                            gettext(
                                              "Permanently delete '%{name}'? This cannot be undone.",
                                              name: file.filename
                                            )
                                      }
                                      icon="hero-trash"
                                      label={
                                        if @filter_trash,
                                          do: gettext("Delete Permanently"),
                                          else: gettext("Move to Trash")
                                      }
                                      variant="error"
                                    />
                                  </.table_row_menu>
                                <% end %>
                              </td>
                            </tr>
                          <% end %>
                        </tbody>
                      </table>
                    </div>
                  <% end %>
                <% end %>
              </div>

              <%!-- Pagination (event-based; URL sync deferred to Task 3) --%>
              <%= if @total_count > @per_page do %>
                <div class="flex justify-center items-center gap-2 mt-4">
                  <%= if @current_page > 1 do %>
                    <button
                      phx-click="set_page"
                      phx-target={@myself}
                      phx-value-page={@current_page - 1}
                      class="btn btn-sm btn-ghost gap-1"
                    >
                      <.icon name="hero-chevron-left" class="w-4 h-4" /> {gettext("Prev")}
                    </button>
                  <% end %>
                  <span class="text-sm text-base-content/70">
                    {@current_page} / {@total_pages}
                  </span>
                  <%= if @current_page < @total_pages do %>
                    <button
                      phx-click="set_page"
                      phx-target={@myself}
                      phx-value-page={@current_page + 1}
                      class="btn btn-sm btn-ghost gap-1"
                    >
                      {gettext("Next")} <.icon name="hero-chevron-right" class="w-4 h-4" />
                    </button>
                  <% end %>
                </div>
              <% end %>
            </div>
          </div>
        </div>
      </div>
    </div>

    <%!-- Move to Folder Modal --%>
    <%= if @show_move_modal do %>
      <div class="modal modal-open">
        <div class="modal-box">
          <h3 class="font-bold text-lg mb-4">
            <%!--
              "item" covers both files and folders so the kebab single-item
              and bulk-mixed selections all read sensibly. Bulk-file-only
              flows used to say "file(s)" — generalising loses that nuance
              but gains correctness when folders are in the mix.
            --%>
            {ngettext(
              "Move %{count} item to folder",
              "Move %{count} items to folder",
              MapSet.size(@selected_files) + MapSet.size(@selected_folders)
            )}
          </h3>
          <ul class="menu bg-base-200 rounded-lg max-h-64 overflow-y-auto">
            <li>
              <button
                phx-click="move_selected_to_folder"
                phx-target={@myself}
                phx-value-folder_uuid=""
                class={if @current_folder == nil, do: "active", else: ""}
              >
                <.icon name="hero-home" class="w-4 h-4" /> {@scope_folder_name}
              </button>
            </li>
            <%= for node <- @folder_tree do %>
              <.move_folder_option node={node} depth={0} myself={@myself} />
            <% end %>
          </ul>
          <div class="modal-action">
            <button phx-click="close_move_modal" phx-target={@myself} class="btn btn-ghost">
              {gettext("Cancel")}
            </button>
          </div>
        </div>
        <div class="modal-backdrop" phx-click="close_move_modal" phx-target={@myself}></div>
      </div>
    <% end %>
  <% end %>

  <%!-- ── Read-only modal viewer ──────────────────────────────────────────── --%>
  <%!-- Default click target for non-admin, non-select_mode browsers — the    --%>
  <%!-- click_file handler stashes the clicked file in :viewer_file and this  --%>
  <%!-- block renders the preview + metadata + Download. Pickers reach        --%>
  <%!-- bulk-select via the toolbar's Select button (`select_mode` toggle).   --%>
  <%!-- Closes via X / Esc / backdrop click.                                  --%>
  <%= if assigns[:viewer_file] do %>
    <% f = @viewer_file %>
    <% viewer_idx = Enum.find_index(@uploaded_files, &(&1.file_uuid == f.file_uuid)) %>
    <% has_prev = is_integer(viewer_idx) and viewer_idx > 0 %>
    <% has_next = is_integer(viewer_idx) and viewer_idx < length(@uploaded_files) - 1 %>
    <div
      id={"#{@id}-viewer-modal"}
      class="modal modal-open"
      phx-hook="ViewerKeydown"
      phx-target={@myself}
    >
      <%!-- Mobile: pin the modal-box directly to the viewport via          --%>
      <%!--   position: fixed; inset: 0;                                    --%>
      <%!-- This bypasses daisyUI's grid layout AND iOS Safari's 100vh /   --%>
      <%!-- 100dvh quirks — the box just covers top:0 right:0 bottom:0     --%>
      <%!-- left:0 of whatever the visual viewport is, no math involved.   --%>
      <%!-- `w-auto h-auto` lets the inset declarations actually drive the --%>
      <%!-- size; otherwise an intrinsic width/height could win.           --%>
      <%!--                                                                 --%>
      <%!-- lg+: revert to a normal centred modal with 95vw × 90vh + soft  --%>
      <%!-- rounded corners.                                               --%>
      <%!--                                                                 --%>
      <%!-- The `!` (important) prefix is required because daisyUI v5's    --%>
      <%!-- .modal-box defaults (width: calc(11/12 * 100%), max-width:     --%>
      <%!-- 32rem, max-height: 100vh) win the cascade over plain Tailwind  --%>
      <%!-- utilities.                                                     --%>
      <div class="modal-box !fixed !inset-0 !w-auto !h-auto !min-w-0 !max-w-none !max-h-none !m-0 !rounded-none lg:!relative lg:!inset-auto lg:!w-[95vw] lg:!h-[90vh] lg:!rounded-2xl lg:!m-auto p-0 !overflow-hidden">
        <%!-- Close button — top-right of modal-box. Solid bg-base-100 + ring +  --%>
        <%!-- shadow-lg keeps it visible against any image content (the previous --%>
        <%!-- bg-base-100/80 blended into light photos and disappeared). z-30    --%>
        <%!-- sits above the chevron buttons (z-10) and the comments thread.    --%>
        <button
          type="button"
          phx-click="close_viewer"
          phx-target={@myself}
          class="btn btn-ghost btn-sm btn-circle absolute top-3 right-3 z-30 bg-base-100 hover:bg-base-200 shadow-lg ring-1 ring-base-300"
          title={gettext("Close")}
        >
          <.icon name="hero-x-mark" class="w-4 h-4" />
        </button>
        <div class="flex flex-col lg:flex-row h-full overflow-hidden">
          <%!-- Viewer (image / video / pdf / icon) --%>
          <div class="flex-[7] relative flex items-center justify-center bg-base-200 overflow-hidden p-0 lg:p-2 min-h-[40vh] lg:min-h-0">
            <%!-- Chevron positioning sits on a wrapper div, not the button.    --%>
            <%!-- daisyUI's active-state CSS replaces `transform` with          --%>
            <%!-- `scale(0.97)` on click, which would clobber a -translate-y-1/2 --%>
            <%!-- on the button itself and make it jump down 50% of its height. --%>
            <%= if has_prev do %>
              <div class="absolute left-2 top-1/2 -translate-y-1/2 z-10">
                <button
                  type="button"
                  phx-click="step_viewer"
                  phx-value-dir="prev"
                  phx-target={@myself}
                  class="btn btn-circle btn-ghost bg-base-100/80 hover:bg-base-100 shadow-md"
                  title={gettext("Previous (←)")}
                >
                  <.icon name="hero-chevron-left" class="w-5 h-5" />
                </button>
              </div>
            <% end %>
            <%= if has_next do %>
              <div class="absolute right-2 top-1/2 -translate-y-1/2 z-10">
                <button
                  type="button"
                  phx-click="step_viewer"
                  phx-value-dir="next"
                  phx-target={@myself}
                  class="btn btn-circle btn-ghost bg-base-100/80 hover:bg-base-100 shadow-md"
                  title={gettext("Next (→)")}
                >
                  <.icon name="hero-chevron-right" class="w-5 h-5" />
                </button>
              </div>
            <% end %>
            <%= cond do %>
              <% is_binary(f.mime_type) and String.starts_with?(f.mime_type, "image/") -> %>
                <%!-- Fresco hosts the viewer (pan + zoom + nav + viewport       --%>
                <%!-- clamping + smooth animations). Tessera attaches as a layer --%>
                <%!-- that adds a DZI source provider + multi-layer progressive  --%>
                <%!-- zoom — starts on `medium` and swaps up as the user zooms:  --%>
                <%!--                                                            --%>
                <%!--   small image  → [medium, dzi]                             --%>
                <%!--   4K+ image    → [medium, large, dzi]                      --%>
                <%!--                                                            --%>
                <%!-- Tessera 0.2 split the viewer into a Fresco OpenSeadragon   --%>
                <%!-- viewer + a Tessera layer that swaps between source         --%>
                <%!-- qualities. Fresco renders the initial cheap source; the    --%>
                <%!-- Tessera layer attaches via fresco_id and takes over the    --%>
                <%!-- per-zoom layer-swap logic, preserving viewport bounds.     --%>
                <%!-- Etcher's annotation overlay attaches to the same Fresco    --%>
                <%!-- viewer and adds the pencil button to its nav column.       --%>
                <%= with sources <- tessera_sources(f),
                       fresco_src <-
                         (case sources do
                            [first | _] -> first.url
                            [] -> f.urls["original"] || f.urls["medium"]
                          end) do %>
                  <Fresco.viewer
                    id={"media-zoom-" <> f.file_uuid}
                    src={fresco_src}
                    class="w-full h-full lg:rounded"
                    rotate
                    theme={:inherit}
                  />
                  <%!-- Tessera only attaches when there's something to    --%>
                  <%!-- swap between — files without medium/large/dzi      --%>
                  <%!-- variants (variant generator hasn't run yet, etc.) --%>
                  <%!-- get plain Fresco without progressive zoom.         --%>
                  <%= if sources != [] do %>
                    <Tessera.layer
                      fresco_id={"media-zoom-" <> f.file_uuid}
                      sources={sources}
                    />
                  <% end %>
                  <%!-- Etcher attaches to any Fresco viewer regardless    --%>
                  <%!-- of Tessera; annotations work even on files that   --%>
                  <%!-- skip the progressive-zoom layer.                  --%>
                  <Etcher.layer
                    fresco_id={"media-zoom-" <> f.file_uuid}
                    target_type="file"
                    target_uuid={f.file_uuid}
                    initial_annotations={@viewer_annotations}
                    tools={[
                      :rectangle,
                      :circle,
                      :polygon,
                      :freehand,
                      :callout,
                      :text,
                      :dimension,
                      :eraser
                    ]}
                  />
                <% end %>
              <% is_binary(f.mime_type) and String.starts_with?(f.mime_type, "video/") -> %>
                <video
                  src={f.urls["original"]}
                  controls
                  class="max-w-full max-h-full rounded"
                  preload="metadata"
                >
                  {gettext("Your browser does not support the video tag.")}
                </video>
              <% f.mime_type == "application/pdf" -> %>
                <iframe
                  src={f.urls["original"]}
                  sandbox="allow-same-origin"
                  class="w-full h-full rounded border-0"
                  title={f.filename}
                >
                </iframe>
              <% true -> %>
                <div class="flex flex-col items-center justify-center text-base-content/50 py-12">
                  <.icon name={file_icon(f.file_type)} class="w-32 h-32 mb-4" />
                  <p class="text-2xl font-semibold">
                    {String.upcase(f.file_type || gettext("FILE"))}
                  </p>
                  <p class="text-sm text-base-content/70 mt-2">{f.mime_type}</p>
                </div>
            <% end %>

            <%!-- Floating annotation composer — anchored to the shape's    --%>
            <%!-- bottom-left in container px (supplied by etcher.js in    --%>
            <%!-- the etcher:created event). Sidebar comments stay visible --%>
            <%!-- alongside; this popover is for the new shape only.       --%>
            <%= if @composing_annotation_uuid && assigns[:phoenix_kit_current_user] do %>
              <%!-- The AnnotationComposerPosition hook clamps left/top      --%>
              <%!-- after mount + updates + window resize so the popover     --%>
              <%!-- never extends past the viewer's right edge or bottom     --%>
              <%!-- (the server-set anchor is the shape's bottom-left, so a  --%>
              <%!-- shape drawn near a boundary would otherwise place the    --%>
              <%!-- popover off-screen).                                     --%>
              <div
                id={"annotation-composer-popover-" <> @composing_annotation_uuid}
                phx-hook="AnnotationComposerPosition"
                class="absolute z-30 w-80 max-w-[calc(100%-1rem)] bg-base-100 rounded-lg shadow-xl border border-base-300 p-3"
                style={"left: #{(@composer_anchor && @composer_anchor.x) || 16}px; top: #{(@composer_anchor && @composer_anchor.y) || 16}px;"}
              >
                <div class="flex items-center gap-2 text-sm font-medium mb-2">
                  <.icon name="hero-pencil-square" class="w-4 h-4 text-warning" />
                  <span>{gettext("Add a note to your annotation")}</span>
                </div>
                <p class="text-xs text-base-content/60 mb-3">
                  {gettext("Post to keep it. Cancel to discard the shape.")}
                </p>
                <.live_component
                  module={PhoenixKitWeb.Components.AnnotationComposer}
                  id={"annotation-composer-" <> @composing_annotation_uuid}
                  annotation_uuid={@composing_annotation_uuid}
                  file_uuid={f.file_uuid}
                  current_user={@phoenix_kit_current_user}
                  parent_id={@id}
                />
              </div>
            <% end %>
          </div>

          <%!-- Sidebar --%>
          <div class="flex-[3] flex flex-col gap-3 p-4 overflow-y-auto lg:min-w-[280px] bg-base-100">
            <h2 class="text-base font-bold break-all leading-tight pr-10">
              {f.filename}
            </h2>

            <%= if f.urls["original"] do %>
              <a
                href={f.urls["original"]}
                download={f.filename}
                target="_blank"
                rel="noopener"
                class="btn btn-primary btn-sm gap-2 self-start"
              >
                <.icon name="hero-arrow-down-tray" class="w-4 h-4" /> {gettext("Download")}
              </a>
            <% end %>

            <div class="text-sm space-y-2 mt-1">
              <div>
                <span class="text-base-content/60">{gettext("Type:")}</span>
                <span class="ml-1 badge badge-ghost">
                  {String.upcase(f.file_type || gettext("FILE"))}
                </span>
              </div>
              <div class="break-all">
                <span class="text-base-content/60">{gettext("MIME:")}</span>
                <span class="ml-1 font-mono text-xs">{f.mime_type}</span>
              </div>
              <div>
                <span class="text-base-content/60">{gettext("Size:")}</span>
                <span class="ml-1">{format_file_size(f.size)}</span>
              </div>
              <div>
                <span class="text-base-content/60">{gettext("Uploaded:")}</span>
                <span class="ml-1">
                  {Calendar.strftime(f.inserted_at, "%b %d, %Y at %H:%M")}
                </span>
              </div>
            </div>

            <%!-- Comments section — gated on the Comments module being     --%>
            <%!-- installed AND enabled, plus a logged-in user. Keyed by    --%>
            <%!-- file_uuid so prev/next remounts the component cleanly.    --%>
            <%!--                                                           --%>
            <%!-- The wrapper applies a compact-mode override: shrinks the  --%>
            <%!-- comments component's typography, paddings, and avatars    --%>
            <%!-- via descendant selectors so it fits inside the sidebar    --%>
            <%!-- without truncation. The component itself isn't modified.  --%>
            <%= if comments_enabled?() and assigns[:phoenix_kit_current_user] do %>
              <div class="border-t border-base-300 pt-3 mt-3 leaf-comments-compact">
                <.live_component
                  module={PhoenixKitComments.Web.CommentsComponent}
                  id={"media-comments-" <> f.file_uuid}
                  resource_type="file"
                  resource_uuid={f.file_uuid}
                  current_user={@phoenix_kit_current_user}
                  show_likes={true}
                  title={gettext("Comments")}
                />
              </div>
            <% end %>
          </div>
        </div>
      </div>
      <div class="modal-backdrop" phx-click="close_viewer" phx-target={@myself}></div>
    </div>
  <% end %>
</div>
