A class reunion website classmates can open on a phone

Classmates live in different places and read different apps. One page with the date, venue, cost and a contact, behind one link, answers the same questions once.

A class reunion website can be one page. Put the date, the venue, the cost and a contact on it, and send classmates a single link. It opens in a browser on a phone or a computer, with nothing to install and no account.

If you have been asking which site lets you share the plan with a scattered group of friends, this is a lighter route. You describe the reunion in plain words, an AI writes the page, and you send the link.

Here is a page you can copy.

Live exampletry it here, then copy the code
Share it as a link
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Hillcrest High, Class of 2006 - 20-year reunion</title>
<style>
  * { box-sizing: border-box; }
  body { margin: 0; background: #e8ecf3; font-family: system-ui, -apple-system, "Segoe UI", sans-serif; color: #1f2937; line-height: 1.55; }
  .page { max-width: 560px; margin: 0 auto; background: #fff; min-height: 100vh; padding-bottom: 28px; }
  .hero { background: #1e3a5f; color: #fff; text-align: center; padding: 22px 20px 20px; }
  .hero svg { width: 120px; height: 70px; display: block; margin: 0 auto 6px; }
  .hero p { margin: 0; font-size: 14px; letter-spacing: .08em; text-transform: uppercase; color: #bcd0ea; }
  h1 { margin: 4px 0 0; font-size: 29px; line-height: 1.15; }
  .days { margin: 0; padding: 10px 20px; background: #f4c542; color: #3b2a00; text-align: center; font-weight: 700; font-size: 17px; }
  section { padding: 0 20px; }
  h2 { margin: 24px 0 8px; font-size: 13px; letter-spacing: .08em; text-transform: uppercase; color: #1e3a5f; }
  p { margin: 0 0 10px; font-size: 17px; }
  .when { border: 2px solid #1e3a5f; border-radius: 14px; padding: 12px 16px; background: #f5f8fc; }
  .when b { display: block; font-size: 22px; color: #1e3a5f; }
  .card { border: 1px solid #d5dbe6; border-radius: 12px; padding: 12px 14px; background: #fafbfd; }
  .card b { display: block; font-size: 18px; }
  .price { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
  .price strong { font-size: 34px; color: #1e3a5f; line-height: 1; }
  table { width: 100%; border-collapse: collapse; font-size: 16px; }
  td { padding: 8px 4px; border-bottom: 1px solid #e5e7eb; vertical-align: top; }
  td:first-child { width: 84px; font-weight: 700; color: #1e3a5f; white-space: nowrap; }
  .who { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; padding: 0; list-style: none; }
  .who li { background: #eef2f8; border-radius: 99px; padding: 5px 12px; font-size: 16px; }
  .small { font-size: 15px; color: #6b7280; }
  .contact { margin-top: 24px; border: 2px solid #1e3a5f; border-radius: 14px; padding: 14px 16px; background: #f5f8fc; }
  .contact b { display: block; font-size: 19px; margin-bottom: 4px; }
  .contact a { display: inline-block; margin: 4px 10px 0 0; padding: 10px 16px; border-radius: 10px; background: #1e3a5f; color: #fff; text-decoration: none; font-size: 17px; font-weight: 600; }
  .contact a.alt { background: #fff; color: #1e3a5f; border: 2px solid #1e3a5f; padding: 8px 14px; }
</style>
</head>
<body>
<div class="page">
  <div class="hero">
    <!-- school crest drawn in SVG, so no image file is needed -->
    <svg viewBox="0 0 120 70" role="img" aria-label="A school crest">
      <path d="M60 4 L92 14 V36 Q92 54 60 66 Q28 54 28 36 V14 Z" fill="#f4c542" stroke="#fff" stroke-width="3"/>
      <path d="M60 18 L66 32 H52 Z M48 38 H72 V44 H48 Z" fill="#1e3a5f"/>
    </svg>
    <p>Hillcrest High School</p>
    <h1>Class of 2006<br>20-year reunion</h1>
  </div>

  <p class="days" id="days">Saturday 14 November 2026</p>

  <section>
    <h2>When</h2>
    <div class="when">
      <b><time datetime="2026-11-14">Saturday 14 November 2026</time></b>
      Doors open 6:30pm, finish 11:00pm
    </div>

    <h2>Where</h2>
    <div class="card"><b>The Granary Room</b>8 Mill Street, above the bakery. Street parking after 6pm, and a car park behind the library.</div>

    <h2>Cost</h2>
    <div class="price"><strong>$45</strong><span>per person, buffet dinner and one drink included</span></div>
    <p class="small">Pay Dana by Saturday 31 October. Message her for how to pay. Partners are welcome at the same price.</p>

    <h2>The evening</h2>
    <table>
      <tr><td>6:30pm</td><td>Doors open, name badges</td></tr>
      <tr><td>7:30pm</td><td>Buffet dinner</td></tr>
      <tr><td>9:00pm</td><td>Slideshow of old photos</td></tr>
      <tr><td>11:00pm</td><td>Finish</td></tr>
    </table>

    <h2>Coming so far</h2>
    <ul class="who" id="who">
      <li>Maya R.</li><li>Tomas B.</li><li>Priya S.</li><li>Jonas K.</li><li>Lena H.</li><li>Omar D.</li>
    </ul>
    <p class="small" id="count"></p>
  </section>

  <section>
    <div class="contact">
      <b>Please reply by Saturday 24 October</b>
      <p style="margin:0">Tell Dana Ruiz you are coming, and how many.</p>
      <a href="tel:+15550142">Call 555 0142</a>
      <a class="alt" href="mailto:dana.reunion@example.com">Email Dana</a>
      <p class="small" style="margin-top:10px">Email: dana.reunion@example.com</p>
    </div>
  </section>
</div>

<script>
  // Days to go, counted from the browser's own date
  const days = document.getElementById('days');
  const party = new Date(2026, 10, 14);  // months start at 0, so 10 is November
  const today = new Date(); today.setHours(0, 0, 0, 0);
  const left = Math.round((party - today) / 86400000);
  if (left > 1) days.textContent = left + ' days to go';
  else if (left === 1) days.textContent = 'Tomorrow';
  else if (left === 0) days.textContent = 'Tonight';
  else days.textContent = 'This reunion has happened. Thank you all.';

  // Count the names in the list, so the number never disagrees with it
  const n = document.querySelectorAll('#who li').length;
  document.getElementById('count').textContent = n + ' classmates have replied. First names and an initial, shared with their OK.';
</script>
</body>
</html>
A one-page reunion site: date, venue, cost, schedule and a contact. Scroll it, tap Call and Email, and copy the code.

The school, names, prices and phone number are made up. Replace them with yours, or let an AI do it, as the next section shows.

What goes on the page

Classmates open a reunion page to answer four questions: when is it, where is it, what does it cost, and who do I tell. Put those first, in that order, in large type.

What a classmate sees on a phone, and the four answers the page gives.
What a classmate sees on a phone, and the four answers the page gives.
  • Date and time. Weekday, date, doors open and finish. A date typed without its weekday is where mistakes hide.
  • Venue. The name and the street address, plus one line on parking.
  • Cost. One price per person, what it covers, and the date to pay by.
  • Contact. One name, one phone number and one email.
  • Reply by. A date, so you can give the venue a head count.

MDN says the datetime attribute of the time element gives a date in machine-readable form, and that this can help a user agent offer to add an event to a calendar. Write the date in words as well.

For the contact, MDN describes the tel: and mailto: link types. A tel: link autodials on cellular devices, and other devices may do something else, such as save the number. Show the number as text too, and test both links from your share link.

Anyone who has the link can open the page, and NOS has no password option. Do not put other people's phone numbers or home addresses on it, and do not put bank details on it.

If you list who is coming, use a first name and an initial, and ask first. Longer advice on the facts an event page needs is in event link and event landing page.

Make it with AI

Paste this into ChatGPT, Claude or Gemini. Replace the brackets with your own facts first.

Write one self-contained HTML page for a high school class
reunion. Mobile first, single column, body text at least 17px,
no external images, fonts or scripts, no form.

Sections, in this order:
1. Header: [school], Class of [year], [number]-year reunion
2. When: [weekday, date], doors [time], finish [time]
3. Where: [venue name], [street address], [parking note]
4. Cost: [price] per person, [what it covers], pay by [date]
5. The evening: a short table of times and what happens
6. A box: "Please reply by [date]", [name], a button that
   calls [phone] using a tel: link, and a mailto: link to [email]

Use only the facts I gave. Do not invent times, prices or names.
Return only the HTML.

Then check the result against your own list. Read every date, time, address, price and phone number. AI tools fill gaps with plausible details, so look for anything you did not write.

Also check that the weekday matches the date on a calendar, that there is no form or Submit button, and that no picture comes from another website.

Open a NOS document and paste the HTML in. The page renders right there and its scripts run, so you can test it on your own screen. Then choose Create share link and copy the address. HTML to link walks through it.

Anyone with that address can open the page in a browser, a phone included, with no account. They can read it but not edit it. If you change the code later, the same link shows the new version.

From an AI chat to a link classmates can open: four steps.
From an AI chat to a link classmates can open: four steps.

Classmates reach you through different routes, so use more than one.

Way to send What a classmate gets If the venue changes
Flyer image or PDF in a chat A file to open and find again Send a new file. The old one stays in the chat
Details typed in a message Plain text Send another message
Link to a NOS page A page in the browser, no account Change the code. The same link shows the change
Email with the link The link in the message Same as the link
QR code on a printed card A camera scan that leads to the link Same as the link. The printed code does not change
Each change in a chat is another message to find. A link keeps one current page.
Each change in a chat is another message to find. A link keeps one current page.

For a QR code, Google's help says that in Chrome on a computer you open the page, choose the three dots, then Cast, save, and share, then Create QR code. You can download it (as of October 2026).

Scan the printout yourself before you hand out cards.

The page must exist before the code does. QR code link covers the printing side, and why links beat attachments covers the file side.

Work out the cost before you publish

The cost line is the one classmates remember, so set it once. Fixed costs, such as the venue, are shared by whoever comes. Fewer guests means a higher price each.

Live exampletry it here, then copy the code
Share it as a link
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Reunion ticket price</title>
<style>
  * { box-sizing: border-box; }
  body { margin: 0; padding: 16px; background: #f4f5f7; font-family: system-ui, -apple-system, "Segoe UI", sans-serif; color: #1f2937; line-height: 1.45; }
  .box { max-width: 520px; margin: 0 auto; background: #fff; border-radius: 14px; padding: 16px 18px 18px; box-shadow: 0 4px 16px rgba(0,0,0,.08); }
  h1 { margin: 0 0 4px; font-size: 20px; }
  .hint { margin: 0 0 12px; font-size: 14px; color: #6b7280; }
  label { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 7px 0; font-size: 16px; border-bottom: 1px solid #eef0f3; }
  label span:first-child { flex: 1; }
  input { width: 96px; padding: 8px 10px; font-size: 16px; border: 1px solid #c7ccd4; border-radius: 8px; text-align: right; }
  .out { margin-top: 14px; border-radius: 12px; background: #eaf1fb; padding: 12px 14px; }
  .out .big { font-size: 30px; font-weight: 800; color: #1e3a5f; line-height: 1.1; }
  .out p { margin: 4px 0 0; font-size: 15px; }
  table { width: 100%; border-collapse: collapse; margin-top: 12px; font-size: 15px; }
  th, td { padding: 6px 4px; text-align: right; border-bottom: 1px solid #e5e7eb; }
  th:first-child, td:first-child { text-align: left; }
  th { font-size: 13px; color: #6b7280; font-weight: 600; }
  .say { margin-top: 12px; font-size: 15px; background: #fffbe6; border: 1px solid #f1e3a0; border-radius: 10px; padding: 10px 12px; }
</style>
</head>
<body>
<div class="box">
  <h1>Ticket price for the reunion</h1>
  <p class="hint">Made-up numbers. Type your own quotes in.</p>

  <label><span>Venue hire (whole evening)</span><input id="venue" type="number" min="0" value="450"></label>
  <label><span>Music, decorations, badges</span><input id="extras" type="number" min="0" value="150"></label>
  <label><span>Food per person</span><input id="food" type="number" min="0" value="22"></label>
  <label><span>Drinks per person</span><input id="drink" type="number" min="0" value="8"></label>
  <label><span>Guests you expect</span><input id="guests" type="number" min="1" value="40"></label>

  <div class="out">
    <div class="big" id="price"></div>
    <p id="total"></p>
  </div>

  <table>
    <thead><tr><th>If this many come</th><th>Price each</th></tr></thead>
    <tbody id="rows"></tbody>
  </table>

  <p class="say" id="say"></p>
</div>

<script>
  const ids = ['venue', 'extras', 'food', 'drink', 'guests'];
  const v = (id) => Math.max(0, parseFloat(document.getElementById(id).value) || 0);

  // Fixed costs are shared by the guests; food and drink are paid per head
  function priceFor(count) {
    const fixed = v('venue') + v('extras');
    return Math.ceil((fixed + count * (v('food') + v('drink'))) / count);  // round up to a whole dollar
  }

  function update() {
    const g = Math.max(1, Math.round(v('guests')));
    const price = priceFor(g);
    document.getElementById('price').textContent = '$' + price + ' per person';
    document.getElementById('total').textContent = 'Total cost for ' + g + (g === 1 ? ' guest' : ' guests') + ': $' + (v('venue') + v('extras') + g * (v('food') + v('drink')));

    const rows = document.getElementById('rows');
    rows.innerHTML = '';
    [g - 10, g, g + 10].filter((c) => c >= 1).forEach((c) => {
      const tr = document.createElement('tr');
      tr.innerHTML = '<td>' + c + (c === 1 ? ' guest' : ' guests') + '</td><td>$' + priceFor(c) + '</td>';
      rows.appendChild(tr);
    });

    document.getElementById('say').textContent =
      'For the page: "$' + price + ' per person, buffet dinner and one drink included. Pay by [date]."';
  }

  ids.forEach((id) => document.getElementById(id).addEventListener('input', update));
  update();
</script>
</body>
</html>
Type your quotes and your expected head count. The table shows the price if ten fewer or ten more people come.

That is why the page asks for a reply by a set date. With a head count you can confirm the price with the venue, and then write it on the page.

Copy the sentence the calculator writes into your prompt. Use quotes you have actually received, not the made-up numbers here.

Replies come by message

There is no sign-up form on this page, and that is a choice. A NOS page can handle a form inside the page, but sending a form to a server is blocked, so nothing would reach you. A text or an email does.

Put your number and email on the page with the reply-by date, and say what to include: name, how many are coming, and any food needs. Keep the list yourself in a note or a spreadsheet.

You can also keep a coming-so-far list on the page. Open your own link in View mode and tick or add rows, and in NOS the owner's changes are saved. A visitor's changes are not saved.

Sending the link to a group chat? Sending an HTML file in WhatsApp explains why a link works better than an attached file. For the invite itself, see HTML for event invites.

When it does not work

Symptom Cause Fix
A classmate went to the old venue They read an old flyer or message, not the link Put "latest version at the link" on every message and printout
The Call button does nothing The device cannot make calls Show the number as plain text too
A sign-up form sends nothing Sending a form to a server is blocked Ask for a reply by text or email
A photo from another site is missing Outside images are blocked Use shapes drawn in the page, or leave pictures out
A classmate ticked a box and it vanished A visitor's changes are not saved Ask them to tell you, and tick it yourself
The weekday does not match the date They were written separately Check a calendar, fix the code, and message the change
The QR code does not scan Too small or blurry on paper Print it larger and scan the printout

Start small. Send the date and venue first, then add the cost and the evening as they get settled. Each edit keeps the same link.

Questions people ask

Do classmates need an account to open the page?

No. A NOS share link opens in a browser on a phone or a computer with no sign-in. They can read the page but they cannot edit it.

Can classmates sign up or pay on the page?

No. A NOS page cannot send a form to a server, so a sign-up form would send nothing. Put a phone number and an email on the page, and have people reply to you. Take payment outside the page and keep bank details off it.

What if the venue changes after I have sent the link?

Edit the code in your NOS document. Editing keeps the same link, so everyone who has it sees the new version the next time they open it. Add a dated line saying what changed, and send a short message so people look again.

Is the page private?

Anyone who has the link can open it, and NOS has no password option. A classmate can forward it to someone you have never met. Leave out phone numbers and home addresses of other people, and list names only with their OK.

Can I see who has opened the page?

No. A NOS page does not report who opened it. The way to know who is coming is a reply by message or email, which is why the page asks for one by a set date.

Keep reading