Template 01:シンプル(画像添付あり)

<h1>お問い合わせ</h1>

<label>お名前<span style="color:red">*</span>
  <input type="text" name="name" required autocomplete="name">
</label>

<label>メールアドレス<span style="color:red">*</span>
  <input type="email" name="email" required autocomplete="email">
</label>

<label>件名
  <input type="text" name="subject">
</label>

<label>お問い合わせ内容<span style="color:red">*</span>
  <textarea name="message" rows="6" required></textarea>
</label>

<div class="drop-zone" tabindex="0">
  <input class="file-input" type="file" name="images[]" accept="image/*" multiple>
  <div>画像をドラッグ&ドロップ、またはクリックして選択(複数可・1ファイル最大50MB)</div>
</div>

<ul class="previews"></ul>

<div><button type="submit">送信</button></div>
body{font-family:sans-serif;line-height:1.5;padding:20px;}
form{max-width:600px;margin:auto;}
h1{font-size:1.3rem;margin:0 0 12px;}
label{display:block;margin:8px 0;}
input[type="text"],input[type="email"],textarea{width:100%;padding:8px;border:1px solid #ccc;border-radius:4px;}
textarea{resize:vertical;}
.drop-zone{position:relative;border:2px dashed #ccc;padding:16px;text-align:center;cursor:pointer;margin:10px 0;}
.drop-zone.is-dragover{border-color:#333;background:#fafafa;}
.file-input{position:absolute;inset:0;opacity:0;cursor:pointer;}
.previews{list-style:none;margin:10px 0 0;padding:0;}
.preview{font-size:.9rem;margin-bottom:6px;}
button[type="submit"]{padding:8px 16px;border:1px solid #ccc;border-radius:4px;background:#f2f2f2;cursor:pointer;}
button[type="submit"]:hover{background:#e6e6e6;}
const form        = document.querySelector("form");
const fileInput   = form.querySelector(".file-input");
const dropZone    = form.querySelector(".drop-zone");
const previewList = form.querySelector(".previews");

const MAX_FILE_SIZE = 50 * 1024 * 1024;
let selectedFiles = [];

function addFiles(list){
  for(const file of list){
    if(!file.type.startsWith("image/")) { console.warn("画像以外は不可:", file.name); continue; }
    if(file.size > MAX_FILE_SIZE)       { console.warn("50MB超過:", file.name); continue; }
    selectedFiles.push(file);
  }
  const dt = new DataTransfer();
  selectedFiles.forEach(f => dt.items.add(f));
  fileInput.files = dt.files;

  previewList.innerHTML = "";
  selectedFiles.forEach(f => {
    const li = document.createElement("li");
    li.className = "preview";
    li.textContent = `${f.name} (${(f.size/1024/1024).toFixed(1)} MB)`;
    previewList.appendChild(li);
  });
}

// 誤ドロップ遷移防止
addEventListener("dragover", e => e.preventDefault());
addEventListener("drop",     e => e.preventDefault());

// D&D
["dragenter","dragover"].forEach(ev => {
  dropZone.addEventListener(ev, e => { e.preventDefault(); dropZone.classList.add("is-dragover"); });
});
["dragleave","drop"].forEach(ev => {
  dropZone.addEventListener(ev, e => { e.preventDefault(); dropZone.classList.remove("is-dragover"); });
});
dropZone.addEventListener("drop",  e => addFiles(e.dataTransfer.files));
fileInput.addEventListener("change", e => addFiles(e.target.files));

// 実送信はアプリ側で行う想定(ここでは書かない)