1. Quick start
Three steps and the site is live with a working order form.
- Open
fillup.phpin a plain text editor. Notepad is fine, Word is not. - Find
$TOat the top and put your own email address there. - Upload the whole folder to your web host, keeping the structure exactly as it is.
Then send yourself one test order and check three things:
- the email arrives, and is not in your spam folder
storage/orders-2026-01.csvappeared, with your test order in it- typing that CSV address into a browser gives 403 or 404, never a download
What you need: a host that runs PHP 7.4 or newer, which is nearly all of them. Nothing to install, no Composer, no libraries, no account anywhere. The page itself is plain HTML and CSS and works on any host; only the order form needs PHP.
2. What is in the folder
fillup.php your settings and wording. The file to edit.
send.php receives the form, checks it, saves it, emails it
css/style.css all styling, colours set at the top
js/main.js one file, no libraries
images/ every picture on the page
storage/ where orders are written. Read the note inside.
docs/ this documentation
README.txt the short version of this page
You will normally only ever open two of them: index.html for the words on the page, and fillup.php for your email settings.
3. The sections
The page is twelve blocks in one column. Every one is marked with a comment in index.html like <!-- ===== 4. Why us ===== --> so you can find it quickly.
| # | Section | What it holds |
|---|---|---|
| 1 | Header | Logo, four nav links, one button. Sticky, and gains a shadow once you scroll. |
| 2 | Hero | Eyebrow, headline, two sentences, two buttons, three ticks, one photograph. |
| 3 | Selection | Three product cards with prices. The middle one carries the "Most ordered" flag. |
| 4 | Why us | Four cards with icons and large outlined numerals. |
| 5 | Parallax band | A statement over a photograph that drifts as you scroll. |
| 6 | How ordering works | Three numbered steps beside a photograph. |
| 7 | Testimonial | One quote over a full width photograph. |
| 8 | Gallery | Eight photographs, two rows of four. Any one opens in a popup. |
| 9 | Order form | The only form on the page. Every button on the page scrolls here. |
| 10 | Questions | Four questions that open and close. |
| 11 | Closing call to action | A second parallax band with one button. |
| 12 | Footer | One line: copyright and credit. |
To remove a section, delete the whole <section>...</section> block including its comment. Nothing else depends on it, with one exception: if you delete the order form, the buttons that point at #order will have nowhere to go.
To reorder sections, cut and paste whole blocks. They do not depend on the order they appear in.
4. Colours and fonts
Every colour is set once, in the first block of css/style.css. Nothing further down hard codes a colour, so changing these changes the whole page.
:root {
--brand: #f97316; /* buttons, prices, accents */
--brand-dark: #ea580c; /* hover states */
--deep: #1e1b4b; /* the dark form band */
--ink: #1b1730; /* headings */
--body: #4b4763; /* body text */
--muted: #77738f; /* quieter text */
--line: #eae6f2; /* borders */
--bg: #ffffff;
--bg-alt: #fdf7f1; /* the warm section background */
--grad: linear-gradient(140deg, #fbbf24, #f97316 55%, #ea580c);
}
Changing --brand and --brand-dark does most of the work. --grad is used by the icon chips and the round buttons; set it to a matching pair of your own colours.
The font is the system font stack, set in --font. It uses whatever the visitor's device already has, so nothing is downloaded and the page draws instantly. To use a web font, add its stylesheet link in the <head> of index.html and put its name first in --font.
5. The product cards
Each card is one <article class="box"> block in section 3. Copy a whole block to add a fourth product, delete one to have two. The grid rearranges itself.
To move the flag, take class="is-popular" and the <p class="flag"> line off one card and put them on another.
The one thing that breaks quietly. The button inside each card carries data-box="Option 1". That text has to match the start of one of the entries in the form's "Which box" list. Change them together, or clicking a card will stop preselecting the right option, with no error to tell you.
A rename touches four places per card: the <h3>, the button text, the button's data-box, and the matching <option> in the form.
6. Images
Everything lives in images/. Each picture is a .jpg with a matching .webp beside it; the browser takes the WebP if it can and the JPEG if it cannot.
| File | Size | Where it appears |
|---|---|---|
logo.png | 96 × 96 | Header mark. Transparent. |
hero-box.jpg | 1200 × 900 | Hero |
box-1/2/3.jpg | 800 × 450 | The three product cards |
field-close.jpg | 1800 × 1013 | Parallax band, section 5 |
steps-packing.jpg | 900 × 675 | How ordering works |
quote-family.jpg | 1600 × 900 | Testimonial background |
pick-*.jpg | 1000 × 750 | The eight gallery photographs |
field-wide.jpg | 1800 × 1013 | Closing band, section 11 |
top.jpg | 144 × 144 | Back to top button |
Replacing them
- Keep the same filename and the same shape, and nothing else needs changing.
- If your new picture is a different shape, update the
widthandheighton its<img>tag to the real numbers. Those attributes reserve space while the page loads; wrong numbers make the page jump about. - If you only have a JPEG and no WebP, delete the
<source>line above that image, or the browser will look for a file that is not there. - The gallery uses one file per photograph for both the small tile and the popup, so there is only one image to replace per slot.
The pictures that come with the template are examples. Replace them with your own before you publish. They are not covered by the licence.
7. The order form
The form works as delivered. Put your address in fillup.php and upload.
What it already does
- checks every field and tells the visitor exactly what is wrong
- stops the three commonest kinds of form spam: a hidden honeypot field, a check that the form was not filled in impossibly fast, and a limit of five orders an hour from one visitor
- removes line breaks from every field before they can reach an email header, which is what stops a contact form being turned into a spam relay
- saves the order to
storage/before trying to email, so an email problem can never lose you an order - emails you, with reply-to set to the customer, so hitting reply writes to them
- emails the customer a short confirmation
- sends without reloading the page when JavaScript is on, and shows a normal thank-you page when it is off
Everything you can change, all in fillup.php
| Setting | What it does |
|---|---|
$TO | Where orders are emailed. The one you must change. |
$TO_NAME | Your business name, shown as the sender. |
$FROM | The address mail is sent from. Empty builds noreply@yourdomain. |
$SUBJECT_TO_YOU | Subject of the email you receive. |
$INTRO_TO_YOU | First line, above the order details. |
$FOOT_TO_YOU | Last line, below the order details. |
$SEND_COPY | false stops the customer's confirmation. |
$SUBJECT_TO_CUSTOMER | Subject of their copy. |
$MESSAGE_TO_CUSTOMER | Their whole message, written as ordinary text. |
$MSG_THANKS | Shown on the page after sending. |
$MSG_FAILED | Shown if the order could not be saved or emailed. |
$MSG_TOO_MANY | Shown if somebody sends a lot very quickly. |
$MAX_PER_HOUR | Orders allowed per visitor per hour. 0 for no limit. |
$REDIRECT_AFTER | Your own thank-you page, for example 'thank-you.html'. |
$LOG_DIR | Where orders are written. Change only if your host asks. |
$SMTP | See section 9. |
Words in curly brackets
In any of the wording settings you can use these, and they are swapped for the real order details when the email goes out:
{name} {email} {phone} {box} {address} {message} {site} {date}
Spell them exactly, in lower case, or they print as written. So:
$SUBJECT_TO_YOU = 'New box order: {box} for {name}';
arrives as New box order: Option 2, $39 for Ann Lee.
Adding or removing a field
Each field in index.html is one <div class="field"> block. Copy one, give it a new id and name, then add that name to the $in list near the top of the reading section in send.php and to the $lines list further down, or it will be ignored.
Do not delete these two. The hidden field named website is the honeypot, and the hidden ts field is the timing check. People never see either. Remove them and your spam goes up sharply.
8. Where orders are saved
Every order is written to storage/orders-YYYY-MM.csv, one file per month, before any email is attempted. Open it in Excel or Google Sheets.
| File | What it holds |
|---|---|
orders-YYYY-MM.csv | Every order that passed the checks. |
trapped-YYYY-MM.csv | Submissions the spam traps stopped. Check occasionally in case a real person was caught. |
mail-failures.log | Written only when an order saved but the email did not go out. Missing or empty is good news. |
rate.json | Counts recent submissions. Addresses are stored hashed, not in full. |
Check this once, before you take real orders. That folder holds your customers' names, phone numbers and addresses. The .htaccess inside it blocks web access on Apache, which is what most shared hosting runs.
After your site is live, type the address of one of the CSV files into a browser. You want 403 Forbidden or 404 Not Found. If the file downloads, your customer list is public. If your host uses nginx, .htaccess is ignored: move the folder above your web root and point $LOG_DIR at the new place, or add a deny rule to your nginx config.
If nothing appears after a test order, PHP cannot write there. Set the folder to 755, or 775 if your host needs it.
9. If email does not arrive
PHP's built in mail function is not reliable on every host, and mail sent that way sometimes lands in spam. The fix is to send through a real mailbox instead. Fill in the $SMTP block at the bottom of fillup.php and change 'enabled' to true.
| Line | What to put |
|---|---|
host | Your outgoing mail server, from your email provider. Usually like smtp.yourdomain.com. |
port | 587 in most cases. 465 only if your provider says so. |
secure | 'tls' goes with 587, 'ssl' goes with 465. They come as a pair. |
user | Your full email address, including the @ and everything after it. |
pass | That mailbox's password. |
Gmail, Outlook and Yahoo will not accept your normal password here. They make you create a separate "app password" in your account security settings, and you paste that instead. If signing in keeps failing, that is almost always why.
Also set $FROM to the same address as user. Many providers refuse to send a message that claims to come from a different address than the one signing in.
The password sits in fillup.php as ordinary text. Use a mailbox made for the website rather than your personal one.
Whatever happens to the email, the order is already saved in storage/.
10. Gallery and popup
Section 8 is eight photographs in two rows. Clicking any one opens it larger.
- arrows on screen, and the left and right arrow keys
- Escape closes it, as does clicking the dark area
- swipe left and right on a phone
- the page behind cannot scroll while it is open, and focus returns to the photograph you clicked
Each tile is a real button, so it works from the keyboard and screen readers announce it properly. To change a caption, edit both the data-caption on the button and the <figcaption> under it. To add or remove a photograph, copy or delete a whole <figure class="shot"> block.
11. Parallax and motion
Sections 5 and 11 have a photograph that drifts slower than the page. It is done with a real <img> moved by script, not a CSS background, because the CSS approach does nothing at all on iPhones.
One line near the top of that block in js/main.js controls how much it moves:
var DRIFT = 0.16; // 0 is still, 0.3 is a lot
Everything that moves is switched off completely for anyone whose device is set to reduce motion. That is a real accessibility setting people use, and the page is designed to look finished without any of it.
12. Without JavaScript
Nothing on this page needs JavaScript to work. With scripting off:
- the whole page renders finished, with nothing hidden
- the form submits normally and shows a proper thank-you page
- the questions still open and close, because they use the browser's own element for it
- the back to top button still works, because it is a plain link
- the parallax stops moving and the gallery popup does not open. Both are decoration.
This matters more than it sounds: a script that fails to load, a slow connection or a corporate proxy can all leave a visitor without JavaScript, and a page that hides its content until a script runs shows them nothing.
13. Browsers
Tested in current Chrome, Firefox, Safari and Edge, on desktop and phone. It uses aspect-ratio, CSS custom properties, object-fit and IntersectionObserver, all supported everywhere since 2021. Older browsers see a slightly plainer page that still reads and still works.
14. Troubleshooting
| What you see | What it usually is |
|---|---|
Blank white page after editing fillup.php | A missing quote mark or semicolon. Undo your last change. Also check you used straight quotes, not curly ones from Word. |
| Form says it sent, no email | Look in storage/mail-failures.log. The order is saved either way. Usually the host blocks mail(): set up SMTP, section 9. |
| Email goes to spam | Set $FROM to an address on your own domain, then use SMTP. |
Nothing in storage/ | PHP cannot write to the folder. Set it to 755 or 775. |
| The CSV downloads in a browser | Your host is ignoring .htaccess. Read the warning in section 8 and fix it before taking real orders. |
| Clicking a product card does not pick that option | data-box no longer matches the <option> text. Section 5. |
| A picture is missing | A .webp was deleted but its <source> line is still there, or the filename changed. Section 6. |
| Page jumps about while loading | An image's real size does not match its width and height. Section 6. |
| Form rejects a real customer | They filled it in under two and a half seconds, or sent six in an hour. Their details are in trapped-*.csv. |
15. Licence
Use it for personal, commercial or client work, on as many sites as you like. Do not resell or redistribute the template files themselves.
The photographs and drawings supplied with the template are placeholders and are not covered by the licence. Replace them with your own before you publish.
Full terms: 7uptheme.com/license