## 1. Quick start

Three steps and the site is live with a working order form.

1. Open `fillup.php` in a plain text editor. Notepad is fine, Word is not.
2. Find `$TO` at the top and put your own email address there.
3. 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.csv` appeared, 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

index.html the page itself
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 `width` and `height` on 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