Feature Deep Dive

Contact Form System — Triple Fallback + Auto-Reply

The contact form never silently fails. It tries EmailJS first (sends to Gmail + auto-reply to sender), falls back to Web3Forms API, and if both fail — opens the user's native mail client via mailto: with the message pre-filled. On mobile, 4 quick-action tap cards give instant access to phone, email, WhatsApp, and Telegram.

Contact form কখনো silently fail করে না। EmailJS → Web3Forms → mailto — 3 স্তরে fallback আছে। Mobile-এ floating label input, 500-char counter, haptic submit feedback এবং 4টি quick-action card (tel/mailto/wa.me/t.me) আছে।

3-layer fallback Auto-reply to sender Mobile deep links
Submission Flow

Triple Fallback Chain

When a user hits Submit, the form tries each layer in sequence. The user only ever sees success or the final fallback link — never a dead end.

1
EmailJS Primary
Two sends happen on success:
① Main email to mdakhinoorislam.official.2005@gmail.com using template template_5lv0are
② Auto-reply email back to the sender's address using template template_ruuu6ra
Service ID: service_l3om32p (Gmail service)
Auto-reply failure is caught separately and silently ignored — the main send already succeeded.
2
Web3Forms API Fallback 1
If EmailJS throws any error → immediately tries Web3Forms.
fetch('https://api.web3forms.com/submit', { method:'POST', ... })
Sends same form data (name, email, subject, message) via JSON to Web3Forms endpoint. No account setup needed for basic delivery. If web3Response.ok → user sees success.
3
Native mailto: Final Fallback
If Web3Forms also fails → generates a mailto: link with subject and body pre-filled from the form data using encodeURIComponent().
Shows a warning message with a clickable link: "Click here to open your email client". Opens the user's native mail app with everything ready — they just hit Send.
Why 3 layers?

EmailJS has a monthly free-tier limit. Web3Forms also has limits. mailto: has no limits — it always works because it uses the device's own email app. The 3-layer system means the contact form works even if both API quotas are exhausted.

Form UI

Input Features

Floating Label Inputs
Labels start inside the input field (like placeholder text). On focus OR when the field has a value, the label smoothly floats up and shrinks. CSS selector: input[placeholder=" "] + label.floating-label. Works via the CSS :not(:placeholder-shown) trick — the placeholder=" " (single space) enables this without visible placeholder text.
500-Character Counter
The message textarea has maxlength="500". A live counter below shows [n]/500 — updates on every keypress. Stops input at 500. Applied on mobile only (desktop uses different styling but same JS logic).
3-State Submit Button
The submit button has 3 states: ① Default — "Send Message" with plane icon. ② Sending — spinner icon + "Sending..." text, button disabled. ③ Done — returns to default state (finally block). The .btn-text and .btn-spinner spans toggle display accordingly.
Success / Warning Status Bar
A #form-status div below the button shows the result. CSS classes: .success (green tint) and .warning (orange tint). On success, the form is also reset with form.reset().
Floating Label — How it looks
Empty (default)
Your Name
 
Focused / filled
Your Name
Akhinoor Islam
CSS trick
placeholder=" " (single space) makes label float using :not(:placeholder-shown) selector — no JS needed.
Mobile Only

Quick Actions + Deep Links

Mobile contact page has 4 one-tap action cards above the form — for direct communication without filling in a form.

📞
Phone
tel:
📧
Email
mailto:
💬
WhatsApp
wa.me
✈️
Telegram
t.me
tel: / mailto: / wa.me
Tapping any quick card opens the respective native app directly. tel: dials immediately on phone. wa.me/{number} opens WhatsApp chat. t.me/{username} opens Telegram. These are OS-level deep links — no app switching needed on mobile.
Haptic Submit Feedback
On form submit success, navigator.vibrate([100, 50, 100]) fires a double-buzz pattern. Confirms submission physically. Only fires on Android (iOS doesn't support navigator.vibrate). Checked with feature detection.
Platform Differences

Desktop vs Mobile

Desktop (Contact/contact.html)

  • Two-column layout: info panel left, form right
  • Pulsing green "Available" status dot (CSS keyframe statusPulse)
  • Direct: Email, WhatsApp, Location in left panel
  • Social grid: 5 icons with brand color hover
  • Same 3-layer EmailJS → Web3Forms → mailto fallback
  • particle background canvas + geometric shapes
  • No char counter on textarea (desktop)

Mobile (mobile/contact/contact.html)

  • Single column, vertical scroll
  • 4 quick-action tap cards at top (tel/mailto/wa.me/t.me)
  • Floating label inputs with .input-border animated underline
  • 500-char counter on textarea
  • Haptic vibrate on submit success
  • 16px input font-size (prevents iOS auto-zoom)
  • Same 3-layer fallback system
Technical Reference

Code Details

EmailJS Config
SDK
@emailjs/browser@4 (CDN)
Public Key
Yj4RUOwG4oxZyKFoh
Service ID
service_l3om32p (Gmail)
Main template
template_5lv0are (Portfolio Contact Form)
Auto-reply template
template_ruuu6ra (Portfolio Auto Reply)
Web3Forms endpoint
https://api.web3forms.com/submit
Final fallback
mailto: with encodeURIComponent() subject+body
Form reset
form.reset() called on EmailJS or Web3Forms success
Auto-reply failure
caught + console.warn only — not shown to user
Desktop file
Contact/contact.html
Mobile file
mobile/contact/contact.html
Explore More

Other Feature Guides

More deep-dives into A3KM Studio features — shortcuts, hidden tricks, mobile vs desktop comparisons and code references.