- Move hand-authored CSS into src/scss/styles.scss, compiled to the
tracked styles.css via `npm run build` (sass, no source maps).
- Add package.json/package-lock.json with dev tooling: sass, and a
`dev` script running php + sass --watch + browser-sync together.
- Add scripts/build-dist.js (npm run dist): assembles an allowlisted,
production-only copy of the site into dist/ (gitignored) for pushing
to hosting — excludes node_modules, src/, package files, and the
live db/fitz.sqlite while including config.php.
- .gitignore: ignore node_modules/, styles.css.map, and dist/.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Admin menu page: mobile item cards now put Actions in the top-right
corner next to Status, matching the desktop row layout instead of
stacking at the bottom; same treatment applied to announcements and
users for consistency across all three admin lists
- Center button label text everywhere via .btn { justify-content: center }
instead of one-off overrides
- Add a Disable/Enable Menu toggle to the admin menu toolbar; the public
menu page shows its existing "menu being updated" message while disabled
- Add an Enabled/Disabled status to user accounts, with its own toggle
badge, guardrails against disabling your own account or the last
enabled account, and an immediate session kick for anyone disabled
mid-session
- Fix the announcement banner / hero tagline "·" separators to hide only
when their neighboring text actually wraps onto a different line,
instead of a fixed breakpoint or always-on dot
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Add a Hours admin panel (admin/hours.php, admin/hours.js) for editing
the weekly open/close schedule and an optional per-day kitchen closing
time, with a live preview of how it'll read on the public site
- Store hours in a new pub_hours table (inc/db.php), seeded with the
site's existing Thu-Sat/9pm-kitchen schedule; inc/hours.php formats
and groups it for display (day ranges, kitchen-close note, footer
summary)
- Wire the public Visit card and both site footers (index.php, menu.php)
to read hours from that data instead of hardcoded copy
- Rebuild the Announcements and Users admin tables onto the same CSS
Grid list pattern already used for the Menu (admin-table-actions ->
row-actions), and make the Announcements status toggle an in-place
AJAX action like the menu item's (admin/index.js)
- Add the Hours tab to admin nav across all four admin pages
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Replace the <table>-based item and category-header rows with CSS Grid
containers using named grid-template-areas, so desktop and mobile each
get their own independent arrangement of the same fields instead of
mobile being a display:block hack forced onto table markup
- Make the status badge itself the availability toggle (no separate
"Mark Sold Out" button), fixed-width so toggling never shifts the
Status column, and shorten its label to "Sold Out"
- Merge the item Tag into the name line as an inline badge instead of
giving it its own column
- Group the move/edit/delete controls into two stacked button columns
(was 4-5 buttons wide) and right-align them on mobile
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Public site: replace the always-hidden mobile nav with a hamburger
toggle (index.php, menu.php, main.js, styles.css)
- Admin: render the Menu/Announcements/Users tables as labeled cards
below ~760px instead of squeezing descriptions into unreadable
single-word-per-line columns
- Admin menu: replace the manual "Order" number (which allowed
duplicates and never reflected in real time) with ↑/↓ buttons that
reorder items and categories immediately and renumber sort_order
sequentially on every move, self-healing any stale duplicates
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Implement admin user management interface (, , ) with async CRUD and password updating
- Add Users tab link to admin navigation across and
- Use in to lower specificity for native button resets, allowing modifier classes like to take precedence
Replaces the text-only Live Music section with a two-column layout
(photo alongside copy) featuring resident musician Jesse Hart, with
a responsive single-column fallback below 50em. Updates the section
copy to name a resident musician plus guest performers rather than
citing a single past artist by name.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
CSS redundancy cleanup on the online menu management feature:
- .menu-category was a byte-for-byte duplicate of the existing .panel
class (background/border/border-radius/padding); folds it into
.panel's shared selector group instead, keeping only what's not
shared (no margin-bottom, since these sit in a grid whose own gap
already spaces them)
- Several inline style="..." attributes were hand-copied verbatim
between admin/menu.php's PHP template and admin/menu.js's client-
side row/panel templates (price/sort/description cell formatting,
category heading spacing, the empty-state row). Replaced with real
CSS classes (.item-price-cell, .item-sort-cell, .item-desc-cell,
.cat-name-heading, .cat-desc-text, .no-items-row td) so the styling
lives in one place instead of two
- class="font-mono" was referenced four times but never defined
anywhere in CSS (silently doing nothing); it's now a real one-line
utility, which also fixes two previously-dead uses of it already
sitting in admin/index.php
- .form-actions already existed as a class with its own margin-top,
but every usage (two new modals here, plus a pre-existing one in
admin/index.php) redundantly re-specified layout via inline style
with a slightly different margin-top value each time; extended the
shared class to own the whole pattern and dropped all three inline
overrides
- Removed a no-op `justify-content: flex-start` (the default value)
from the new .admin-toolbar
Caught and fixed a regression from the above before it shipped:
removing the inline margin-bottom override on the category heading
exposed that .panel h2's margin-bottom (from the existing panel
styles) has higher specificity than a bare .cat-name-heading class,
so the heading would have rendered with 5x the intended spacing.
Rescoped as .category-panel .cat-name-heading to reliably win.
Also restores the "Mark Sold Out" / "Mark Available" button wording
(both directions of the toggle, in both the PHP-rendered rows and
the two JS render paths) after it had been shortened to just "Sold
Out" / "Available".
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds a public menu page (menu.php) and an admin CRUD interface
(admin/menu.php + admin/menu.js) backed by new menu_categories and
menu_items tables, replacing the "menu lives on Facebook" placeholder
on the homepage.
The admin JS/PHP came out of an AI-assisted pass that used outdated
JS (var, .then() chains, string-built HTML) and had some rough edges
security-wise, so this also:
- Rewrites the admin JS to modern ES (const/let, async/await,
template literals, dataset API) and splits it out of admin/menu.php
into admin/menu.js for proper separation of concerns
- Adds declare(strict_types=1) and PHP 8 match-based action dispatch
in place of an if-chain
- Validates category_id/item_id/category_id server-side before use,
so a bad ID returns a clean JSON error instead of an uncaught
PDOException or a null item breaking the client
- Rejects non-string POST fields instead of crashing trim() on them
- Replaces the category-save handler's full-page location.reload()
with in-place DOM updates (panel insert/update, resort by
sort_order, keep the item modal's category dropdown in sync), so
every admin action is now AJAX with no reload
- Sets data-name/data-desc via dataset assignment rather than string-
interpolating them into an HTML attribute, closing a stored-XSS
path through the category name/description fields
Removes seed-menu.php, a leftover stub with no working code left in
it after the AI's one-time seeding run.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Add --danger-bg/--danger-text tokens and point .error-msg,
.alert-error, and .btn-danger at them instead of repeating the
same rgba/hex literals
- Drop .login-btn's cursor: pointer (already covered by button.btn)
- Drop .btn-outline's background: transparent (already covered by
button.btn for buttons; default background for anchors)
No visual changes intended.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Update inc/announcements.php to support listing, fetching by ID, toggling, and deleting multiple announcements
- Upgrade admin/index.php to an announcement management view with data table, status indicators, and create/edit sub-views
- Add admin table and action styles to styles.css without using inline style blocks
- Update index.php to render all currently active banner and hours announcements dynamically
- Add --font-serif/--font-mono/--font-sans tokens to :root and point
all ~24 hardcoded font-family declarations at them
- Drop an exact-duplicate .footer-brand .knot rule
- Merge the shared background/border of .stat-card, .card,
.login-card, and .panel into one grouped selector
- Combine .btn-outline:hover and .nav-cta:hover into one rule
- Move remaining inline style="" attributes in index.php and
admin/index.php into named classes/rules (.about-grid h2,
footer address/.social-row spacing, .panel-head,
.checkbox-label-lg, .field-hint, .form-actions)
No visual changes intended — values carried over as-is.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Move all admin dashboard and login rules into styles.css
- Remove embedded <style> blocks from admin/login.php and admin/index.php
- Clean up redundant preview action button
- Add SQLite database initialization and management in inc/db.php
- Implement session authentication and CSRF security helpers in inc/auth.php
- Implement announcement querying and saving in inc/announcements.php
- Add management dashboard, login, and logout in admin/
- Protect db/ directory with Apache access controls
- Refactor hardcoded px values to rem and em across layout, components, and media queries
- Improve WCAG color contrast by updating --gold-dim token
- Convert hours table to a semantic description list (<dl>)
- Wrap hero logo in h1 for proper heading hierarchy
- Add database ignore rules to .gitignore
Static-turned-PHP site for a pub in Marion, Indiana, with:
- Hero section with tiled brick-texture background
- Live-capable stat card (Facebook followers/reviews via Graph API,
with graceful fallback to config.php constants when no token is set)
- Open Graph / Twitter Card meta tags for social sharing
- robots.txt
config.php is gitignored (holds a Facebook Page Access Token once
generated); config.sample.php is the tracked template — copy it to
config.php and fill in values to run this locally or in deployment.