<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Ewing Family Association — Membership Form (Replica)</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style>
:root{
--bg:#f7f7f9; --card:#ffffff; --ink:#1d2433; --muted:#6b7280; --accent:#234d8e;
--accent-2:#0f7ae5; --border:#e5e7eb; --error:#c1121f; --ok:#107e39;
}
*{box-sizing:border-box}
body{margin:0; font-family:system-ui,-apple-system,Segoe UI,Roboto,Inter,Helvetica,Arial,sans-serif; color:var(--ink); background:var(--bg); line-height:1.45}
header{background:#0b1b33; color:#fff; padding:24px}
header .brand{display:flex; align-items:baseline; gap:10px; flex-wrap:wrap}
header h1{margin:0; font-size:22px; letter-spacing:.2px}
header .motto{font-style:italic; opacity:.9}
main{max-width:900px; margin:32px auto; padding:0 16px}
.card{background:var(--card); border:1px solid var(--border); border-radius:14px; box-shadow:0 2px 12px rgba(0,0,0,.04)}
.card header{background:transparent; color:inherit; padding:20px; border-bottom:1px solid var(--border)}
.card .content{padding:20px}
h2{margin:0 0 6px 0; font-size:22px}
p.lead{margin:0; color:var(--muted)}
fieldset{border:none; margin:0; padding:0}
.grid{display:grid; gap:14px}
.cols-2{grid-template-columns:1fr 1fr}
.cols-3{grid-template-columns:repeat(3,1fr)}
.row{display:flex; align-items:center; gap:12px; flex-wrap:wrap}
label{font-size:14px; color:#111827}
.req::after{content:" *"; color:var(--error)}
input[type="text"], input[type="email"], input[type="tel"], textarea, select{
width:100%; padding:10px 12px; border:1px solid var(--border); border-radius:10px; font:inherit; background:#fff
}
textarea{min-height:120px; resize:vertical}
.hint{font-size:12px; color:var(--muted)}
.counter{font-size:12px; color:var(--muted); text-align:right}
.section-title{margin:24px 0 4px; font-weight:700; letter-spacing:.2px}
.btnbar{display:flex; gap:10px; justify-content:space-between; margin-top:18px}
.btn{appearance:none; border:1px solid var(--border); background:#fff; padding:10px 14px; border-radius:10px; cursor:pointer; font-weight:600}
.btn.primary{background:var(--accent); color:#fff; border-color:transparent}
.btn.ghost{background:#fff}
.btn.warn{border-color:#d1d5db}
.btn:disabled{opacity:.6; cursor:not-allowed}
.error{color:#fff; background:var(--error); padding:10px 12px; border-radius:10px; display:none}
.ok{color:#fff; background:var(--ok); padding:10px 12px; border-radius:10px; display:none}
.invisible{display:none !important}
table.summary{width:100%; border-collapse:collapse; overflow:hidden; border-radius:10px; border:1px solid var(--border)}
table.summary th, table.summary td{padding:10px 12px; border-bottom:1px solid var(--border); text-align:left; vertical-align:top}
table.summary th{width:260px; background:#fbfbfc; font-weight:600}
.captcha{display:flex; align-items:center; gap:10px; padding:12px; border:1px dashed #cbd5e1; border-radius:10px; background:#f8fafc}
footer{margin:28px 0 60px; text-align:center; color:var(--muted); font-size:12px}
.nav{margin-top:8px; display:flex; gap:10px; flex-wrap:wrap; font-size:13px}
.nav a{color:#c8d6ff; text-decoration:none}
.nav a:hover{text-decoration:underline}
.badge{display:inline-block; font-size:12px; padding:2px 8px; border-radius:999px; background:#eef2ff; color:#3730a3; border:1px solid #e0e7ff}
</style>
</head>
<body>
<header>
<div class="brand">
<h1>Ewing Family Association</h1>
<span class="motto">Audaciter!</span>
</div>
<nav class="nav" aria-label="Main">
<span class="badge">New Form</span>
<a href="#">Home</a>
<a href="#">About Us</a>
<a href="#">Membership</a>
<a href="#">Join/Renew</a>
<a href="#">Resources</a>
</nav>
</header>
<main>
<div class="card" id="step1-card">
<header>
<h2>New or Renewal EFA Membership</h2>
<p class="lead">Please fill in your membership data below. Items marked with <span class="req"></span> are required.</p>
</header>
<div class="content">
<div class="error" id="err1" role="alert">Please correct the highlighted fields.</div>
<fieldset class="grid">
<div class="section-title">Action Requested</div>
<div class="row" role="group" aria-label="Action Requested">
<label><input type="radio" name="action" value="New Membership" required> New Membership</label>
<label><input type="radio" name="action" value="Renewal"> Renewal</label>
</div>
<div class="section-title">Journal Delivery</div>
<div class="row" role="group" aria-label="Send paper version">
<span>Send traditional paper version?</span>
<label><input type="radio" name="paper" value="Yes" required> Yes</label>
<label><input type="radio" name="paper" value="No"> No</label>
</div>
<div class="section-title">Member Information</div>
<div class="grid cols-2">
<div>
<label class="req" for="memberName">Member Name</label>
<input id="memberName" required autocomplete="name" />
</div>
<div>
<label for="institution">Institution Name</label>
<input id="institution" />
</div>
</div>
<div>
<label for="spouse">Spouse Name</label>
<input id="spouse" />
</div>
<div class="grid cols-2">
<div>
<label class="req" for="street">Street Address</label>
<input id="street" required autocomplete="address-line1" />
</div>
<div>
<label class="req" for="city">City</label>
<input id="city" required autocomplete="address-level2" />
</div>
</div>
<div class="grid cols-3">
<div>
<label class="req" for="state">State/Region</label>
<input id="state" required autocomplete="address-level1" />
</div>
<div>
<label for="country">Country</label>
<input id="country" autocomplete="country-name" />
</div>
<div>
<label class="req" for="zip">Zip/Postal Code</label>
<input id="zip" required autocomplete="postal-code" />
</div>
</div>
<div class="grid cols-2">
<div>
<label class="req" for="email">Email</label>
<input id="email" type="email" required autocomplete="email" />
</div>
<div>
<label for="phone">Phone</label>
<input id="phone" type="tel" autocomplete="tel" />
</div>
</div>
<div>
<label for="connection" class="req">Please briefly share your Ewing connection</label>
<textarea id="connection" maxlength="288" required placeholder="Names, locations, and vital dates help identify people."></textarea>
<div class="row" style="justify-content:space-between;">
<span class="hint">Max 288 characters</span>
<span class="counter" id="connCounter">288</span>
</div>
</div>
<div class="section-title">Library Memberships (optional)</div>
<p class="hint">You may sponsor up to four libraries (full address and contact info appreciated).</p>
<div class="grid cols-2">
<div>
<label for="lib1">Library 1</label>
<textarea id="lib1" placeholder="Name, address, contact, email, phone"></textarea>
</div>
<div>
<label for="lib2">Library 2</label>
<textarea id="lib2" placeholder="Name, address, contact, email, phone"></textarea>
</div>
</div>
<div class="grid cols-2">
<div>
<label for="lib3">Library 3</label>
<textarea id="lib3" placeholder="Name, address, contact, email, phone"></textarea>
</div>
<div>
<label for="lib4">Library 4</label>
<textarea id="lib4" placeholder="Name, address, contact, email, phone"></textarea>
</div>
</div>
<div class="btnbar">
<button class="btn warn" type="button" id="reset1">Reset</button>
<div>
<button class="btn primary" type="button" id="next1">Next</button>
</div>
</div>
</fieldset>
</div>m
</div>
<!-- Step 2: Summary + human check -->
<div class="card invisible" id="step2-card" aria-live="polite">
<header>
<h2>Information Summary</h2>
<p class="lead">Please check your details. Use “Back” to make changes.</p>
</header>
<div class="content">
<table class="summary" id="summaryTable" aria-describedby="sumDesc"></table>
<p id="sumDesc" class="hint">If everything looks correct, confirm you are human and submit.</p>
<div class="captcha" style="margin-top:14px;">
<input type="checkbox" id="human" />
<label for="human"><strong>Are you human?</strong> (check this box to proceed)</label>
</div>
<div class="error" id="err2" role="alert" style="margin-top:12px;">Please check the “Are you human?” box before submitting.</div>
<div class="btnbar">
<button class="btn" type="button" id="back2">Back</button>
<div>
<button class="btn primary" type="button" id="submit2">Submit and go to Payment</button>
</div>
</div>
</div>
</div>
<!-- Step 3: Thank you / payment directions -->
<div class="card invisible" id="step3-card">
<header>
<h2>Thank you!</h2>
<p class="lead">We’ve received your membership request.</p>
</header>
<div class="content">
<p>To finalize your membership or renewal, please arrange payment. You may pay electronically (e.g., via the Association’s payment page)
or by mailing a check or money order. Be sure to include your name, address, and email so your application is credited correctly.</p>
<div class="ok" style="display:block; margin-top:12px;" role="status">Submission recorded (demo).</div>
<div class="btnbar">
<button class="btn" type="button" id="startOver">Start Over</button>
</div>
</div>
</div>
<footer>
<div id="mod-custom75" class="mod-custom custom" style="box-sizing: border-box; position: relative; color: rgb(255, 255, 255); font-family: Roboto, sans-serif; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(145, 43, 59); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">
<p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 1rem;">
<span style="box-sizing: border-box; font-size: 10pt; color: rgb(204, 204, 204);">
Before 2008, the Ewing Family Association<br style="box-sizing: border-box;">
was known as Clan Ewing in America.</span></p>
</div>
<div id="mod-custom91" class="mod-custom custom" style="box-sizing: border-box; position: relative; color: rgb(255, 255, 255); font-family: Roboto, sans-serif; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(145, 43, 59); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">
<p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 1rem;">
Copyright © 2016 - 2025 Ewing Family Association</p>
</div>
</footer>
</main>
<script>
// Utilities
const q = sel => document.querySelector(sel);
const byId = id => document.getElementById(id);
const step1 = byId('step1-card'), step2 = byId('step2-card'), step3 = byId('step3-card');
const fields = {
action: () => (document.querySelector('input[name="action"]:checked')||{}).value || "",
paper: () => (document.querySelector('input[name="paper"]:checked')||{}).value || "",
memberName: () => byId('memberName').value.trim(),
institution: () => byId('institution').value.trim(),
spouse: () => byId('spouse').value.trim(),
street: () => byId('street').value.trim(),
city: () => byId('city').value.trim(),
state: () => byId('state').value.trim(),
country: () => byId('country').value.trim(),
zip: () => byId('zip').value.trim(),
email: () => byId('email').value.trim(),
phone: () => byId('phone').value.trim(),
connection: () => byId('connection').value.trim(),
lib1: () => byId('lib1').value.trim(),
lib2: () => byId('lib2').value.trim(),
lib3: () => byId('lib3').value.trim(),
lib4: () => byId('lib4').value.trim(),
};
// Character counter
const maxConn = 288;
const conn = byId('connection');
const counter = byId('connCounter');
const updateCounter = () => {
const left = Math.max(0, maxConn - conn.value.length);
counter.textContent = left;
};
conn.addEventListener('input', updateCounter);
updateCounter();
// Validation helper (adds red border to invalid fields)
function setInvalid(el, isInvalid){
if(!el) return;
el.style.borderColor = isInvalid ? "var(--error)" : "var(--border)";
el.style.outline = isInvalid ? "2px solid rgba(193,18,31,.15)" : "none";
}
function validateStep1(){
let ok = true;
// Required radios
const action = document.querySelector('input[name="action"]:checked');
const paper = document.querySelector('input[name="paper"]:checked');
if(!action){ ok = false; }
if(!paper){ ok = false; }
// Required inputs
const requiredIds = ['memberName','street','city','state','zip','email','connection'];
requiredIds.forEach(id=>{
const el = byId(id);
const empty = !el.value.trim();
setInvalid(el, empty);
if(empty) ok = false;
});
// Email quick check
const emailVal = byId('email').value.trim();
const emailBad = emailVal && !/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(emailVal);
setInvalid(byId('email'), emailBad || !emailVal);
if(emailBad) ok = false;
byId('err1').style.display = ok ? 'none' : 'block';
return ok;
}
function showStep(which){
step1.classList.add('invisible');
step2.classList.add('invisible');
step3.classList.add('invisible');
which.classList.remove('invisible');
window.scrollTo({top:0, behavior:'smooth'});
}
function buildSummary(){
const rows = [
['Action Requested', fields.action()],
['Send Paper Copy of Journal?', fields.paper()],
['Member Name', fields.memberName()],
['Institution Name', fields.institution()],
['Spouse Name', fields.spouse()],
['Street Address', fields.street()],
['City', fields.city()],
['State/Region', fields.state()],
['Country', fields.country()],
['Zip/Postal Code', fields.zip()],
['Email', fields.email()],
['Phone', fields.phone()],
['Conn. Info', fields.connection()],
['Library 1', fields.lib1()],
['Library 2', fields.lib2()],
['Library 3', fields.lib3()],
['Library 4', fields.lib4()],
];
const table = byId('summaryTable');
table.innerHTML = rows.map(([k,v]) => `
<tr>
<th scope="row">${k}</th>
<td>${(v||'').replace(/</g,'<').replace(/>/g,'>').replace(/\n/g,'<br>')}</td>
</tr>
`).join('');
}
// Buttons
byId('next1').addEventListener('click', ()=>{
if(!validateStep1()) return;
buildSummary();
showStep(step2);
});
byId('back2').addEventListener('click', ()=> showStep(step1));
byId('submit2').addEventListener('click', ()=>{
const human = byId('human').checked;
byId('err2').style.display = human ? 'none' : 'block';
if(!human) return;
// Demo “submit”: show thank-you step.
// To integrate with a backend, collect payload and POST it below.
// Example:
// const payload = Object.fromEntries(Object.keys(fields).map(k=>[k, fields[k]()]));
// fetch('/your-endpoint', { method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify(payload) });
showStep(step3);
});
byId('reset1').addEventListener('click', ()=>{
document.querySelectorAll('input[type="text"], input[type="email"], input[type="tel"], textarea').forEach(el=>{ el.value=''; setInvalid(el,false); });
document.querySelectorAll('input[type="radio"]').forEach(el=> el.checked=false);
byId('err1').style.display='none';
updateCounter();
});
byId('startOver').addEventListener('click', ()=>{
byId('reset1').click();
showStep(step1);
});
</script>
</body>
</html>