- Created `admin-head.php` for consistent <head> markup across admin pages.
- Created `admin-nav.php` for shared navigation bar, reducing duplication.
- Updated all admin pages (account, hours, index, login, menu, users) to utilize the new components.
- Added security headers to `auth.php` and `index.php` for improved security.
- Introduced `security-headers.php` to manage security headers across the application.
- Moved inline styles from admin pages to SCSS files to comply with Content Security Policy (CSP).
- Normalized file permissions during build process to prevent permission issues on deployment.
- Added role-based access control for user management links in admin navigation.
- Improved user account display with a dedicated account link.
- Implemented form submission confirmation for delete actions in the admin interface.
- Introduced a password visibility toggle on the login page.
- Added login throttling to prevent brute-force attacks, recording failed attempts.
- Created a CLI script for creating an admin user, replacing the previous hardcoded admin credentials.
- Updated database schema to support login attempt tracking.
- Enhanced user editing functionality, allowing role changes with restrictions.
- Improved modal handling for user actions, ensuring better focus management.
- Added styles for new account management page and improved modal transitions.
- components/_cards.scss: .stat-card gets margin-top: 2rem; rebuilt
styles.css to match.
- index.php: strip trailing whitespace on a blank line in the music
section.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Breaks the single 2,167-line styles.scss into abstracts/base/components/
layout/pages partials, forwarded from styles.scss (now a manifest only)
via @use. Organized by what each rule is/does rather than by page, since
a lot of it is intentionally shared — the item/announcement/user admin
list grids share one CSS Grid system across three admin pages, and
.knot/.rule-row/.hero-ctas/the announcement banner are used on both
index.php and menu.php. Splitting by page would have fought that.
abstracts/tokens — :root custom properties
base/reset, utilities — bare-element defaults, small reusable utility classes
components/* — buttons, cards/panels, forms, status-badge,
admin data-grid, admin modal, announcement
banner, dividers, social-row
layout/* — header/nav, footer, admin nav+dashboard shell
pages/* — home, public menu, admin login/menu/hours
One real content move: .category-panel .panel-head's mobile override
now sits next to its desktop rule in pages/admin-menu instead of inside
the shared admin-data-grid mobile block — keeping it there would have
broken a same-specificity cascade order dependency once split across
files.
Verified behavior-preserving: fresh build's declaration count, class-
token set, and declaration multiset all match the pre-split styles.css
exactly; homepage, menu page, and admin login spot-checked visually and
via computed styles.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Replace inc/facebook-stats.php with inc/google-reviews.php: fetches
average star rating + review count from the Places API (New) instead
of Facebook's Graph API, same cache-to-JSON/fallback-on-failure shape
as before.
- index.php: stat card now shows the native star rating ("4.8★ average
rating") instead of a recommend %, sourced from Google. Drops the
Facebook-followers line entirely — Google's API has no equivalent and
showing a stale/static number wasn't worth keeping. "Follow on
Facebook" links elsewhere on the site are untouched.
- config.example.php: swap FB_PAGE_ID/FB_PAGE_ACCESS_TOKEN/
FB_STATS_CACHE_TTL/FB_FALLBACK_* for GOOGLE_PLACE_ID/
GOOGLE_PLACES_API_KEY/GOOGLE_STATS_CACHE_TTL/GOOGLE_FALLBACK_RATING/
GOOGLE_FALLBACK_REVIEW_COUNT (set to the pub's actual 4.8★/71 reviews),
with setup instructions in comments. config.php (gitignored) updated
to match.
- Remove the now-dead .stat-row CSS that only existed for the dropped
followers line; rebuild styles.css.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- 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>