Archived
docs: sync wikis from Gitea (2026-05-10 00:15 UTC)
This commit is contained in:
@@ -11,6 +11,7 @@ Consolidated backup of all project wikis from [Gitea](https://git.mokoconsulting
|
||||
- [**Template-Client-WaaS**](Template-Client-WaaS/) — 5 pages
|
||||
- [**backup-mcp**](backup-mcp/) — 6 pages
|
||||
- [**client-clarksvillefurs**](client-clarksvillefurs/) — 16 pages
|
||||
- [**client-waas-clarksvillefurs**](client-waas-clarksvillefurs/) — 16 pages
|
||||
- [**deploy-mcp**](deploy-mcp/) — 6 pages
|
||||
- [**joomla-api-mcp**](joomla-api-mcp/) — 6 pages
|
||||
- [**moko-platform**](moko-platform/) — 53 pages
|
||||
@@ -18,4 +19,4 @@ Consolidated backup of all project wikis from [Gitea](https://git.mokoconsulting
|
||||
- [**ssh-mcp**](ssh-mcp/) — 10 pages
|
||||
|
||||
---
|
||||
*Last synced: 2026-05-10 00:09 UTC*
|
||||
*Last synced: 2026-05-10 00:15 UTC*
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
# ClarksvilleFurs.com
|
||||
|
||||
Managed Joomla client site for the Clarksville Furs community — a free, all-ages furry community in Clarksville, TN.
|
||||
|
||||
## Infrastructure
|
||||
|
||||
| Environment | URL | Server |
|
||||
|---|---|---|
|
||||
| **Live** | [clarksvillefurs.com](https://clarksvillefurs.com) | DreamHost (iad1-shared-b7-01) |
|
||||
| **Dev** | [clarksvillefurs.dev.mokoconsulting.tech](https://clarksvillefurs.dev.mokoconsulting.tech) | Moko Dev Server |
|
||||
| **Monitoring** | [Grafana Dashboard](https://bench.mokoconsulting.tech/d/client-d85a0ed3/) | Moko Bench |
|
||||
|
||||
Both environments share the same database. Dev is an open mirror of live (without offline mode).
|
||||
|
||||
## Quick Links
|
||||
|
||||
| Task | How |
|
||||
|---|---|
|
||||
| Deploy to dev | Push to `dev` branch → auto-deploys via workflow |
|
||||
| Deploy to live | Merge to `main` → auto-deploys dev + live |
|
||||
| Sync extensions | `deploy_sync_joomla` MCP tool or `sync-servers.yml` workflow |
|
||||
| Monitor status | [Grafana dashboard](https://bench.mokoconsulting.tech/d/client-d85a0ed3/) |
|
||||
| Run backup | Akeeba Backup in Joomla admin |
|
||||
|
||||
## Platform
|
||||
|
||||
- **CMS:** Joomla 6.1.0
|
||||
- **Template:** MokoOnyx
|
||||
- **PHP:** 8.4 (web) / 8.2 (CLI)
|
||||
- **Platform type:** `client` (MokoStandards)
|
||||
|
||||
## Documentation
|
||||
|
||||
### Site Management
|
||||
- [Deployment](deployment) — server access, deploy workflow, SFTP configs
|
||||
- [Content Authoring](content-authoring) — article and page management
|
||||
- [Brand Reference](brand-reference) — logos, colors, voice
|
||||
|
||||
### Content Guides
|
||||
- [Style Guide](authoring-style-guide) — writing standards
|
||||
- [Quick Reference](authoring-quick-reference) — common tasks
|
||||
- [Cross-Post Preview](authoring-cross-post-preview) — social media teasers
|
||||
- [Ad Schedule](authoring-ad-schedule) — promotion calendar
|
||||
|
||||
### SOPs
|
||||
- [Website Management](authoring-sop-website-management) — admin procedures
|
||||
- [Moderation](authoring-sop-moderation) — community moderation
|
||||
|
||||
### Technical
|
||||
- [Theme Architecture](theme-architecture) — MokoOnyx template structure
|
||||
- [CSS Variables](css-variables) — custom theme variables
|
||||
- [Accessibility](accessibility) — WCAG compliance
|
||||
- [Migration Plan](migration-plan-events) — events system migration
|
||||
|
||||
## MokoStandards
|
||||
|
||||
This repo follows the [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home) governance framework.
|
||||
|
||||
- [Site Monitoring](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/SITE_MONITORING) — Prometheus + Grafana monitoring
|
||||
- [Joomla Sync](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/JOOMLA_SYNC) — dev ↔ live file sync
|
||||
- [Minification](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/MINIFICATION) — CSS/JS build pipeline
|
||||
|
||||
---
|
||||
|
||||
*Repo: [client-clarksvillefurs](https://git.mokoconsulting.tech/ClarksvilleFurs/client-waas-clarksvillefurs) · [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
|
||||
|
||||
| Revision | Date | Author | Description |
|
||||
|---|---|---|---|
|
||||
| 1.0 | 2026-05-09 | Moko Consulting | Initial version |
|
||||
@@ -0,0 +1,162 @@
|
||||
← [Home](Home)
|
||||
|
||||
# Accessibility
|
||||
|
||||
WCAG 2.1 AA is the baseline target for all text on the CF site. That means
|
||||
4.5:1 contrast for normal text and 3:1 for large text (≥18pt or ≥14pt bold) or
|
||||
UI components. This document tracks issues found during live-site audits, the
|
||||
theme-level mitigations in place, and the content-edit items that can't be
|
||||
fixed from CSS.
|
||||
|
||||
## Resolved in the theme
|
||||
|
||||
### Coral-on-sky links fail AA — fixed
|
||||
|
||||
Coral `#FF4B3E` on the sky blue backgrounds used across the site measures
|
||||
2.06:1 to 2.57:1, all below the 4.5:1 AA threshold.
|
||||
|
||||
| Fg | Bg | Ratio | Where |
|
||||
|---|---|---|---|
|
||||
| Coral | Sky Primary `#9CCEDB` | 2.33:1 | block-color-1, hero-primary |
|
||||
| Coral | Sky Secondary `#7FB7C6` | 2.06:1 | container-bottom-a, offline page bg |
|
||||
| Coral | Sky Raw `#a3cde2` | 2.57:1 | `.custom.sky` cards, container-top-b |
|
||||
|
||||
**Mitigation:** `user.css` has a scoped override that flips `--link-color` to
|
||||
ink `#1E1E1E` inside any element with a sky background (selectors cover
|
||||
`[style*="var(--color-primary)"]`, `[style*="var(--sky)"]`, `.cf-brand-callout`,
|
||||
`.container-top-b`, `.container-bottom-a`, `.hero-primary`, `.block-color-1`,
|
||||
`.custom.sky .card`, `.custom.yellow .card`, `.custom.red .card`).
|
||||
|
||||
**Hover state** uses coral, which does fail AA against sky. Hover is
|
||||
time-limited and visual affordance is already established by underline
|
||||
thickness change. Monitored but not currently a blocker.
|
||||
|
||||
### White-on-red fails AA — fixed
|
||||
|
||||
White on soft red `#ff7a73` measures 2.53:1. `.custom.red .card-body` now uses
|
||||
ink text (5.79:1, AA pass) instead of white.
|
||||
|
||||
### Muted text invisible on sky — fixed
|
||||
|
||||
Mascot Grey `#8F8F8F` on sky backgrounds drops below 2:1. Same scoped override
|
||||
bumps muted text to `#3a3a3a` inside sky surfaces.
|
||||
|
||||
### Light palette drift — fixed
|
||||
|
||||
Several Bootstrap palette variables in `light.custom.css` had accidentally held
|
||||
dark-mode values (`--light: #1B2027`, `--primary-text-emphasis: #7A1E15`,
|
||||
`--primary-bg-subtle: #3a1511`, etc.). These were silently breaking
|
||||
`.bg-primary-subtle`, `.text-primary-emphasis`, `.bg-light`, `.bg-dark` utility
|
||||
classes site-wide. All corrected to proper light-mode values in v02.02.00.
|
||||
|
||||
## Known exceptions — acceptable
|
||||
|
||||
### Coral on white, small text (3.63:1)
|
||||
|
||||
Coral on white background at body text size measures 3.63:1 — above AA-large
|
||||
(3:1) but below AA-normal (4.5:1). The `.cf-brand-accent` utility and the
|
||||
decorative `.text-danger` on headings compat rule only apply this color to
|
||||
large text (`h1`–`h6`, `.display-*`), where 3.63:1 is AA-pass. Link text with
|
||||
body font size uses a darker shade via `--link-color: #FF4B3E` + underline for
|
||||
affordance.
|
||||
|
||||
### Coral hover on dark-tint cards (1.05:1–1.39:1)
|
||||
|
||||
Hover state on `.custom.green` links is 1.39:1. Primary affordance is
|
||||
underline thickness change, which is preserved. Fix available: swap hover
|
||||
color to ink (11.4:1 AAA). Not applied by default because coral hover is the
|
||||
site-wide brand convention.
|
||||
|
||||
## Known issues — content-edit required
|
||||
|
||||
Theme CSS cannot fix these; they must be addressed in Joomla article content
|
||||
or module configuration.
|
||||
|
||||
### Placeholder URLs
|
||||
|
||||
Found in article content on about-us, faq, news:
|
||||
|
||||
```html
|
||||
<a href="/YOUR_FACEBOOK_URL">Facebook</a>
|
||||
```
|
||||
|
||||
Either replace with the real Facebook URL or remove the Facebook mention.
|
||||
|
||||
### Hardcoded brand-color CTAs
|
||||
|
||||
Home page has inline-styled Discord and Telegram CTAs:
|
||||
|
||||
```html
|
||||
```
|
||||
|
||||
Telegram's official light cyan fails AA with white text. Options:
|
||||
|
||||
1. Swap text to ink: `color: #1E1E1E` (5.09:1, AA pass)
|
||||
2. Use Telegram's darker brand variant `#0088CC` (5.09:1 with white, AA pass)
|
||||
3. Use a `.btn-primary` instead and accept that all CTAs look the same
|
||||
|
||||
All three require a content edit. Option 2 is most brand-authentic.
|
||||
|
||||
### Decorative `.text-danger` on body text
|
||||
|
||||
If an editor uses `<p class="text-danger">` to make a paragraph red (as
|
||||
decoration, not warning), the text renders as soft red `#ff7a73` — 3.14:1
|
||||
against white. Fails AA for normal text. The compat rule only applies to
|
||||
headings. For decorative red body text, use `.cf-brand-accent` (coral) instead
|
||||
— which also fails AA at body size, but is the intended brand color and is
|
||||
constrained to short spans.
|
||||
|
||||
Real semantic danger messages should stay in `.text-danger` and be kept to
|
||||
large-text usage (alerts, form validation summaries).
|
||||
|
||||
## Audit tools
|
||||
|
||||
### Style guide preview
|
||||
|
||||
Open `/style-guide.html` (at the repo root of any theme package delivery) in
|
||||
a browser. Contains:
|
||||
|
||||
- A Blue Gauntlet section exercising every common element on sky backgrounds
|
||||
- Contrast audit table computing ratios live for all common color pairs
|
||||
- Light/dark toggle
|
||||
- All tinted card variants rendered with sample content
|
||||
|
||||
### Browser DevTools
|
||||
|
||||
Chrome/Firefox DevTools Accessibility panel shows contrast ratios on hover for
|
||||
any text element. Fastest way to sanity-check a page before committing.
|
||||
|
||||
### WebAIM Contrast Checker
|
||||
|
||||
<https://webaim.org/resources/contrastchecker/> — paste in two hex values,
|
||||
confirms AA/AAA grading.
|
||||
|
||||
## Metadata
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Document Type | reference |
|
||||
| Domain | Accessibility |
|
||||
| Applies To | CF website (clarksvillefurs.com) |
|
||||
| Jurisdiction | WCAG 2.1 AA |
|
||||
| Owner | Moko Consulting |
|
||||
| Repo | mokoconsulting-tech/client-clarksvillefurs |
|
||||
| Path | ./docs/accessibility.md |
|
||||
| Version | 00.01.00 |
|
||||
| Status | Active |
|
||||
| Last Reviewed | 2026-04-21 |
|
||||
| Reviewed By | Claude |
|
||||
|
||||
## Revision History
|
||||
|
||||
| Date | Author | Change | Notes |
|
||||
|---|---|---|---|
|
||||
| 2026-04-21 | Claude | Initial creation | Findings from live-site audit at v02.06.00 |
|
||||
|
||||
---
|
||||
|
||||
*Repo: [client-clarksvillefurs](https://git.mokoconsulting.tech/ClarksvilleFurs/client-waas-clarksvillefurs) · [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
|
||||
|
||||
| Revision | Date | Author | Description |
|
||||
|---|---|---|---|
|
||||
| 1.0 | 2026-05-09 | Moko Consulting | Initial version |
|
||||
@@ -0,0 +1,89 @@
|
||||
← [Home](Home)
|
||||
|
||||
# Authoring Documentation
|
||||
|
||||
Documentation for anyone posting Events or News articles on the
|
||||
Clarksville Furs website. Written for members of the **Event Authors**
|
||||
Joomla group and the webmaster.
|
||||
|
||||
## Who these docs are for
|
||||
|
||||
- **Event Authors** — managers and volunteers who create and publish
|
||||
event listings and news posts through the Joomla admin.
|
||||
- **Webmaster** — the person responsible for the site, user accounts,
|
||||
and cross-post integrations.
|
||||
|
||||
## Reading order
|
||||
|
||||
If you're brand new, read in this order:
|
||||
|
||||
1. **[Quick Reference](quick-reference)** — numbered steps to log
|
||||
in, create an article, attach an image, and publish. One page,
|
||||
skimmable in under a minute.
|
||||
2. **[Style Guide](style-guide)** — voice and tone rules, title
|
||||
format, body length targets, image specs, and what not to do.
|
||||
3. **[Cross-Post Preview](cross-post-preview)** — how a single
|
||||
article shows up on Discord, Telegram, and Facebook, and which
|
||||
fields control what.
|
||||
4. **[Screencast Script](screencast-script)** — the spoken script
|
||||
for the recorded walkthrough video. Read this if you want a
|
||||
scene-by-scene overview of the full workflow before you try it.
|
||||
5. **[Ad Schedule](ad-schedule)** — promotional posting schedule
|
||||
for pre-launch (4 weeks) and post-launch (6 months) to drive
|
||||
traffic to the website.
|
||||
6. **[SOP — Website Management](sop-website-management)** — user
|
||||
accounts, content management, events, media, backups, and
|
||||
emergency procedures.
|
||||
7. **[SOP — Community Moderation](sop-moderation)** — 4-tier
|
||||
moderation system, platform-specific procedures, crisis handling,
|
||||
and moderator self-care.
|
||||
|
||||
If you've posted before and just need a refresher, start and stop at
|
||||
the Quick Reference.
|
||||
|
||||
## Related documents
|
||||
|
||||
- [Migration Plan — Events](migration-plan-events) — the
|
||||
upstream plan that defines when and how Events authoring goes live.
|
||||
- [Content Authoring Guide](content-authoring) — CSS utility
|
||||
classes available inside article HTML.
|
||||
- [Brand Reference](brand-reference) — palette, typography, and
|
||||
design decisions.
|
||||
- [Deployment Guide](deployment) — how theme changes ship to
|
||||
dev and production.
|
||||
|
||||
## Questions?
|
||||
|
||||
Use the [Contact Us](https://clarksvillefurs.com/contact-us) page or ask in #server-announcements on Discord.
|
||||
|
||||
---
|
||||
|
||||
## Metadata
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Document Type | index |
|
||||
| Domain | Content Authoring |
|
||||
| Applies To | Event Authors group, Webmaster |
|
||||
| Jurisdiction | Moko Consulting |
|
||||
| Owner | Moko Consulting |
|
||||
| Repo | mokoconsulting-tech/client-clarksvillefurs |
|
||||
| Path | ./docs/authoring/README.md |
|
||||
| Version | 00.01.00 |
|
||||
| Status | Active |
|
||||
| Last Reviewed | 2026-04-26 |
|
||||
| Reviewed By | Claude |
|
||||
|
||||
## Revision History
|
||||
|
||||
| Date | Author | Change | Notes |
|
||||
|---|---|---|---|
|
||||
| 2026-04-26 | Claude | Initial creation | Phase 3 authoring docs index |
|
||||
|
||||
---
|
||||
|
||||
*Repo: [client-clarksvillefurs](https://git.mokoconsulting.tech/ClarksvilleFurs/client-waas-clarksvillefurs) · [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
|
||||
|
||||
| Revision | Date | Author | Description |
|
||||
|---|---|---|---|
|
||||
| 1.0 | 2026-05-09 | Moko Consulting | Initial version |
|
||||
@@ -0,0 +1,138 @@
|
||||
← [Home](Home)
|
||||
|
||||
# Ad Schedule — Pre-Launch and Post-Launch
|
||||
|
||||
Promotional posting schedule for Discord, Telegram, and Facebook to
|
||||
build awareness of the website and drive traffic to
|
||||
clarksvillefurs.com.
|
||||
|
||||
All posts should link to the website as the primary destination — not
|
||||
to direct chat invites. The goal is to get members and newcomers
|
||||
interacting with the site, reading the FAQ, and using the events page.
|
||||
|
||||
---
|
||||
|
||||
## Pre-Launch (4 weeks before [LAUNCH DATE])
|
||||
|
||||
### Week 4 (T-28 days)
|
||||
|
||||
| Day | Platform | Post |
|
||||
|---|---|---|
|
||||
| Monday | Discord, Telegram | **Teaser**: "Something new is coming to Clarksville Furs. Stay tuned." (No link yet) |
|
||||
| Thursday | Facebook | **Teaser**: Same message, post to the Facebook group |
|
||||
|
||||
### Week 3 (T-21 days)
|
||||
|
||||
| Day | Platform | Post |
|
||||
|---|---|---|
|
||||
| Monday | Discord, Telegram | **Sneak peek**: "Our new website is almost ready. Here's a preview of what's coming — FAQ, events, and a whole new way to stay connected." Screenshot of the FAQ page. |
|
||||
| Wednesday | Facebook | **Sneak peek**: Same, with screenshot |
|
||||
| Friday | Discord | **FAQ highlight**: Share one FAQ answer as a teaser — "This and 11 more answers at clarksvillefurs.com/faq (coming soon)" |
|
||||
|
||||
### Week 2 (T-14 days)
|
||||
|
||||
| Day | Platform | Post |
|
||||
|---|---|---|
|
||||
| Monday | Discord, Telegram | **Feature spotlight — Events**: "Soon you'll be able to browse all CF events in one place — and submit your own. clarksvillefurs.com/events" |
|
||||
| Wednesday | Discord | **Feature spotlight — FAQ**: "Parents asking questions? Friends curious about the fandom? We built a FAQ page that covers it all." |
|
||||
| Friday | Facebook | **Countdown**: "One week out. The new Clarksville Furs website launches [LAUNCH DATE]." |
|
||||
|
||||
### Week 1 (T-7 days)
|
||||
|
||||
| Day | Platform | Post |
|
||||
|---|---|---|
|
||||
| Monday | All platforms | **Countdown**: "This week. clarksvillefurs.com goes live on [LAUNCH DATE]." |
|
||||
| Wednesday | Discord, Telegram | **Call to action**: "When the site launches, head to clarksvillefurs.com and explore. Read the FAQ. Check out the events page." |
|
||||
| Friday | All platforms | **Launch eve**: "Tomorrow. clarksvillefurs.com" |
|
||||
|
||||
### Launch Day
|
||||
|
||||
| Platform | Post |
|
||||
|---|---|
|
||||
| All platforms | **Launch**: "We're live! The new Clarksville Furs website is here. Explore the FAQ, browse upcoming events, and get to know the community. clarksvillefurs.com" |
|
||||
| Discord (pinned) | **Pinned**: "The Clarksville Furs website is live at clarksvillefurs.com. This is now the best place to find event details, read the FAQ, and learn about the community." |
|
||||
|
||||
---
|
||||
|
||||
## Post-Launch: Months 1–6
|
||||
|
||||
### Monthly recurring posts
|
||||
|
||||
| Frequency | Platform | Post type |
|
||||
|---|---|---|
|
||||
| 1st of month | All platforms | **Monthly reminder**: "All upcoming events are on clarksvillefurs.com/events. Browse what's coming up and RSVP." |
|
||||
| 15th of month | Discord, Telegram | **Submit your own event**: "Did you know members can create their own events? Visit clarksvillefurs.com/events and click Submit Event." |
|
||||
| Weekly (Mon) | Discord | **FAQ of the week**: Pick one FAQ article and share the intro text with a link. Rotate through all 12 over 3 months. |
|
||||
|
||||
### Month 1 — Establish habits
|
||||
|
||||
| Week | Platform | Post |
|
||||
|---|---|---|
|
||||
| 1 | All platforms | **Welcome post**: "New here? Start at clarksvillefurs.com — our FAQ answers the most common questions, and the events page shows you what's coming up." |
|
||||
| 2 | Discord, Telegram | **For parents**: "Got a kid who's into furries? Our FAQ has a page just for you: clarksvillefurs.com/faq" |
|
||||
| 3 | Facebook | **Share prompt**: "Know someone curious about the fandom? Share our FAQ with them: clarksvillefurs.com/faq" |
|
||||
| 4 | Discord | **Event submission reminder**: "Want to organize a game night, movie night, or meetup? Submit it at clarksvillefurs.com/events" |
|
||||
|
||||
### Month 2 — Deepen engagement
|
||||
|
||||
| Week | Platform | Post |
|
||||
|---|---|---|
|
||||
| 1 | Discord, Telegram | **Highlight a specific FAQ**: "What is a Therian?" intro text + link |
|
||||
| 2 | Facebook | **Convention planning**: "Thinking about a con trip? Check our events page for group plans: clarksvillefurs.com/events" |
|
||||
| 3 | Discord | **Feedback ask**: "Been using the website? Tell us what you think — use the Contact Us page: clarksvillefurs.com/contact-us" |
|
||||
| 4 | All platforms | **Community stat**: "X members and counting. If you haven't visited the site yet, now's a great time: clarksvillefurs.com" |
|
||||
|
||||
### Months 3–6 — Maintain cadence
|
||||
|
||||
By month 3, reduce to the monthly recurring schedule (1st and 15th)
|
||||
plus the weekly FAQ rotation on Discord. Add one-off posts only when:
|
||||
|
||||
- A new FAQ article is added
|
||||
- A major event is coming up
|
||||
- The website gets a significant update
|
||||
- A milestone is reached (member count, event count)
|
||||
|
||||
---
|
||||
|
||||
## Post guidelines
|
||||
|
||||
- **Always link to clarksvillefurs.com** — never give out direct
|
||||
Discord or Telegram invite links as the primary entry point
|
||||
- **Teasers, not full details** — drive traffic to the website for
|
||||
complete information
|
||||
- **Contact goes through the ticket system** — point people to
|
||||
clarksvillefurs.com/contact-us, not a direct email address
|
||||
- **Keep it casual** — match the CF voice (warm, direct, inclusive)
|
||||
- **One exclamation mark max** per post
|
||||
|
||||
---
|
||||
|
||||
## Metadata
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Document Type | schedule |
|
||||
| Domain | Content Marketing |
|
||||
| Applies To | Webmaster, Event Authors, Social media managers |
|
||||
| Jurisdiction | Moko Consulting |
|
||||
| Owner | Moko Consulting |
|
||||
| Repo | mokoconsulting-tech/client-clarksvillefurs |
|
||||
| Path | ./docs/authoring/ad-schedule.md |
|
||||
| Version | 00.01.00 |
|
||||
| Status | Draft |
|
||||
| Last Reviewed | 2026-04-27 |
|
||||
| Reviewed By | Claude |
|
||||
|
||||
## Revision History
|
||||
|
||||
| Date | Author | Change | Notes |
|
||||
|---|---|---|---|
|
||||
| 2026-04-27 | Claude | Initial creation | Pre-launch (4 weeks) and post-launch (6 months) promotional schedule |
|
||||
|
||||
---
|
||||
|
||||
*Repo: [client-clarksvillefurs](https://git.mokoconsulting.tech/ClarksvilleFurs/client-waas-clarksvillefurs) · [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
|
||||
|
||||
| Revision | Date | Author | Description |
|
||||
|---|---|---|---|
|
||||
| 1.0 | 2026-05-09 | Moko Consulting | Initial version |
|
||||
@@ -0,0 +1,238 @@
|
||||
← [Home](Home)
|
||||
|
||||
# Cross-Post Preview
|
||||
|
||||
When you publish an article in the **Events** or **News** category, it
|
||||
automatically cross-posts to three platforms. Each platform pulls
|
||||
different fields from the article. This page shows you exactly what
|
||||
goes where so you can tune your intro text and image before hitting
|
||||
Publish.
|
||||
|
||||
## How cross-posting works
|
||||
|
||||
Two integrations handle the cross-posts:
|
||||
|
||||
| Integration | Destination | Trigger |
|
||||
|---|---|---|
|
||||
| **MokoDiscordHook** | Discord — #server-announcements | `onContentAfterSave` fires when an article is saved in a configured category |
|
||||
| **Perfect Publisher** | Facebook Page + Telegram channel | Rule Engine matches the article category and posts via the FB and Telegram APIs |
|
||||
|
||||
You don't need to do anything extra. Save a published article in the
|
||||
right category and the cross-posts fire automatically.
|
||||
|
||||
**Important — teasers, not full details.** Cross-posts should hook the
|
||||
reader and drive them to the website. Write the intro as a short teaser
|
||||
that makes people want to click through to clarksvillefurs.com/events
|
||||
for the full info. Don't put the complete date, time, and location in
|
||||
the intro — save those for the article body.
|
||||
|
||||
## Worked example
|
||||
|
||||
Suppose you create this article:
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| **Title** | Monthly Meetup — Downtown Clarksville |
|
||||
| **Alias** | monthly-meetup-downtown-clarksville |
|
||||
| **Category** | Events |
|
||||
| **Intro text** | Our monthly meetup is back! Grab a lawn chair and come hang — full details on the website. |
|
||||
| **Intro Image** | `images/events/meetup-heritage-park.jpg` (1200x630, pavilion with picnic tables) |
|
||||
| **Intro Image Alt** | Pavilion at Heritage Park with picnic tables and string lights |
|
||||
| **Full article body** | (additional details: directions, parking, what to bring, RSVP link) |
|
||||
|
||||
Here's how that article renders on each surface:
|
||||
|
||||
---
|
||||
|
||||
### Discord — MokoDiscordHook embed
|
||||
|
||||
MokoDiscordHook sends a rich embed to #server-announcements. The
|
||||
embed uses these article fields:
|
||||
|
||||
| Embed element | Sourced from |
|
||||
|---|---|
|
||||
| **Embed title** | Article title |
|
||||
| **Embed description** | Intro text (first 1–2 sentences of the article body, before the "Read more" break) |
|
||||
| **Embed image** | Intro Image |
|
||||
| **Embed link** | Full article URL on clarksvillefurs.com |
|
||||
|
||||
**What it looks like in Discord:**
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────┐
|
||||
│ Monthly Meetup — Downtown Clarksville │
|
||||
│ │
|
||||
│ Our monthly meetup is back! Grab a │
|
||||
│ lawn chair and come hang — full │
|
||||
│ details on the website. │
|
||||
│ │
|
||||
│ │
|
||||
│ ┌────────────────────────────────────┐ │
|
||||
│ │ │ │
|
||||
│ │ [ intro image: pavilion with │ │
|
||||
│ │ picnic tables and string │ │
|
||||
│ │ lights ] │ │
|
||||
│ │ │ │
|
||||
│ └────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ clarksvillefurs.com │
|
||||
└──────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Tips for Discord:**
|
||||
|
||||
- Keep the intro under 200 characters for clean embed layout.
|
||||
- Title truncates around 70 characters — stay under.
|
||||
- The image renders full-width in the embed. Landscape (1200x630) is
|
||||
ideal.
|
||||
- Discord caches embeds aggressively. If you edit the article after
|
||||
posting, the Discord embed will **not** update.
|
||||
|
||||
---
|
||||
|
||||
### Telegram — Perfect Publisher message
|
||||
|
||||
Perfect Publisher posts to @ClarksvilleFurs as a text message
|
||||
with a link preview.
|
||||
|
||||
| Message element | Sourced from |
|
||||
|---|---|
|
||||
| **Message text** | Intro text + article URL |
|
||||
| **Link preview title** | Article title (from the page's `<meta og:title>`) |
|
||||
| **Link preview image** | Intro Image (from `<meta og:image>`) |
|
||||
| **Link preview description** | Meta description, or intro text if meta description is empty |
|
||||
|
||||
**What it looks like in Telegram:**
|
||||
|
||||
```
|
||||
Our monthly meetup is back! Grab a lawn
|
||||
chair and come hang — full details on
|
||||
the website.
|
||||
|
||||
clarksvillefurs.com/events/monthly-meetup-
|
||||
downtown-clarksville
|
||||
|
||||
┌────────────────────────────────┐
|
||||
│ [ link preview card ] │
|
||||
│ │
|
||||
│ Monthly Meetup — Downtown │
|
||||
│ Clarksville │
|
||||
│ │
|
||||
│ [ intro image thumbnail ] │
|
||||
│ │
|
||||
│ clarksvillefurs.com │
|
||||
└────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Tips for Telegram:**
|
||||
|
||||
- The intro text becomes the message body — write it as a teaser that
|
||||
hooks the reader and drives them to the website for full details.
|
||||
- Telegram generates the link preview from Open Graph meta tags. If the
|
||||
intro image is missing, Telegram may show no preview or a generic
|
||||
favicon.
|
||||
- The link preview caches. If you need to refresh it after editing,
|
||||
use Telegram's [@webpagebot](https://t.me/webpagebot) to clear the
|
||||
cache for the URL.
|
||||
|
||||
---
|
||||
|
||||
### Facebook — Perfect Publisher post
|
||||
|
||||
Perfect Publisher creates a post on the linked Facebook Page
|
||||
(clarksvillefurs) with a link card.
|
||||
|
||||
| Post element | Sourced from |
|
||||
|---|---|
|
||||
| **Post text** | Intro text (prepended to the link) |
|
||||
| **Link card title** | Article title (from `<meta og:title>`) |
|
||||
| **Link card image** | Intro Image (from `<meta og:image>`) |
|
||||
| **Link card description** | Meta description, or intro text if empty |
|
||||
| **Link card domain** | clarksvillefurs.com |
|
||||
|
||||
**What it looks like on Facebook:**
|
||||
|
||||
```
|
||||
Clarksville Furs
|
||||
Just now · 🌐
|
||||
|
||||
Our monthly meetup is back! Grab a lawn
|
||||
chair and come hang — full details on
|
||||
the website.
|
||||
|
||||
┌────────────────────────────────────┐
|
||||
│ │
|
||||
│ [ large link card image: │
|
||||
│ pavilion with picnic tables │
|
||||
│ and string lights ] │
|
||||
│ │
|
||||
├────────────────────────────────────┤
|
||||
│ CLARKSVILLEFURS.COM │
|
||||
│ Monthly Meetup — Downtown │
|
||||
│ Clarksville │
|
||||
│ Our monthly meetup is back! │
|
||||
│ Grab a lawn chair and come... │
|
||||
└────────────────────────────────────┘
|
||||
|
||||
👍 Like 💬 Comment ↗ Share
|
||||
```
|
||||
|
||||
**Tips for Facebook:**
|
||||
|
||||
- The link card image must be at least 600x315 px. The recommended
|
||||
1200x630 works perfectly.
|
||||
- Facebook caches link previews aggressively. If you update the image
|
||||
or title after the first post, use the Facebook Sharing Debugger to
|
||||
force a re-scrape of the URL.
|
||||
- The intro text appears *above* the link card. Keep it short and
|
||||
punchy — two sentences max.
|
||||
|
||||
---
|
||||
|
||||
## Field-to-surface cheat sheet
|
||||
|
||||
| Article field | Website | Discord | Telegram | Facebook |
|
||||
|---|---|---|---|---|
|
||||
| Title | Page heading | Embed title | Link preview title | Link card title |
|
||||
| Intro text | Category listing excerpt | Embed description | Message body | Post text |
|
||||
| Intro Image | Category listing thumbnail | Embed image | Link preview image | Link card image |
|
||||
| Intro Image Alt | `alt` attribute on `<img>` | Not displayed | Not displayed | Not displayed (but good practice) |
|
||||
| Full article body | Full article page | Not included | Not included | Not included |
|
||||
| Article URL | Canonical link | Embed link | Message link | Link card URL |
|
||||
| Meta description | `<meta name="description">` | Not used | Link preview fallback | Link card fallback |
|
||||
|
||||
**Key takeaway:** The **intro text** and **intro image** are the two
|
||||
fields that matter most for cross-posts. Get those right and every
|
||||
platform looks good.
|
||||
|
||||
---
|
||||
|
||||
## Metadata
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Document Type | guide |
|
||||
| Domain | Content Authoring |
|
||||
| Applies To | Event Authors group, Webmaster |
|
||||
| Jurisdiction | Moko Consulting |
|
||||
| Owner | Moko Consulting |
|
||||
| Repo | mokoconsulting-tech/client-clarksvillefurs |
|
||||
| Path | ./docs/authoring/cross-post-preview.md |
|
||||
| Version | 00.01.00 |
|
||||
| Status | Active |
|
||||
| Last Reviewed | 2026-04-26 |
|
||||
| Reviewed By | Claude |
|
||||
|
||||
## Revision History
|
||||
|
||||
| Date | Author | Change | Notes |
|
||||
|---|---|---|---|
|
||||
| 2026-04-26 | Claude | Initial creation | Phase 3 cross-post field mapping with worked example |
|
||||
|
||||
---
|
||||
|
||||
*Repo: [client-clarksvillefurs](https://git.mokoconsulting.tech/ClarksvilleFurs/client-waas-clarksvillefurs) · [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
|
||||
|
||||
| Revision | Date | Author | Description |
|
||||
|---|---|---|---|
|
||||
| 1.0 | 2026-05-09 | Moko Consulting | Initial version |
|
||||
@@ -0,0 +1,100 @@
|
||||
← [Home](Home)
|
||||
|
||||
# Quick Reference — Events and News
|
||||
|
||||
One-page cheat sheet. If you've posted before and just forgot the
|
||||
steps, this should get you unblocked in under a minute.
|
||||
|
||||
## Log in
|
||||
|
||||
1. Go to `clarksvillefurs.com/administrator`
|
||||
2. Enter your username and password.
|
||||
3. Complete the 2FA prompt (authenticator app code).
|
||||
4. You land on the Home Dashboard.
|
||||
|
||||
## Create a new article
|
||||
|
||||
5. From the Home Dashboard, click **Content > Articles > + New**.
|
||||
6. Enter the **Title** — use the format described in the
|
||||
[Style Guide](./style-guide.md#title-format).
|
||||
7. Set the **Alias** — Joomla auto-generates one from the title. Leave
|
||||
it unless you need a shorter URL slug.
|
||||
8. Set the **Category**:
|
||||
- **Events** for event listings.
|
||||
- **News** for announcements and updates.
|
||||
|
||||
## Write the body
|
||||
|
||||
9. Write a 1–2 sentence intro paragraph. This is the text that
|
||||
appears in cross-posts to Discord, Telegram, and Facebook — make
|
||||
it count.
|
||||
10. Add the rest of the article body. See the
|
||||
[Style Guide](./style-guide.md#body-length-targets) for length
|
||||
guidance.
|
||||
|
||||
## Attach an image
|
||||
|
||||
11. In the **Images** tab (below the editor):
|
||||
- **Intro Image** — shown in category list views and cross-posts.
|
||||
- **Full Article Image** — shown at the top of the full article.
|
||||
12. Click **Select** and upload or pick from the Media Manager.
|
||||
13. Fill in the **Alt Text** field — describe what's in the image.
|
||||
See [Style Guide — Image specs](./style-guide.md#image-specs).
|
||||
|
||||
## Set the publish date
|
||||
|
||||
14. In the **Publishing** tab:
|
||||
- **Start Publishing** — set the date and time the article should
|
||||
go live. Use this for scheduling future events.
|
||||
- Leave **Finish Publishing** blank unless the article should
|
||||
auto-expire.
|
||||
|
||||
## Publish
|
||||
|
||||
15. Set **Status** to **Published** (green toggle at the top).
|
||||
16. Click **Save & Close**.
|
||||
|
||||
## Verify
|
||||
|
||||
17. Open the site in a new tab and confirm the article appears in the
|
||||
correct category listing.
|
||||
18. Check that the intro image renders and the title is correct.
|
||||
19. Wait 1–2 minutes, then verify the cross-posts arrived:
|
||||
- Discord — #server-announcements
|
||||
- Telegram — @ClarksvilleFurs
|
||||
- Facebook — linked Facebook Page
|
||||
|
||||
If a cross-post didn't arrive, check the article category. Cross-posts
|
||||
only fire for articles saved in the **Events** or **News** categories.
|
||||
|
||||
---
|
||||
|
||||
## Metadata
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Document Type | guide |
|
||||
| Domain | Content Authoring |
|
||||
| Applies To | Event Authors group, Webmaster |
|
||||
| Jurisdiction | Moko Consulting |
|
||||
| Owner | Moko Consulting |
|
||||
| Repo | mokoconsulting-tech/client-clarksvillefurs |
|
||||
| Path | ./docs/authoring/quick-reference.md |
|
||||
| Version | 00.01.00 |
|
||||
| Status | Active |
|
||||
| Last Reviewed | 2026-04-26 |
|
||||
| Reviewed By | Claude |
|
||||
|
||||
## Revision History
|
||||
|
||||
| Date | Author | Change | Notes |
|
||||
|---|---|---|---|
|
||||
| 2026-04-26 | Claude | Initial creation | Phase 3 quick-reference cheat sheet |
|
||||
|
||||
---
|
||||
|
||||
*Repo: [client-clarksvillefurs](https://git.mokoconsulting.tech/ClarksvilleFurs/client-waas-clarksvillefurs) · [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
|
||||
|
||||
| Revision | Date | Author | Description |
|
||||
|---|---|---|---|
|
||||
| 1.0 | 2026-05-09 | Moko Consulting | Initial version |
|
||||
@@ -0,0 +1,245 @@
|
||||
← [Home](Home)
|
||||
|
||||
# Screencast Script — Events and News Walkthrough
|
||||
|
||||
**Runtime target:** 5–8 minutes
|
||||
**Presenter:** Moko Consulting (to be assigned)
|
||||
**Format:** Screen recording with voiceover
|
||||
|
||||
This is the read-from script for the recorded walkthrough. Screen
|
||||
directions are in `[BRACKETS]`. Spoken voiceover is the plain text
|
||||
beneath each direction.
|
||||
|
||||
---
|
||||
|
||||
## Scene 1 — Intro (0:00–0:30)
|
||||
|
||||
`[SCREEN: CF website homepage, scrolled to show the Events section]`
|
||||
|
||||
Hey everyone! This is a quick walkthrough of how to post events and
|
||||
news on the Clarksville Furs website. By the end of this video you'll
|
||||
know how to log in, create an article, attach an image, and publish —
|
||||
plus you'll see how your post automatically shows up on Discord,
|
||||
Telegram, and Facebook.
|
||||
|
||||
Let's jump in.
|
||||
|
||||
---
|
||||
|
||||
## Scene 2 — Logging in (0:30–1:15)
|
||||
|
||||
`[SCREEN: Browser navigating to clarksvillefurs.com/administrator]`
|
||||
|
||||
First, head to clarksvillefurs.com/administrator. This is the Joomla
|
||||
admin panel — it's where all content management happens.
|
||||
|
||||
`[SCREEN: Joomla login form — type username and password]`
|
||||
|
||||
Enter your username and password. These were set up for you when your
|
||||
account was created. If you don't have credentials yet, reach out to
|
||||
the [Contact Us](https://clarksvillefurs.com/contact-us) page.
|
||||
|
||||
`[SCREEN: 2FA prompt — enter authenticator code]`
|
||||
|
||||
You'll also need to enter a code from your authenticator app. This
|
||||
is two-factor authentication — it keeps the site secure even if your
|
||||
password gets compromised.
|
||||
|
||||
`[SCREEN: Home Dashboard loads]`
|
||||
|
||||
And we're in. This is the Home Dashboard. You can see quick links to
|
||||
articles, media, and users. We're going to create a new article.
|
||||
|
||||
---
|
||||
|
||||
## Scene 3 — Creating the article (1:15–2:45)
|
||||
|
||||
`[SCREEN: Click Content > Articles > + New in the top menu]`
|
||||
|
||||
Click **Content**, then **Articles**, then the **New** button. This
|
||||
opens a blank article editor.
|
||||
|
||||
`[SCREEN: Article editor — cursor in Title field]`
|
||||
|
||||
Start with the title. For events, we use the format "Event Name — em
|
||||
dash — Location." So for our monthly meetup, that's "Monthly Meetup —
|
||||
Downtown Clarksville."
|
||||
|
||||
`[SCREEN: Type the title "Monthly Meetup — Downtown Clarksville"]`
|
||||
|
||||
Keep it under 70 characters so it doesn't get cut off in Discord
|
||||
embeds.
|
||||
|
||||
`[SCREEN: Click the Category dropdown, select "Events"]`
|
||||
|
||||
Next, set the category. Pick **Events** for event listings or **News**
|
||||
for announcements. This is important — the category controls which
|
||||
cross-post integrations fire. If you pick the wrong category, your
|
||||
post won't show up on Discord or Telegram.
|
||||
|
||||
`[SCREEN: Click into the editor body area]`
|
||||
|
||||
Now write the body. Start with one or two sentences that summarize the
|
||||
event — the what, when, and where. This intro text is what people see
|
||||
on Discord, Telegram, and Facebook before they click through, so make
|
||||
it count.
|
||||
|
||||
`[SCREEN: Type intro text: "Come hang out with us this Saturday! We're meeting at the pavilion in Heritage Park, 12–3 PM. Bring a lawn chair and a good attitude."]`
|
||||
|
||||
After the intro, add whatever details people need: directions, parking,
|
||||
what to bring, an RSVP link. But keep it concise — 50 to 150 words is
|
||||
plenty for an event listing.
|
||||
|
||||
---
|
||||
|
||||
## Scene 4 — Adding an image (2:45–4:00)
|
||||
|
||||
`[SCREEN: Click the "Images" tab below the editor]`
|
||||
|
||||
Scroll down and click the **Images** tab. You'll see two image slots:
|
||||
Intro Image and Full Article Image.
|
||||
|
||||
`[SCREEN: Click "Select" next to Intro Image]`
|
||||
|
||||
The **Intro Image** is the one that matters most. It shows up in the
|
||||
category listing on the website and in every cross-post. Click
|
||||
**Select** to open the Media Manager.
|
||||
|
||||
`[SCREEN: Media Manager — upload a new image or select an existing one]`
|
||||
|
||||
You can upload a new image or pick one that's already in the library.
|
||||
For best results, use a landscape photo — 1200 by 630 pixels. Keep the
|
||||
file size under 500 KB. JPG works great for photos.
|
||||
|
||||
`[SCREEN: Select the image, return to the Images tab]`
|
||||
|
||||
Once you've picked the image, fill in the **Alt Text** field. This is
|
||||
a short description of what's *in* the image — not the event title.
|
||||
Something like "Pavilion at Heritage Park with picnic tables and string
|
||||
lights." Screen readers use this, and it's good practice for
|
||||
accessibility.
|
||||
|
||||
`[SCREEN: Type alt text into the Alt Text field]`
|
||||
|
||||
Don't skip the alt text. It takes five seconds and makes the site
|
||||
better for everyone.
|
||||
|
||||
---
|
||||
|
||||
## Scene 5 — Publishing options (4:00–5:00)
|
||||
|
||||
`[SCREEN: Click the "Publishing" tab]`
|
||||
|
||||
Click the **Publishing** tab. The main field here is **Start
|
||||
Publishing** — this is when the article goes live on the site.
|
||||
|
||||
`[SCREEN: Set Start Publishing to a date a few days from now]`
|
||||
|
||||
For events, I like to set this a few days before the event so people
|
||||
have time to see it and plan. You can also set **Finish Publishing** if
|
||||
you want the article to automatically disappear after the event date,
|
||||
but that's optional.
|
||||
|
||||
`[SCREEN: Scroll up to the Status toggle at the top]`
|
||||
|
||||
Last thing before we save — make sure the **Status** is set to
|
||||
**Published**. It's the green toggle at the top of the editor. If this
|
||||
is set to Unpublished, the article exists but nobody can see it.
|
||||
|
||||
---
|
||||
|
||||
## Scene 6 — Save and verify (5:00–6:00)
|
||||
|
||||
`[SCREEN: Click "Save & Close" in the toolbar]`
|
||||
|
||||
Click **Save & Close**. Joomla saves the article and drops you back to
|
||||
the article list.
|
||||
|
||||
`[SCREEN: Open the site frontend in a new tab, navigate to the Events category]`
|
||||
|
||||
Let's verify. Open the site in a new tab and navigate to the Events
|
||||
page. There's our article — title, intro text, and the image we just
|
||||
uploaded.
|
||||
|
||||
`[SCREEN: Click into the full article to show the complete content]`
|
||||
|
||||
Click into it to see the full article. Everything looks good.
|
||||
|
||||
---
|
||||
|
||||
## Scene 7 — Cross-post verification (6:00–7:00)
|
||||
|
||||
`[SCREEN: Switch to Discord — show the channel with the new embed]`
|
||||
|
||||
Now let's check the cross-posts. Over in Discord, in the
|
||||
#server-announcements channel, you can see the embed that fired
|
||||
automatically when we saved the article. It pulled in the title, the
|
||||
intro text, the image, and a link back to the full article on the
|
||||
website.
|
||||
|
||||
`[SCREEN: Switch to Telegram — show the channel message]`
|
||||
|
||||
Same thing on Telegram. The intro text is the message body, and
|
||||
there's a link preview card with the title and image.
|
||||
|
||||
`[SCREEN: Switch to Facebook — show the page post]`
|
||||
|
||||
And on Facebook — the page post has the intro text above a link card
|
||||
with the image and title.
|
||||
|
||||
All three platforms pulled from the same two fields: the **intro text**
|
||||
and the **intro image**. That's why those two fields matter the most.
|
||||
|
||||
---
|
||||
|
||||
## Scene 8 — Wrap-up (7:00–7:30)
|
||||
|
||||
`[SCREEN: Back on the CF website Events page]`
|
||||
|
||||
That's the whole workflow. To recap:
|
||||
|
||||
1. Log in with your credentials and 2FA code.
|
||||
2. Create a new article — set the title, category, and body.
|
||||
3. Attach an intro image with alt text.
|
||||
4. Set the publish date and status.
|
||||
5. Save, verify on the website, and confirm the cross-posts arrived.
|
||||
|
||||
If you get stuck, check the Quick Reference doc — it's a one-page
|
||||
cheat sheet with all the steps. And if something's not working, reach
|
||||
out to the [Contact Us](https://clarksvillefurs.com/contact-us) page.
|
||||
|
||||
Thanks for watching, and happy posting!
|
||||
|
||||
`[SCREEN: Fade to CF logo / end card]`
|
||||
|
||||
---
|
||||
|
||||
## Metadata
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Document Type | script |
|
||||
| Domain | Content Authoring |
|
||||
| Applies To | Screencast recording — Moko Consulting presenter |
|
||||
| Jurisdiction | Moko Consulting |
|
||||
| Owner | Moko Consulting |
|
||||
| Repo | mokoconsulting-tech/client-clarksvillefurs |
|
||||
| Path | ./docs/authoring/screencast-script.md |
|
||||
| Version | 00.01.00 |
|
||||
| Status | Draft |
|
||||
| Last Reviewed | 2026-04-26 |
|
||||
| Reviewed By | Claude |
|
||||
|
||||
## Revision History
|
||||
|
||||
| Date | Author | Change | Notes |
|
||||
|---|---|---|---|
|
||||
| 2026-04-26 | Claude | Initial creation | Phase 3 walkthrough script, 8 scenes, ~7 min target |
|
||||
|
||||
---
|
||||
|
||||
*Repo: [client-clarksvillefurs](https://git.mokoconsulting.tech/ClarksvilleFurs/client-waas-clarksvillefurs) · [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
|
||||
|
||||
| Revision | Date | Author | Description |
|
||||
|---|---|---|---|
|
||||
| 1.0 | 2026-05-09 | Moko Consulting | Initial version |
|
||||
@@ -0,0 +1,488 @@
|
||||
← [Home](Home)
|
||||
|
||||
# SOP — Community Moderation
|
||||
|
||||
Standard operating procedures for moderating the Clarksville Furs
|
||||
community across all platforms: the website, Discord, Telegram, and
|
||||
Facebook.
|
||||
|
||||
Clarksville Furs is an all-ages, family-friendly community. These
|
||||
procedures exist to keep it that way.
|
||||
|
||||
---
|
||||
|
||||
## 1. Guiding Principles
|
||||
|
||||
- **Safety first** — protect minors, protect vulnerable members,
|
||||
protect the community's reputation.
|
||||
- **Assume good intent** — most issues are misunderstandings, not
|
||||
malice. Educate before you escalate.
|
||||
- **Consistency** — enforce the same standards everywhere. What's not
|
||||
okay on Discord is not okay on Telegram, Facebook, or the website.
|
||||
- **Transparency** — when you take moderation action, explain why.
|
||||
Members deserve to know what rule was broken.
|
||||
- **Documentation** — log every moderation action. Patterns matter
|
||||
more than individual incidents.
|
||||
|
||||
---
|
||||
|
||||
## 2. Community Guidelines Summary
|
||||
|
||||
The full Community Guidelines are published at
|
||||
`clarksvillefurs.com/community-guidelines`. Key rules for moderators:
|
||||
|
||||
1. **All-ages content only** in all public spaces
|
||||
2. **No harassment, bullying, or targeted behavior**
|
||||
3. **No hate speech** — racism, homophobia, transphobia, or any
|
||||
identity-based attacks
|
||||
4. **No unsolicited sexual content** in any public space
|
||||
5. **No doxxing** — sharing someone's real name, address, workplace,
|
||||
or photo without consent
|
||||
6. **No spam or self-promotion** without moderator approval
|
||||
7. **Respect pronouns and chosen names**
|
||||
8. **No drama-baiting** — deliberately provocative posts designed to
|
||||
start arguments
|
||||
|
||||
---
|
||||
|
||||
## 3. Moderation Tiers
|
||||
|
||||
Not every issue requires the same response. Use the tier system to
|
||||
match the response to the severity.
|
||||
|
||||
### Tier 1 — Gentle reminder (most common)
|
||||
|
||||
**When to use:** First-time minor infractions. Off-topic posting,
|
||||
mild language in a family-friendly channel, accidental oversharing.
|
||||
|
||||
**Action:**
|
||||
1. Send a friendly DM (not a public callout).
|
||||
2. Explain which guideline was relevant.
|
||||
3. Ask them to edit or delete the message.
|
||||
4. No formal record unless it recurs.
|
||||
|
||||
**Example script:**
|
||||
> Hey! Just a heads-up — we keep things family-friendly in the public
|
||||
> channels. Would you mind editing/removing that message? Thanks!
|
||||
|
||||
### Tier 2 — Formal warning
|
||||
|
||||
**When to use:** Repeat minor infractions after a Tier 1 reminder, or
|
||||
a single moderate infraction (heated argument, inappropriate content
|
||||
that's not extreme, disrespectful behavior).
|
||||
|
||||
**Action:**
|
||||
1. DM the member with a clear statement of what happened and which
|
||||
rule was broken.
|
||||
2. Delete or hide the offending content.
|
||||
3. Log the warning in the moderation log (see Section 7).
|
||||
4. Inform other moderators so they're aware.
|
||||
|
||||
**Example script:**
|
||||
> Hi — this is a formal warning about [specific behavior] in
|
||||
> [channel/platform]. This violates our Community Guidelines,
|
||||
> specifically [rule number/name]. Please review the guidelines at
|
||||
> clarksvillefurs.com/community-guidelines. Further violations may
|
||||
> result in a temporary or permanent ban.
|
||||
|
||||
### Tier 3 — Temporary ban (24 hours to 30 days)
|
||||
|
||||
**When to use:** Serious single infractions or pattern of Tier 2
|
||||
warnings (3+ warnings in 90 days). Examples: explicit content in a
|
||||
public channel, targeted harassment, sustained disruptive behavior.
|
||||
|
||||
**Action:**
|
||||
1. Mute or ban the member on the affected platform.
|
||||
2. DM them with the reason and duration.
|
||||
3. Log in the moderation log with full context.
|
||||
4. Notify the moderation team.
|
||||
5. After the ban expires, send a welcome-back message reminding them
|
||||
of the guidelines.
|
||||
|
||||
**Duration guidelines:**
|
||||
- First temp ban: 24–72 hours
|
||||
- Second temp ban: 7–14 days
|
||||
- Third temp ban: 30 days, with a note that the next step is permanent
|
||||
|
||||
### Tier 4 — Permanent ban
|
||||
|
||||
**When to use:** Extreme violations (threats, doxxing, CSAM, predatory
|
||||
behavior toward minors) or failure to reform after multiple Tier 3
|
||||
bans.
|
||||
|
||||
**Action:**
|
||||
1. Immediately ban on all platforms (Discord, Telegram, Facebook,
|
||||
website).
|
||||
2. Do not engage in debate — the decision is final.
|
||||
3. Log the full incident with screenshots and timestamps.
|
||||
4. Notify the webmaster and Moko Consulting.
|
||||
5. If the violation involves a minor or is potentially criminal,
|
||||
see Section 6.
|
||||
|
||||
---
|
||||
|
||||
## 4. Platform-Specific Procedures
|
||||
|
||||
### 4.1 Discord
|
||||
|
||||
- **Roles**: Moderators have the `Content Moderators` role with
|
||||
permissions to delete messages, mute members, and manage channels.
|
||||
- **Slow mode**: Enable slow mode (30–60 seconds) during heated
|
||||
conversations instead of immediately banning.
|
||||
- **Channel locks**: Lock a channel temporarily if a situation is
|
||||
escalating. Announce: "Channel is paused while mods review. Be
|
||||
back shortly."
|
||||
- **DM policy**: Always DM the member before or after taking public
|
||||
action. Never moderate silently — it breeds distrust.
|
||||
- **Bot logs**: Check the audit log and bot logs for context before
|
||||
acting.
|
||||
|
||||
### 4.2 Telegram
|
||||
|
||||
- **Admin rights**: Moderators have admin rights in the main chat
|
||||
group.
|
||||
- **Announcement channel** (@ClarksvilleFurs): Only admins can post.
|
||||
No moderation needed — it's outbound only.
|
||||
- **Main chat group**: Apply the same tier system as Discord.
|
||||
- **Spam bots**: Telegram is prone to join-spam. Use the group's
|
||||
anti-spam bot and manually remove/ban spam accounts immediately.
|
||||
|
||||
### 4.3 Facebook group
|
||||
|
||||
- **Admin/Moderator roles**: Moderators have the Moderator role on the
|
||||
Facebook group.
|
||||
- **Post approval**: Consider enabling post approval for new members
|
||||
(first 30 days) to catch spam and inappropriate content before it's
|
||||
visible.
|
||||
- **Reporting**: Facebook has its own reporting system. If someone
|
||||
reports a post, review it promptly — Facebook may act independently
|
||||
if reports pile up.
|
||||
- **Non-members**: The group is public, so non-members can see content.
|
||||
Moderate accordingly — assume parents and employers are reading.
|
||||
|
||||
### 4.4 Website (Joomla)
|
||||
|
||||
Content Moderators have Joomla admin panel access and can manage
|
||||
content directly.
|
||||
|
||||
- **Admin access**: Content Moderators can log in at
|
||||
`clarksvillefurs.com/administrator` to manage articles and events.
|
||||
- **User blocking**: Go to **Users > Manage**, find the user, set
|
||||
**Block User** to Yes.
|
||||
- **Content removal**: Unpublish the article or event immediately.
|
||||
Investigate before permanently deleting — you may need the content
|
||||
as evidence.
|
||||
- **Event review**: Event Authors can auto-publish DPCalendar events.
|
||||
Review recently published events periodically and unpublish anything
|
||||
that violates Community Guidelines.
|
||||
- **Protected categories**: Content Moderators cannot edit FAQ, About
|
||||
Us, Legal, SOP, or News articles. Escalate to a Manager if changes
|
||||
are needed in those categories.
|
||||
- **Registration spam**: Check the Community Builder approval queue
|
||||
regularly. Reject accounts with obviously fake names, disposable
|
||||
emails, or no profile information.
|
||||
|
||||
---
|
||||
|
||||
## 5. In-Person Event Moderation
|
||||
|
||||
### 5.1 Meetup ground rules
|
||||
|
||||
All Clarksville Furs meetups follow the same Community Guidelines as
|
||||
online spaces. Additionally:
|
||||
|
||||
- **All-ages environment** — no alcohol at CF-organized events unless
|
||||
the venue is 21+ only and the event is explicitly labeled as such.
|
||||
- **Photography consent** — ask before photographing or filming anyone.
|
||||
Never photograph minors without explicit parental consent. Fursuiters
|
||||
may be photographed in public spaces unless they ask not to be.
|
||||
- **Personal space** — not everyone wants hugs. Ask first. "Can I hug
|
||||
you?" is always the right question.
|
||||
- **No weapons** — real or prop. Even if it's part of a costume.
|
||||
|
||||
### 5.2 Handling issues at a meetup
|
||||
|
||||
If someone is making others uncomfortable or violating guidelines:
|
||||
|
||||
1. Pull them aside privately — do not make a scene.
|
||||
2. Explain the issue calmly and specifically.
|
||||
3. If they cooperate, move on. No need to escalate.
|
||||
4. If they refuse or the behavior is serious, ask them to leave.
|
||||
Be firm but not aggressive: "I need you to head out for today.
|
||||
We can talk about this later."
|
||||
5. If they refuse to leave or become threatening, call 911. Do not
|
||||
physically confront anyone.
|
||||
6. Log the incident after the event. Follow the tier system for any
|
||||
online follow-up.
|
||||
|
||||
### 5.3 Photography and social media at events
|
||||
|
||||
- **Before the event**: Announce in Discord/Telegram that photos will
|
||||
be taken and may be shared on CF social media.
|
||||
- **At the event**: Designate a photographer if possible. Ask for
|
||||
verbal consent before posting photos of identifiable people.
|
||||
- **Minors**: Never post photos of minors on CF social media without
|
||||
written parental consent. When in doubt, don't post it.
|
||||
- **Fursuiters**: Fursuiters in public spaces generally expect to be
|
||||
photographed, but always respect a "no photos" request.
|
||||
|
||||
### 5.4 Venue-specific rules
|
||||
|
||||
Some venues have their own rules (no outside food, specific parking,
|
||||
noise limits). The event organizer should:
|
||||
|
||||
1. Visit the venue beforehand or call to confirm rules.
|
||||
2. Post venue rules in the event description.
|
||||
3. Remind attendees at the start of the meetup.
|
||||
4. If a member violates venue rules, address it immediately — losing
|
||||
a venue relationship hurts the whole community.
|
||||
|
||||
---
|
||||
|
||||
## 6. Handling Sensitive Situations
|
||||
|
||||
### 6.1 A member reports harassment
|
||||
|
||||
1. Thank them for reporting — never dismiss or minimize.
|
||||
2. Ask for screenshots, timestamps, and any witnesses.
|
||||
3. Do not reveal the reporter's identity to the accused.
|
||||
4. Investigate promptly (within 24 hours).
|
||||
5. Take action based on the tier system.
|
||||
6. Follow up with the reporter to let them know the outcome (without
|
||||
sharing details of any punishment).
|
||||
|
||||
### 6.2 A member is in crisis (self-harm, suicidal ideation)
|
||||
|
||||
1. Do not ignore it. Do not dismiss it as attention-seeking.
|
||||
2. Respond with empathy: "I hear you. I care about you. Can I help
|
||||
you find support?"
|
||||
3. Share the 988 Suicide and Crisis Lifeline: **call or text 988**.
|
||||
4. If you believe there is immediate danger, contact local emergency
|
||||
services (911).
|
||||
5. Notify the webmaster privately.
|
||||
6. Do not share the member's situation publicly or with other members.
|
||||
|
||||
### 6.3 A minor is involved
|
||||
|
||||
1. Any content involving a minor that is sexual, exploitative, or
|
||||
predatory is an **immediate Tier 4 permanent ban** on all
|
||||
platforms.
|
||||
2. Preserve all evidence (screenshots with timestamps).
|
||||
3. Contact the webmaster and Moko Consulting immediately.
|
||||
4. If the content may be illegal (CSAM, grooming), report to the
|
||||
National Center for Missing & Exploited Children (NCMEC) at
|
||||
CyberTipline.org and contact local law enforcement.
|
||||
5. Do not attempt to investigate yourself — let authorities handle it.
|
||||
|
||||
---
|
||||
|
||||
### 6.4 Content takedown or privacy request
|
||||
|
||||
If someone requests removal of content that identifies them (photos,
|
||||
real name, personal info):
|
||||
|
||||
1. Take the request seriously regardless of who posted the content.
|
||||
2. Remove or edit the content within 24 hours.
|
||||
3. If the content has cross-posted to Discord/Telegram/Facebook,
|
||||
delete those posts manually.
|
||||
4. Notify the original poster that the content was removed and why.
|
||||
5. No formal moderation action is needed against the poster unless
|
||||
the content was posted maliciously (doxxing — Tier 4).
|
||||
|
||||
### 6.5 Handling media or public attention
|
||||
|
||||
If CF receives press coverage, goes viral, or gets attention from
|
||||
outside the community:
|
||||
|
||||
1. Do not respond to journalists or media on behalf of CF without
|
||||
webmaster approval.
|
||||
2. Do not engage with trolls or bad-faith actors on social media.
|
||||
Ignore, mute, or block.
|
||||
3. If the attention is negative, consider temporarily setting Discord
|
||||
to slow mode and enabling Facebook post approval.
|
||||
4. Coordinate any official response through the webmaster.
|
||||
5. Document the situation for the team so everyone is on the same page.
|
||||
|
||||
---
|
||||
|
||||
## 7. Reporting to Authorities
|
||||
|
||||
If a moderation situation involves potential criminal activity:
|
||||
|
||||
1. **Do not delete the evidence.** Screenshot everything with
|
||||
timestamps and usernames.
|
||||
2. **Do not confront the individual** — this may cause them to
|
||||
destroy evidence or flee.
|
||||
3. Contact local law enforcement (Clarksville Police Department
|
||||
non-emergency: 931-648-0656) or 911 if there is immediate danger.
|
||||
4. For online exploitation of minors, file a report at
|
||||
CyberTipline.org (National Center for Missing & Exploited
|
||||
Children).
|
||||
5. Notify the webmaster and Moko Consulting.
|
||||
|
||||
---
|
||||
|
||||
## 8. Appeals Process
|
||||
|
||||
### 8.1 Who can appeal
|
||||
|
||||
Any member who receives a Tier 2 warning, Tier 3 temporary ban, or
|
||||
Tier 4 permanent ban may appeal. Tier 1 reminders are informal and
|
||||
not appealable.
|
||||
|
||||
### 8.2 How to appeal
|
||||
|
||||
1. The member contacts the webmaster via the Contact Us page at
|
||||
clarksvillefurs.com/contact-us (or by email if they are banned
|
||||
from the website).
|
||||
2. The appeal must include: what happened (their perspective), why
|
||||
they believe the action was incorrect or disproportionate, and
|
||||
what they would do differently.
|
||||
|
||||
### 8.3 Review process
|
||||
|
||||
1. The webmaster reviews the appeal against the moderation log.
|
||||
2. If the original moderator is available, get their input — but the
|
||||
webmaster makes the final call.
|
||||
3. Possible outcomes:
|
||||
- **Upheld** — the original action stands. Explain why.
|
||||
- **Modified** — reduce the severity (e.g., Tier 3 → Tier 2).
|
||||
Update the moderation log.
|
||||
- **Overturned** — remove the action entirely. Apologize if
|
||||
appropriate. Update the moderation log.
|
||||
4. Respond to the member within 7 days.
|
||||
5. Appeals are final. There is no second appeal.
|
||||
|
||||
### 8.4 Exceptions
|
||||
|
||||
Tier 4 bans for threats, CSAM, or predatory behavior toward minors
|
||||
are **not appealable**. These are safety decisions, not judgment calls.
|
||||
|
||||
---
|
||||
|
||||
## 9. Ban Evasion
|
||||
|
||||
### 9.1 Identifying alt accounts
|
||||
|
||||
Signs that a banned member has returned with a new account:
|
||||
|
||||
- New account created shortly after a ban
|
||||
- Same writing style, vocabulary, or topics
|
||||
- Same city/state in Community Builder profile
|
||||
- References to events or conversations the new account shouldn't
|
||||
know about
|
||||
- Other members report recognizing the person
|
||||
|
||||
### 9.2 Handling confirmed evasion
|
||||
|
||||
1. Ban the alt account immediately on all platforms.
|
||||
2. Log it as a new Tier 4 entry referencing the original ban.
|
||||
3. Do not engage in debate about whether it's really them.
|
||||
4. If evasion is persistent (3+ attempts), consider IP-based
|
||||
restrictions on Discord and website registration.
|
||||
|
||||
---
|
||||
|
||||
## 10. Moderator Onboarding
|
||||
|
||||
### 10.1 Checklist for new moderators
|
||||
|
||||
When adding a new Content Moderator:
|
||||
|
||||
- [ ] Add to the **Content Moderators** Joomla user group
|
||||
- [ ] Grant Discord moderator role
|
||||
- [ ] Grant Telegram admin rights in the main chat group
|
||||
- [ ] Grant Facebook group moderator role
|
||||
- [ ] Share access to the moderation log
|
||||
- [ ] Walk through this SOP document — especially Sections 3 (tiers),
|
||||
5 (in-person), and 6 (sensitive situations)
|
||||
- [ ] Introduce them to the mod team in the private moderator channel
|
||||
- [ ] Pair them with an experienced moderator for their first 2 weeks
|
||||
|
||||
### 10.2 Moderator expectations
|
||||
|
||||
- Check in on at least one platform daily (even just a glance)
|
||||
- Respond to reported issues within 24 hours
|
||||
- Log all Tier 2+ actions
|
||||
- Attend mod team check-ins (monthly or as scheduled)
|
||||
- Ask for help when unsure — there's no penalty for escalating
|
||||
|
||||
### 10.3 Removing a moderator
|
||||
|
||||
If a moderator steps down or is removed:
|
||||
|
||||
1. Remove from Content Moderators Joomla group (revokes admin access).
|
||||
2. Remove moderator roles on Discord, Telegram, and Facebook.
|
||||
3. Revoke access to the moderation log.
|
||||
4. Thank them for their service (if voluntary departure).
|
||||
|
||||
---
|
||||
|
||||
## 11. Moderation Log
|
||||
|
||||
All Tier 2+ actions must be logged. Use a shared document or
|
||||
spreadsheet accessible to all moderators.
|
||||
|
||||
Each entry should include:
|
||||
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| Date | Date and time of the incident |
|
||||
| Platform | Discord, Telegram, Facebook, Website |
|
||||
| Member | Username or display name |
|
||||
| Incident | Brief description of what happened |
|
||||
| Rule violated | Which community guideline was broken |
|
||||
| Tier | 2, 3, or 4 |
|
||||
| Action taken | Warning, mute, temp ban (duration), permanent ban |
|
||||
| Moderator | Who handled it |
|
||||
| Notes | Context, screenshots reference, follow-up needed |
|
||||
|
||||
---
|
||||
|
||||
## 12. Moderator Self-Care
|
||||
|
||||
Moderation is emotionally taxing. Take care of yourself:
|
||||
|
||||
- **You are not on call 24/7.** If something can wait until tomorrow,
|
||||
let it wait. Mute the channel and come back fresh.
|
||||
- **Tag-team difficult situations.** Don't handle a Tier 3 or 4
|
||||
alone — loop in another moderator.
|
||||
- **Step away if you're angry.** You'll make better decisions calm.
|
||||
Mute the conversation, take a walk, come back.
|
||||
- **Debrief after hard incidents.** Talk to a fellow moderator or the
|
||||
webmaster. You shouldn't carry it alone.
|
||||
- **It's okay to ask for help.** If a situation is beyond your
|
||||
experience, escalate to the webmaster or Moko Consulting.
|
||||
|
||||
---
|
||||
|
||||
## Metadata
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Document Type | SOP |
|
||||
| Domain | Community Moderation |
|
||||
| Applies To | Moderators, Content Moderators, Webmaster |
|
||||
| Jurisdiction | Moko Consulting |
|
||||
| Owner | Moko Consulting |
|
||||
| Repo | mokoconsulting-tech/client-clarksvillefurs |
|
||||
| Path | ./docs/authoring/sop-moderation.md |
|
||||
| Version | 00.02.00 |
|
||||
| Status | Active |
|
||||
| Last Reviewed | 2026-05-01 |
|
||||
| Reviewed By | Claude |
|
||||
|
||||
## Revision History
|
||||
|
||||
| Date | Author | Change | Notes |
|
||||
|---|---|---|---|
|
||||
| 2026-05-01 | Claude | Expanded: in-person events, appeals, ban evasion, onboarding, privacy/takedown, media handling | Sections 5, 6.4–6.5, 8–10 added; renumbered |
|
||||
| 2026-04-27 | Claude | Initial creation | 4-tier system, platform procedures, crisis handling, mod log, self-care |
|
||||
|
||||
---
|
||||
|
||||
*Repo: [client-clarksvillefurs](https://git.mokoconsulting.tech/ClarksvilleFurs/client-waas-clarksvillefurs) · [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
|
||||
|
||||
| Revision | Date | Author | Description |
|
||||
|---|---|---|---|
|
||||
| 1.0 | 2026-05-09 | Moko Consulting | Initial version |
|
||||
@@ -0,0 +1,441 @@
|
||||
← [Home](Home)
|
||||
|
||||
# SOP — Website Management
|
||||
|
||||
Standard operating procedures for the webmaster and authorized managers
|
||||
of the Clarksville Furs website (clarksvillefurs.com).
|
||||
|
||||
---
|
||||
|
||||
## 1. User Account Management
|
||||
|
||||
### 1.1 Creating a new user account
|
||||
|
||||
1. Log in to the Joomla admin at `clarksvillefurs.com/administrator`.
|
||||
2. Go to **Users > Manage > + New**.
|
||||
3. Fill in: name, username, email, and a temporary password.
|
||||
4. Assign the user to the appropriate group(s):
|
||||
- **Registered** — can log in and view member-only content
|
||||
- **Event Authors** — can create and auto-publish DPCalendar events,
|
||||
edit their own. Cannot post News or edit protected categories
|
||||
(FAQ, About Us, Legal, SOP).
|
||||
- **Content Moderators** — inherits Event Authors permissions, plus:
|
||||
can edit all articles, can access the Joomla admin panel, can
|
||||
manage content across all unlocked categories.
|
||||
- **Manager** — full content control including News, FAQ, About Us,
|
||||
Legal, and SOP categories. Admin panel access.
|
||||
5. Set **Require Password Reset** to Yes.
|
||||
6. Click **Save & Close**.
|
||||
7. Notify the user via the Contact Us system — never send credentials
|
||||
by Discord, Telegram, or any public channel.
|
||||
|
||||
### 1.2 Enabling 2FA for a user
|
||||
|
||||
1. The user logs in for the first time with their temporary password.
|
||||
2. They are prompted to set a new password.
|
||||
3. Go to **Users > Manage** and open the user's profile.
|
||||
4. Under **Multi-factor Authentication**, enable **Authenticator App**.
|
||||
5. The user scans the QR code with their authenticator app and enters
|
||||
the verification code.
|
||||
|
||||
### 1.3 Disabling or removing a user
|
||||
|
||||
1. Go to **Users > Manage** and find the user.
|
||||
2. To temporarily disable: set **Block User** to Yes. The account
|
||||
remains but cannot log in.
|
||||
3. To permanently remove: click the user, then **Delete**. This
|
||||
removes the account but preserves any articles they created.
|
||||
|
||||
### 1.4 Community Builder registration approval
|
||||
|
||||
New registrations through Community Builder require manual approval.
|
||||
|
||||
1. Check the **User Approval Queue** in the Staff Menu.
|
||||
2. Review the registration: name, email, location, birthday.
|
||||
3. Approve legitimate registrations. Reject obvious spam (gibberish
|
||||
names, throwaway emails, empty profiles).
|
||||
4. Approved users receive a welcome email automatically.
|
||||
|
||||
---
|
||||
|
||||
## 2. Content Management
|
||||
|
||||
### 2.1 Publishing an article
|
||||
|
||||
See the [Quick Reference](quick-reference) for the step-by-step
|
||||
workflow.
|
||||
|
||||
### 2.2 Reviewing published content
|
||||
|
||||
Event Authors can auto-publish DPCalendar events. Content Moderators
|
||||
and Managers should periodically review recently published content:
|
||||
|
||||
1. Go to **Content > Articles** or **Components > DPCalendar > Events**
|
||||
and sort by most recent.
|
||||
2. Review for:
|
||||
- Accurate date, time, and location (in the body, not the intro)
|
||||
- Intro text is a teaser that drives traffic to the website
|
||||
- Intro image is set with alt text
|
||||
- No personal contact info (emails, phone numbers)
|
||||
- Tone matches the [Style Guide](style-guide)
|
||||
3. If changes are needed, edit directly or contact the author.
|
||||
4. If content violates Community Guidelines, unpublish immediately
|
||||
and follow the [Moderation SOP](sop-moderation).
|
||||
|
||||
### 2.3 Who can post where
|
||||
|
||||
| Category | Event Authors | Content Mods | Manager+ |
|
||||
|---|---|---|---|
|
||||
| DPCalendar events | Create + publish + edit own | Edit all | Full |
|
||||
| News | No access | No access | Full |
|
||||
| FAQ | No access | No access | Full |
|
||||
| About Us | No access | No access | Full |
|
||||
| Legal | No access | No access | Full |
|
||||
| SOP | No access | No access | Full |
|
||||
|
||||
News articles are authored by Managers only to maintain editorial
|
||||
control over official announcements.
|
||||
|
||||
### 2.4 Editing an existing article
|
||||
|
||||
1. Go to **Content > Articles** and find the article.
|
||||
2. Click the title to open the editor.
|
||||
3. Make changes and click **Save & Close**.
|
||||
4. **Important**: If the article has already cross-posted to Discord,
|
||||
the Discord embed will NOT update. Telegram and Facebook link
|
||||
previews can be refreshed using their respective cache-clearing
|
||||
tools (see [Cross-Post Preview](cross-post-preview)).
|
||||
|
||||
### 2.5 Unpublishing or removing an article
|
||||
|
||||
1. To hide temporarily: set **Status** to **Unpublished**. The article
|
||||
stays in the database but is not visible on the site.
|
||||
2. To remove permanently: set **Status** to **Trashed**, then go to
|
||||
**Content > Articles**, filter by **Trashed**, select, and
|
||||
**Empty Trash**.
|
||||
3. Cross-posts on Discord, Telegram, and Facebook are NOT automatically
|
||||
removed — delete those manually if needed.
|
||||
|
||||
### 2.6 Managing the FAQ
|
||||
|
||||
FAQ articles are in the **FAQ** category (ID: 31). To add a new FAQ:
|
||||
|
||||
1. Create a new article in the FAQ category.
|
||||
2. Write a standalone intro paragraph that fully answers the question
|
||||
(see [Style Guide — Body length targets](style-guide)).
|
||||
3. Add a readmore break after the intro.
|
||||
4. Add detailed content below the break.
|
||||
5. Set the **Ordering** to place it in the right position on the FAQ
|
||||
page (see the current order by viewing the article list sorted by
|
||||
ordering).
|
||||
|
||||
---
|
||||
|
||||
## 3. Events (DPCalendar)
|
||||
|
||||
### 3.1 Creating an event
|
||||
|
||||
Events on the website use the DPCalendar component, not standard
|
||||
articles.
|
||||
|
||||
1. Go to **Components > DPCalendar > Events > + New**.
|
||||
2. Fill in: title, start date/time, end date/time, location, and
|
||||
description.
|
||||
3. Set the calendar (category) and access level.
|
||||
4. Add an image if available.
|
||||
5. Click **Save & Close**.
|
||||
|
||||
### 3.2 Member event submissions
|
||||
|
||||
Members with the **Event Authors** group can submit and auto-publish
|
||||
events from the frontend at `clarksvillefurs.com/events/submit`.
|
||||
|
||||
Events go live immediately — no approval step. Content Moderators and
|
||||
Managers should review recently published events periodically (see
|
||||
Section 2.2).
|
||||
|
||||
If an event needs to be taken down, a Content Moderator or Manager
|
||||
can unpublish it from the admin panel.
|
||||
|
||||
### 3.3 Recurring events
|
||||
|
||||
For monthly meetups or regular events:
|
||||
|
||||
1. Use DPCalendar's **Recurrence** feature.
|
||||
2. Set the recurrence pattern (e.g., first Saturday of every month).
|
||||
3. Individual occurrences can be edited without affecting the series.
|
||||
|
||||
---
|
||||
|
||||
## 4. Cross-Post Management
|
||||
|
||||
### 4.1 How cross-posting works
|
||||
|
||||
Two integrations automatically share content to social channels:
|
||||
|
||||
| Integration | Destination | Trigger |
|
||||
|---|---|---|
|
||||
| MokoDiscordHook | #server-announcements | `onContentAfterSave` for configured categories |
|
||||
| Perfect Publisher | Facebook group + @ClarksvilleFurs Telegram | Rule Engine on category match |
|
||||
|
||||
### 4.2 Verifying a cross-post
|
||||
|
||||
After publishing an article or event:
|
||||
|
||||
1. Wait 1–2 minutes for the integrations to fire.
|
||||
2. Check #server-announcements in Discord for the embed.
|
||||
3. Check @ClarksvilleFurs on Telegram for the message + link preview.
|
||||
4. Check the Facebook group for the post + link card.
|
||||
5. If any cross-post is missing, check that the article's category
|
||||
matches the configured trigger categories.
|
||||
|
||||
### 4.3 Troubleshooting cross-posts
|
||||
|
||||
| Symptom | Likely cause | Fix |
|
||||
|---|---|---|
|
||||
| No Discord embed | Article saved in wrong category, or webhook URL expired | Verify category in article. Check MokoDiscordHook plugin settings for valid webhook URL. |
|
||||
| Discord embed has wrong image | Intro Image not set, or cached | Set Intro Image in the article's Images tab. Discord caches aggressively — the image on the first post is permanent. |
|
||||
| No Telegram message | Perfect Publisher rule not matching, or bot token expired | Check Rule Engine rules. Verify bot is still a member of the channel. |
|
||||
| Telegram preview shows old image | Telegram caches link previews | Use [@webpagebot](https://t.me/webpagebot) to clear cache for the URL. |
|
||||
| No Facebook post | Page token expired, or Rule Engine rule disabled | Re-authenticate the Facebook Page in Perfect Publisher. Check Rule Engine. |
|
||||
| Facebook card shows wrong image | Facebook caches og:image | Use the [Facebook Sharing Debugger](https://developers.facebook.com/tools/debug/) to re-scrape the URL. |
|
||||
|
||||
### 4.4 What cross-posts cannot do
|
||||
|
||||
- Cross-posts do **not** update if you edit the article after
|
||||
publishing. The Discord embed is permanent. Telegram and Facebook
|
||||
can be refreshed via cache-clearing tools, but the original post
|
||||
text does not change.
|
||||
- Cross-posts do **not** auto-delete if you unpublish or trash the
|
||||
article. Delete the Discord message, Telegram message, and Facebook
|
||||
post manually.
|
||||
- Cross-posts show the **intro text only**, not the full article body.
|
||||
Write the intro as a teaser (see
|
||||
[Style Guide](./style-guide.md#body-length-targets)).
|
||||
|
||||
---
|
||||
|
||||
## 5. Community Builder Management
|
||||
|
||||
### 5.1 Required registration fields
|
||||
|
||||
New registrations require: first name, last name, username, email,
|
||||
password, city, state, zip code, country, and birthday.
|
||||
|
||||
### 5.2 Profile moderation
|
||||
|
||||
Periodically review Community Builder profiles for:
|
||||
|
||||
- Inappropriate profile images or avatars
|
||||
- Offensive usernames or display names
|
||||
- Spam or promotional content in profile bio fields
|
||||
- Fake or clearly fabricated profile information
|
||||
|
||||
To edit a profile: go to **Components > Community Builder > User
|
||||
Management**, find the user, click to edit.
|
||||
|
||||
### 5.3 Managing profile fields
|
||||
|
||||
To add, remove, or change required fields:
|
||||
|
||||
1. Go to **Components > Community Builder > Field Management**.
|
||||
2. Find the field by name.
|
||||
3. To make a field required: set **Required** to Yes.
|
||||
4. To show on registration: set **Registration** to Yes.
|
||||
5. To show on profile: set **Profile** to the desired visibility.
|
||||
|
||||
Current required fields: first name, last name, username, email,
|
||||
password, city, state, zip code, country, birthday.
|
||||
|
||||
---
|
||||
|
||||
## 6. Menu Management
|
||||
|
||||
### 6.1 Menu structure
|
||||
|
||||
| Menu | Purpose | Audience |
|
||||
|---|---|---|
|
||||
| Main Menu | Primary site navigation | Everyone |
|
||||
| User Menu | Login, logout, SOPs | Registered users |
|
||||
| Legal Menu | Terms, Privacy, Community Guidelines | Footer links |
|
||||
| Staff Menu | Profile, events, drafts, approvals | Staff/moderators |
|
||||
|
||||
### 6.2 Adding a menu item
|
||||
|
||||
1. Go to **Menus > [Menu Name] > + New**.
|
||||
2. Set the **Menu Item Type** (Single Article, Category Blog, URL, etc.).
|
||||
3. Set the **Title** and **Alias** (alias becomes the URL slug).
|
||||
4. Set **Access** to control who sees the menu item (Public, Registered,
|
||||
Content Moderators, etc.).
|
||||
5. Set **Parent Item** to control nesting.
|
||||
6. Click **Save & Close**.
|
||||
|
||||
### 6.3 Reordering menu items
|
||||
|
||||
1. Go to **Menus > [Menu Name]**.
|
||||
2. Click the ordering column header to enable drag-and-drop.
|
||||
3. Drag items to the desired position.
|
||||
4. Changes take effect immediately — no save needed.
|
||||
|
||||
---
|
||||
|
||||
## 7. Media Management
|
||||
|
||||
### 7.1 Uploading images
|
||||
|
||||
1. Go to **Content > Media** or use the inline media picker in the
|
||||
article editor.
|
||||
2. Organize images into folders: `events/`, `news/`, `branding/`.
|
||||
3. Image requirements:
|
||||
- Format: JPG for photos, PNG for graphics
|
||||
- Intro images: 1200 x 630 px, under 500 KB
|
||||
- Always fill in alt text
|
||||
4. Do not upload images with personally identifiable information
|
||||
(license plates, addresses, faces of minors without consent).
|
||||
|
||||
### 7.2 Cleaning up unused media
|
||||
|
||||
Periodically review the Media Manager for orphaned files:
|
||||
|
||||
1. Go to **Content > Media**.
|
||||
2. Sort by date and review old uploads.
|
||||
3. Before deleting, search for the filename in article content to
|
||||
confirm it is not in use.
|
||||
|
||||
---
|
||||
|
||||
## 8. Backups and Maintenance
|
||||
|
||||
### 8.1 Automated backups
|
||||
|
||||
The site is backed up daily by the hosting provider. Retention:
|
||||
daily for 30 days, weekly for 90 days, monthly for 12 months.
|
||||
|
||||
### 8.2 Cache clearing
|
||||
|
||||
After any significant content change:
|
||||
|
||||
1. Go to **System > Maintenance > Clear Cache**.
|
||||
2. Check all boxes and click **Clear Cache**.
|
||||
3. Go to **System > Maintenance > Purge Expired Cache**.
|
||||
|
||||
### 8.3 Updates
|
||||
|
||||
Joomla core, template, and extension updates are managed by Moko
|
||||
Consulting. Do not install updates without coordination.
|
||||
|
||||
### 8.4 Scheduled maintenance checklist
|
||||
|
||||
**Weekly:**
|
||||
|
||||
- [ ] Review Community Builder approval queue — approve or reject
|
||||
pending registrations
|
||||
- [ ] Check recently published events for accuracy and guideline
|
||||
compliance
|
||||
- [ ] Glance at the moderation log for patterns
|
||||
|
||||
**Monthly:**
|
||||
|
||||
- [ ] Review Media Manager for orphaned or oversized files
|
||||
- [ ] Check cross-post integrations are still firing (publish a test
|
||||
event, verify all three surfaces, then unpublish)
|
||||
- [ ] Review user accounts — block any that haven't logged in for
|
||||
12+ months if desired, or remove obvious spam accounts
|
||||
- [ ] Clear Joomla cache (**System > Maintenance > Clear Cache**)
|
||||
|
||||
**Quarterly:**
|
||||
|
||||
- [ ] Review FAQ articles — are answers still accurate? Any new
|
||||
questions coming up repeatedly in Discord?
|
||||
- [ ] Review SOP articles — do they still match current permissions
|
||||
and workflows?
|
||||
- [ ] Check that 2FA is enabled for all Content Moderators and Managers
|
||||
- [ ] Verify automated backups are running (check backup logs with
|
||||
Moko Consulting)
|
||||
- [ ] Review Community Builder required fields — are they still
|
||||
appropriate?
|
||||
|
||||
---
|
||||
|
||||
## 9. Analytics and Reporting
|
||||
|
||||
### 9.1 What to check
|
||||
|
||||
If analytics are configured (Google Analytics or Tag Manager):
|
||||
|
||||
- **Pageviews**: Which pages get the most traffic? FAQ and Events
|
||||
should be near the top.
|
||||
- **Referral sources**: Are cross-posts driving traffic from Discord,
|
||||
Telegram, and Facebook?
|
||||
- **Search terms**: What are people searching for on the site? Use
|
||||
this to identify missing FAQ articles.
|
||||
- **Bounce rate on Events**: If people land on the events page and
|
||||
leave immediately, the event descriptions may need improvement.
|
||||
|
||||
### 9.2 Reporting cadence
|
||||
|
||||
- **Monthly**: Glance at top pages and referral sources. No formal
|
||||
report needed — just awareness.
|
||||
- **Quarterly**: Share a brief summary with the team: top 5 pages,
|
||||
where traffic comes from, any FAQ gaps identified.
|
||||
|
||||
---
|
||||
|
||||
## 10. Emergency Procedures
|
||||
|
||||
### 10.1 Site is down
|
||||
|
||||
1. Check if the issue is local (try a different browser/device/network).
|
||||
2. Check the hosting provider's status page.
|
||||
3. Contact Moko Consulting via the Contact Us system or the emergency
|
||||
contact in the onboarding documentation.
|
||||
4. Do not attempt server-level fixes unless you have been trained.
|
||||
|
||||
### 10.2 Security incident (defacement, unauthorized access)
|
||||
|
||||
1. Do not make changes to the site — preserve evidence.
|
||||
2. Contact Moko Consulting immediately.
|
||||
3. If you have admin access, check **Users > Manage** for unfamiliar
|
||||
accounts.
|
||||
4. Change your own password immediately from a trusted device.
|
||||
|
||||
### 10.3 Spam or inappropriate content
|
||||
|
||||
1. Unpublish the content immediately.
|
||||
2. Block the user account if applicable.
|
||||
3. Document the incident (screenshot, user details, timestamp).
|
||||
4. Report to Moko Consulting if the spam came through an automated
|
||||
vector (registration exploit, comment spam).
|
||||
|
||||
---
|
||||
|
||||
## Metadata
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Document Type | SOP |
|
||||
| Domain | Website Management |
|
||||
| Applies To | Webmaster, Content Moderators |
|
||||
| Jurisdiction | Moko Consulting |
|
||||
| Owner | Moko Consulting |
|
||||
| Repo | mokoconsulting-tech/client-clarksvillefurs |
|
||||
| Path | ./docs/authoring/sop-website-management.md |
|
||||
| Version | 00.02.00 |
|
||||
| Status | Active |
|
||||
| Last Reviewed | 2026-05-01 |
|
||||
| Reviewed By | Claude |
|
||||
|
||||
## Revision History
|
||||
|
||||
| Date | Author | Change | Notes |
|
||||
|---|---|---|---|
|
||||
| 2026-05-01 | Claude | Expanded: cross-posts, CB profiles, menus, analytics, maintenance checklist | Sections 4–6, 8.4, 9 added; permissions updated for auto-publish model |
|
||||
| 2026-04-27 | Claude | Initial creation | User management, content, events, media, backups, emergencies |
|
||||
|
||||
---
|
||||
|
||||
*Repo: [client-clarksvillefurs](https://git.mokoconsulting.tech/ClarksvilleFurs/client-waas-clarksvillefurs) · [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
|
||||
|
||||
| Revision | Date | Author | Description |
|
||||
|---|---|---|---|
|
||||
| 1.0 | 2026-05-09 | Moko Consulting | Initial version |
|
||||
@@ -0,0 +1,178 @@
|
||||
← [Home](Home)
|
||||
|
||||
# Style Guide — Events and News
|
||||
|
||||
Rules for writing articles that sound like Clarksville Furs and look
|
||||
good across every surface (website, Discord, Telegram, Facebook).
|
||||
|
||||
## Voice and tone
|
||||
|
||||
Clarksville Furs articles should feel like a friend inviting you to
|
||||
hang out — not a corporation issuing a press release.
|
||||
|
||||
**Be:**
|
||||
|
||||
- **Warm** — "We'd love to see you there" over "Attendance is
|
||||
encouraged."
|
||||
- **Direct** — short sentences, plain words. Say what's happening,
|
||||
when, and where.
|
||||
- **Inclusive** — write for everyone: newcomers, families, kids, people
|
||||
who've never heard of the fandom. No inside jokes that leave readers
|
||||
out.
|
||||
- **Casual** — contractions are fine. "We're" not "We are." First
|
||||
person plural ("we", "our") for the group.
|
||||
- **Enthusiastic but not over-the-top** — one exclamation mark per
|
||||
article is plenty. Let the event speak for itself.
|
||||
|
||||
**Don't be:**
|
||||
|
||||
- Corporate — no "leverage", "synergy", "stakeholders", "action items."
|
||||
- Vague — "sometime in June" is not a date. Use `TBA` if it's truly
|
||||
unknown (see below).
|
||||
- Edgy — keep it family-friendly. No profanity, no sarcasm that could
|
||||
land wrong.
|
||||
|
||||
## Title format
|
||||
|
||||
Use this pattern for event titles:
|
||||
|
||||
```
|
||||
Event Name — Location
|
||||
```
|
||||
|
||||
Examples:
|
||||
|
||||
- `Monthly Meetup — Downtown Clarksville`
|
||||
- `Barnaby TN Ren Fest — Triune, TN`
|
||||
- `Movie Night — TBA`
|
||||
|
||||
For news articles, just use a clear descriptive title:
|
||||
|
||||
- `We're Live: Introducing Our New Website`
|
||||
- `Summer Schedule Update`
|
||||
|
||||
Rules:
|
||||
|
||||
- Use an em dash ( — ) between event name and location, not a hyphen.
|
||||
- Title-case the event name.
|
||||
- Keep it under 70 characters so it doesn't truncate in Discord embeds.
|
||||
- Don't put the date in the title — it's in the publish date and the
|
||||
body.
|
||||
|
||||
## Body length targets
|
||||
|
||||
| Article type | Target length | Notes |
|
||||
|---|---|---|
|
||||
| Event listing | 50–150 words | Date, time, location, what to expect, how to RSVP |
|
||||
| News post | 100–300 words | What happened or is changing, why it matters, what's next |
|
||||
| Longer feature | 300–600 words | Only when the topic genuinely needs it |
|
||||
|
||||
The first 1–2 sentences are the **intro**. This text appears in
|
||||
cross-posts and category listings. Write the intro as a **teaser** that
|
||||
hooks the reader and drives them to the full event page on the website
|
||||
— do not put the full date, time, and location in the intro. Save
|
||||
those details for the article body so people click through to
|
||||
clarksvillefurs.com/events to get the complete picture.
|
||||
|
||||
## Image specs
|
||||
|
||||
Every Events article should have an **Intro Image** set. This image
|
||||
appears in:
|
||||
|
||||
- The category list view on the website
|
||||
- Discord embeds (via MokoDiscordHook)
|
||||
- Facebook link cards (via Perfect Publisher)
|
||||
- Telegram link previews (via Perfect Publisher)
|
||||
|
||||
| Property | Requirement |
|
||||
|---|---|
|
||||
| Format | JPG or PNG (JPG preferred for photos) |
|
||||
| Dimensions | 1200 x 630 px (landscape, 1.91:1 ratio) |
|
||||
| File size | Under 500 KB |
|
||||
| Alt text | Required. Describe what's in the image, not the event title. Example: "Furries in costume at a park picnic table" |
|
||||
|
||||
Tips:
|
||||
|
||||
- Avoid text overlaid on the image — it gets cropped differently on
|
||||
each platform.
|
||||
- Use a photo of the venue, the group, or the activity. Generic stock
|
||||
images feel impersonal.
|
||||
- If you don't have a photo, use the CF mascot image from the Media
|
||||
Manager rather than leaving it blank.
|
||||
|
||||
## Using TBA for unknown details
|
||||
|
||||
If the date, time, or location isn't confirmed yet, use `TBA`
|
||||
(To Be Announced) as a placeholder:
|
||||
|
||||
- **Date unknown:** Set the publish date to today and write "Date: TBA"
|
||||
in the body. Update the article when the date is confirmed.
|
||||
- **Location unknown:** Use `TBA` in the title where the location goes:
|
||||
`Monthly Meetup — TBA`
|
||||
- **Time unknown:** Write "Time: TBA" in the body.
|
||||
|
||||
Always go back and update TBA fields before the event. A stale TBA
|
||||
looks like nobody's running things.
|
||||
|
||||
## Recurring events
|
||||
|
||||
For recurring events (monthly meetups, weekly game nights):
|
||||
|
||||
- Create a **new article** for each occurrence. Don't edit the old one.
|
||||
- Use a consistent title pattern: `Monthly Meetup — Downtown Clarksville`
|
||||
(same name each time, location may change).
|
||||
- In the body, reference that this is a recurring event:
|
||||
"Our monthly meetup is back! This month we're at..."
|
||||
- Set the **Start Publishing** date to a few days before the event so
|
||||
it shows up in the listing with lead time.
|
||||
|
||||
## What NOT to do
|
||||
|
||||
- **Don't use HTML in the article body** unless you're using an
|
||||
approved utility class (see
|
||||
[Content Authoring Guide](content-authoring)). The editor's
|
||||
visual mode handles formatting.
|
||||
- **Don't hardcode brand colors** inline — use `.cf-brand-accent` or
|
||||
`.cf-brand-callout` instead. See the
|
||||
[Content Authoring Guide](../content-authoring.md#patterns-to-avoid).
|
||||
- **Don't leave Alt Text blank** on images. Screen readers need it, and
|
||||
social platforms use it as fallback text.
|
||||
- **Don't write a novel.** If your event listing is over 200 words,
|
||||
you're probably over-explaining. Trust the reader.
|
||||
- **Don't duplicate the title in the first sentence.** The title is
|
||||
already displayed above the body.
|
||||
- **Don't use all caps** for emphasis. Bold a word if you must.
|
||||
- **Don't link to personal social media accounts** — only official CF
|
||||
channels.
|
||||
|
||||
---
|
||||
|
||||
## Metadata
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Document Type | guide |
|
||||
| Domain | Content Authoring |
|
||||
| Applies To | Event Authors group, Webmaster |
|
||||
| Jurisdiction | Moko Consulting |
|
||||
| Owner | Moko Consulting |
|
||||
| Repo | mokoconsulting-tech/client-clarksvillefurs |
|
||||
| Path | ./docs/authoring/style-guide.md |
|
||||
| Version | 00.01.00 |
|
||||
| Status | Active |
|
||||
| Last Reviewed | 2026-04-26 |
|
||||
| Reviewed By | Claude |
|
||||
|
||||
## Revision History
|
||||
|
||||
| Date | Author | Change | Notes |
|
||||
|---|---|---|---|
|
||||
| 2026-04-26 | Claude | Initial creation | Phase 3 voice, title, image, and formatting rules |
|
||||
|
||||
---
|
||||
|
||||
*Repo: [client-clarksvillefurs](https://git.mokoconsulting.tech/ClarksvilleFurs/client-waas-clarksvillefurs) · [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
|
||||
|
||||
| Revision | Date | Author | Description |
|
||||
|---|---|---|---|
|
||||
| 1.0 | 2026-05-09 | Moko Consulting | Initial version |
|
||||
@@ -0,0 +1,158 @@
|
||||
← [Home](Home)
|
||||
|
||||
# Brand Reference — Clarksville Furs
|
||||
|
||||
## Core palette
|
||||
|
||||
Nine tokens. Every color on the site should trace back to one of these.
|
||||
|
||||
| Token | Hex | Role |
|
||||
|---|---|---|
|
||||
| Sky Primary | `#9CCEDB` | Large surfaces, hero washes, block-color-1 |
|
||||
| Sky Secondary | `#7FB7C6` | Gradient depth, light-mode `--color-primary`, bottom-a container |
|
||||
| Sky Raw (`--sky`) | `#a3cde2` | Module tints, `.custom.sky` cards, top-b container background |
|
||||
| Coral Accent | `#FF4B3E` | CTAs, links, focus, `.btn-primary`, brand-accent text |
|
||||
| Ink Outline | `#1E1E1E` | Body text, linework, light-mode navigation background |
|
||||
| Mascot White | `#F4F4F4` | Soft surfaces, on-dark button text |
|
||||
| Mascot Grey | `#8F8F8F` | Muted text, secondary neutral |
|
||||
| Gold Eye | `#F5C518` | Highlights, warning states, `.custom.yellow` cards |
|
||||
| Soft Red | `#ff7a73` | `.btn-danger`, `.custom.red` cards — softer than coral, semantic danger |
|
||||
|
||||
The Sky Raw token `--sky` is available as a CSS custom property for direct
|
||||
reference in article HTML, module content, and user extensions. Prefer it over
|
||||
hardcoding `#a3cde2`.
|
||||
|
||||
## Typography
|
||||
|
||||
**Primary:** Fredoka (variable weight 300–700). Loaded locally from
|
||||
`/media/templates/site/mokoonyx/fonts/Fredoka-Variable.ttf` via `@font-face` in
|
||||
`user.css`.
|
||||
|
||||
**Secondary:** Nunito (weights 400–700). Loaded from Google Fonts for resilience;
|
||||
bundle locally if performance audits require it.
|
||||
|
||||
**Stack:**
|
||||
|
||||
```css
|
||||
--body-font-family: "Fredoka", "Nunito", "Inter",
|
||||
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
||||
"Helvetica Neue", Arial, "Noto Sans", sans-serif;
|
||||
```
|
||||
|
||||
**Weight scale (per brand guide):**
|
||||
|
||||
| Element | Weight | Notes |
|
||||
|---|---|---|
|
||||
| `h1`–`h3`, `.site-title` | 700 | Fredoka, letter-spacing `-0.01em` |
|
||||
| `h4`–`h6` | 600 | Fredoka |
|
||||
| `.lead`, `.callout`, `.subhead` | 500 | Fredoka |
|
||||
| Body (`p`, `li`, `td`, `dd`) | 400 | Nunito falls back to Fredoka |
|
||||
| `small`, `.text-muted`, `.meta` | 300 | Nunito |
|
||||
|
||||
**Note on `.site-title`:** MokoOnyx's base template ships with an "Osaka" font
|
||||
loaded via `fonts/osaka.css`. CF overrides this with `!important` in `user.css`
|
||||
to force Fredoka on site title markers. If the MokoOnyx template is updated and
|
||||
this class changes, the override may need to follow.
|
||||
|
||||
## Design decisions
|
||||
|
||||
These are the non-obvious choices that drive the look and won't survive a naïve
|
||||
"reset to defaults" pass. Read before changing anything in the theme.
|
||||
|
||||
### `--color-primary` is Sky Secondary (#7FB7C6) in light mode, not coral
|
||||
|
||||
MokoOnyx's offline page uses `--color-primary` as a full-viewport background.
|
||||
Coral at that scale would be jarring. Sky-secondary reads warm and on-brand at
|
||||
hero scale. Coral retains its role as the action color via Bootstrap's `--primary`.
|
||||
|
||||
### Navigation is ink in light mode, dark-neutral in dark mode
|
||||
|
||||
Light mode uses `#1E1E1E` ink as nav background with mascot-white text — structural
|
||||
brand presence at the top of every page. Dark mode uses `#151B22` neutral dark so
|
||||
the nav doesn't compete with content for attention. Active link is coral in light,
|
||||
sky in dark.
|
||||
|
||||
### Baseline `--border-radius` is 0.875rem
|
||||
|
||||
Matches the template's own offline-card radius. Gives consistent soft-rounded
|
||||
surfaces across form controls, badges, alerts, dropdowns, popovers, toasts.
|
||||
Cards use a slightly larger 1rem radius; hero cards use 1.25rem.
|
||||
|
||||
### Coral hover on dark-tint cards fails AA
|
||||
|
||||
`.custom.green` cards (`#448344`) keep white text (4.61:1 AA pass) but the
|
||||
coral hover on green links is 1.39:1 — visually invisible. This is documented
|
||||
in-file. If hover legibility becomes a complaint, swap hover to ink.
|
||||
|
||||
### `.custom.red` uses ink text, not white
|
||||
|
||||
White on `#ff7a73` is 2.53:1 (AA fail). Ink is 5.79:1 (AA pass) AND reads
|
||||
warmer, which matches the "Celebrating Individuality" card's intended tone.
|
||||
This is a deliberate departure from the "white on colored card" convention.
|
||||
|
||||
### `--danger` is soft red (#ff7a73), not coral
|
||||
|
||||
Bootstrap expects primary and danger to be distinct colors. Coral owns primary
|
||||
(brand action); soft red owns danger (alarm states). A compatibility rule in
|
||||
`user.css` keeps `.text-danger` on `h1`–`h6` and `.display-*` rendering as coral
|
||||
so existing hero content (which uses `.text-danger` decoratively) still reads as
|
||||
brand-accent. New decorative uses should prefer `.cf-brand-accent`.
|
||||
|
||||
## Accessibility baselines
|
||||
|
||||
All non-incidental text on the live site is checked to at least WCAG AA (4.5:1
|
||||
for normal text, 3:1 for ≥18pt or ≥14pt bold). Known exceptions are documented
|
||||
in [accessibility.md](accessibility).
|
||||
|
||||
**Contrast pairs that pass AA or better:**
|
||||
|
||||
| Foreground | Background | Ratio | Grade |
|
||||
|---|---|---|---|
|
||||
| Ink `#1E1E1E` | White `#FFFFFF` | 15.3:1 | AAA |
|
||||
| Ink `#1E1E1E` | Sky Primary `#9CCEDB` | 10.97:1 | AAA |
|
||||
| Ink `#1E1E1E` | Sky Secondary `#7FB7C6` | 8.22:1 | AAA |
|
||||
| Ink `#1E1E1E` | Sky Raw `#a3cde2` | 12.1:1 | AAA |
|
||||
| Ink `#1E1E1E` | Coral `#FF4B3E` | 5.16:1 | AA |
|
||||
| Ink `#1E1E1E` | Soft Red `#ff7a73` | 5.79:1 | AA |
|
||||
| Ink `#1E1E1E` | Gold `#F5C518` | 11.5:1 | AAA |
|
||||
| White `#F4F4F4` | Ink `#1E1E1E` | 15.3:1 | AAA |
|
||||
| White `#F4F4F4` | Dark Green `#448344` | 4.61:1 | AA |
|
||||
|
||||
**Contrast pairs that fail AA (known, documented, handled):**
|
||||
|
||||
| Foreground | Background | Ratio | Mitigation |
|
||||
|---|---|---|---|
|
||||
| Coral `#FF4B3E` | Sky Primary | 2.33:1 | Scoped override: links on sky containers flip to ink |
|
||||
| Coral `#FF4B3E` | Sky Secondary | 2.06:1 | Scoped override (same) |
|
||||
| Coral `#FF4B3E` | White (small text) | 3.63:1 | Only used for large text / headings (AA-large passes) |
|
||||
| White | Soft Red | 2.53:1 | Not used — `.custom.red` uses ink text instead |
|
||||
|
||||
## Metadata
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Document Type | reference |
|
||||
| Domain | Brand |
|
||||
| Applies To | All client-clarksvillefurs theme and content work |
|
||||
| Jurisdiction | Moko Consulting |
|
||||
| Owner | Moko Consulting |
|
||||
| Repo | mokoconsulting-tech/client-clarksvillefurs |
|
||||
| Path | ./docs/brand-reference.md |
|
||||
| Version | 00.01.00 |
|
||||
| Status | Active |
|
||||
| Last Reviewed | 2026-04-21 |
|
||||
| Reviewed By | Claude |
|
||||
|
||||
## Revision History
|
||||
|
||||
| Date | Author | Change | Notes |
|
||||
|---|---|---|---|
|
||||
| 2026-04-21 | Claude | Initial creation | Synthesized from brand guide + theme work |
|
||||
|
||||
---
|
||||
|
||||
*Repo: [client-clarksvillefurs](https://git.mokoconsulting.tech/ClarksvilleFurs/client-waas-clarksvillefurs) · [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
|
||||
|
||||
| Revision | Date | Author | Description |
|
||||
|---|---|---|---|
|
||||
| 1.0 | 2026-05-09 | Moko Consulting | Initial version |
|
||||
@@ -0,0 +1,184 @@
|
||||
← [Home](Home)
|
||||
|
||||
# Content Authoring Guide
|
||||
|
||||
This is for whoever writes articles, modules, and page content in the Joomla
|
||||
admin. The CF theme adds a small library of utility classes that make it easy
|
||||
to put on-brand components into articles without touching CSS.
|
||||
|
||||
## Quick lookup: "I want to…"
|
||||
|
||||
| Goal | Use | Example |
|
||||
|---|---|---|
|
||||
| Add a warm welcome/community box | `.cf-brand-callout` | See below |
|
||||
| Make heading text pop coral | `.cf-brand-accent` | `<span class="cf-brand-accent">Your place.</span>` |
|
||||
| Tint a feature card sky blue | `.custom.sky` wrapper on a `.card` | See below |
|
||||
| Tint a feature card red/yellow/green | `.custom.red` / `.custom.yellow` / `.custom.green` | See below |
|
||||
| Heavy sticker outline around any box | `.cf-sticker` | See below |
|
||||
|
||||
## `.cf-brand-callout` — welcome and community boxes
|
||||
|
||||
Use for the "💙 Clarksville Furs is an all-ages, family-friendly community"
|
||||
pattern on the FAQ page and similar. Handles the sky background, ink text,
|
||||
readable link color (ink with coral hover), and flex layout for an icon +
|
||||
paragraph.
|
||||
|
||||
```html
|
||||
<div class="cf-brand-callout">
|
||||
<span class="fs-5">💙</span>
|
||||
<p class="mb-0 small">
|
||||
<strong>Clarksville Furs is an all-ages, family-friendly community.</strong>
|
||||
Find us on <a href="/discord">Discord</a>,
|
||||
<a href="/telegram">Telegram</a>, and
|
||||
<a href="https://facebook.com/clarksvillefurs">Facebook</a>.
|
||||
</p>
|
||||
</div>
|
||||
```
|
||||
|
||||
**Do not** author this as inline `<div style="background: var(--color-primary)">`.
|
||||
The utility class handles the contrast scoping automatically — the inline
|
||||
pattern is legacy and currently works via a selector hack in `user.css` but
|
||||
should be migrated.
|
||||
|
||||
## `.cf-brand-accent` — coral brand-pop text
|
||||
|
||||
For the "pop of coral" on big headings that used to be done with `.text-danger`.
|
||||
|
||||
```html
|
||||
<h1 class="display-4 fw-bold">
|
||||
<span class="cf-brand-accent">Your place.</span> Your pack.
|
||||
</h1>
|
||||
```
|
||||
|
||||
`.text-danger` on h1–h6 and `.display-*` still renders as coral via a
|
||||
compatibility rule, so existing content doesn't break — but `.cf-brand-accent`
|
||||
is semantically correct and should be used for all new content.
|
||||
|
||||
## `.custom.{sky|red|yellow|green}` — tinted feature cards
|
||||
|
||||
Wrap a standard Bootstrap `.card` in a `.mod-custom.custom.{color}` module
|
||||
wrapper (or any div with `custom.{color}`) to paint it with a brand tint. The
|
||||
card-body text color auto-flips for legibility.
|
||||
|
||||
```html
|
||||
<div class="mod-custom custom sky">
|
||||
<div class="card border-0 h-100 rounded-3">
|
||||
<div class="card-body p-4 text-center">
|
||||
<i class="fa-solid fa-house fs-2 mb-3 d-block"></i>
|
||||
<h5 class="card-title fw-bold">Belonging First</h5>
|
||||
<p class="card-text small">
|
||||
Every decision starts with one question: will this make someone
|
||||
feel welcome?
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
Tint → text-color mapping:
|
||||
|
||||
| Class | Card bg | Card body text | AA on body |
|
||||
|---|---|---|---|
|
||||
| `.custom.sky` | `#a3cde2` | Ink (black) | 12.1:1 AAA |
|
||||
| `.custom.red` | `#ff7a73` | Ink (black) | 5.79:1 AA |
|
||||
| `.custom.yellow` | `#ffd166` | Ink (black) | 13.3:1 AAA |
|
||||
| `.custom.green` | `#448344` | White | 4.61:1 AA |
|
||||
|
||||
Links inside these cards are auto-styled:
|
||||
|
||||
- `.custom.sky`, `.custom.red`, `.custom.yellow` — ink links, coral hover
|
||||
- `.custom.green` — white links, coral hover (hover contrast is low — don't
|
||||
rely on hover color alone to indicate interactivity)
|
||||
|
||||
## `.cf-sticker` — heavy-outline sticker aesthetic
|
||||
|
||||
Opt-in mascot-inspired look: thick outline and hard-offset shadow that lifts on
|
||||
hover. Use sparingly, for feature callouts and stickers where the brand
|
||||
personality should shout.
|
||||
|
||||
```html
|
||||
<div class="cf-sticker p-4 bg-white">
|
||||
<h3>Meet-up this Saturday</h3>
|
||||
<p>Join us at the park — bring snacks, bring friends.</p>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Patterns to avoid
|
||||
|
||||
### Inline hex colors for brand colors
|
||||
|
||||
```html
|
||||
<span style="color: #FF4B3E;">Your place.</span>
|
||||
|
||||
<span class="cf-brand-accent">Your place.</span>
|
||||
```
|
||||
|
||||
Hardcoded hexes don't update when the theme does. If the brand ever shifts
|
||||
(new accent color, tonal correction), utility classes update site-wide in a
|
||||
single CSS change.
|
||||
|
||||
### Inline `style="background: var(--color-primary)"`
|
||||
|
||||
Currently works because `user.css` has a scoped override, but it's fragile.
|
||||
Prefer `.cf-brand-callout` for callout boxes.
|
||||
|
||||
### White-on-coral text
|
||||
|
||||
```html
|
||||
<a href="..." style="background: #FF4B3E; color: white;">Join us</a>
|
||||
|
||||
<a href="..." class="btn btn-primary">Join us</a>
|
||||
```
|
||||
|
||||
The `.btn-primary` class handles the ink-on-coral contrast correctly. Don't
|
||||
re-invent it inline.
|
||||
|
||||
### Hardcoded brand colors that fail contrast
|
||||
|
||||
The home page currently has a Telegram CTA with `style="background: #26A5E4;
|
||||
color: #fff;"` — white on Telegram's official light cyan measures 2.44:1, fails
|
||||
AA. Either use ink text (`color: #1E1E1E`, 5.09:1 AA) or switch to Telegram's
|
||||
darker brand variant `#0088CC`.
|
||||
|
||||
## Common edits that need a content pass
|
||||
|
||||
When any of these come up in an editor review, expect to fix content, not CSS:
|
||||
|
||||
- **Placeholder URLs** like `/YOUR_FACEBOOK_URL`, `YOUR_DISCORD_INVITE_URL`,
|
||||
`YOUR_TELEGRAM_URL` — real URLs are `/discord` and `/telegram` (server-side
|
||||
redirects). Facebook needs a real URL or the mention should be removed.
|
||||
- **Hardcoded brand-color CTAs** without contrast audit — Discord `#5865F2`
|
||||
with white text is fine (4.50:1), Telegram `#26A5E4` fails.
|
||||
- **Decorative `.text-danger`** on body text — only on headings does the
|
||||
compatibility rule keep it coral. On body text it renders as soft red
|
||||
(correctly, semantically), which may not be the author's intent.
|
||||
|
||||
## Metadata
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Document Type | guide |
|
||||
| Domain | Content Authoring |
|
||||
| Applies To | All Joomla article editors working on the CF site |
|
||||
| Jurisdiction | Moko Consulting |
|
||||
| Owner | Moko Consulting |
|
||||
| Repo | mokoconsulting-tech/client-clarksvillefurs |
|
||||
| Path | ./docs/content-authoring.md |
|
||||
| Version | 00.01.00 |
|
||||
| Status | Active |
|
||||
| Last Reviewed | 2026-04-21 |
|
||||
| Reviewed By | Claude |
|
||||
|
||||
## Revision History
|
||||
|
||||
| Date | Author | Change | Notes |
|
||||
|---|---|---|---|
|
||||
| 2026-04-21 | Claude | Initial creation | Covers v02.06.00 theme utility classes |
|
||||
|
||||
---
|
||||
|
||||
*Repo: [client-clarksvillefurs](https://git.mokoconsulting.tech/ClarksvilleFurs/client-waas-clarksvillefurs) · [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
|
||||
|
||||
| Revision | Date | Author | Description |
|
||||
|---|---|---|---|
|
||||
| 1.0 | 2026-05-09 | Moko Consulting | Initial version |
|
||||
@@ -0,0 +1,260 @@
|
||||
← [Home](Home)
|
||||
|
||||
# CSS Variables Reference
|
||||
|
||||
Quick reference for the CSS custom properties that drive the CF theme. The full
|
||||
theme files (`light.custom.css` and `dark.custom.css`) declare 924+ variables
|
||||
each, but most are Bootstrap internals that inherit from the tokens below. Edit
|
||||
the tokens, not the internals.
|
||||
|
||||
Base template: [MokoOnyx](https://github.com/mokoconsulting-tech/MokoCassiopeia)
|
||||
(formerly MokoCassiopeia).
|
||||
|
||||
---
|
||||
|
||||
## Brand tokens
|
||||
|
||||
These are the raw CF brand values. Every other variable in the theme should
|
||||
trace back to one of these.
|
||||
|
||||
| Token | Variable | Light | Dark | Notes |
|
||||
|---|---|---|---|---|
|
||||
| Sky Primary | `--accent-color-secondary` (light) / `--color-primary` (dark) | `#9CCEDB` | `#9CCEDB` | Hero washes, large surfaces |
|
||||
| Sky Secondary | `--color-primary` (light) / `--accent-color-secondary` (dark) | `#7FB7C6` | `#7FB7C6` | Gradient depth, offline page bg |
|
||||
| Sky Raw | `--sky` | `#a3cde2` | `#a3cde2` | Module tints, `.custom.sky` cards |
|
||||
| Coral | `--accent-color-primary` | `#FF4B3E` | `#FF4B3E` | CTAs, links, focus rings |
|
||||
| Ink | `--body-color` (light) | `#1E1E1E` | n/a | Body text, linework |
|
||||
| Mascot White | `--white` | `#F4F4F4` | `#F4F4F4` | Soft surfaces, on-dark text |
|
||||
| Mascot Grey | `--muted-color` | `#8F8F8F` | `#8F8F8F` | Secondary text |
|
||||
| Gold | `--yellow` | `#F5C518` | `#F5C518` | Highlights, warnings |
|
||||
| Soft Red | `--danger` | `#ff7a73` | `#ff7a73` | Danger states |
|
||||
|
||||
**Key light/dark swap:** `--color-primary` is Sky Secondary in light mode but
|
||||
Sky Primary in dark mode. This is intentional — see
|
||||
[brand-reference.md](./brand-reference.md#--color-primary-is-sky-secondary-7fb7c6-in-light-mode-not-coral)
|
||||
for the reasoning.
|
||||
|
||||
---
|
||||
|
||||
## Bootstrap palette mapping
|
||||
|
||||
CF brand tokens mapped to Bootstrap's contextual color system. These drive
|
||||
`.btn-*`, `.bg-*`, `.text-*`, `.border-*`, `.alert-*`, and `.badge-*` utilities.
|
||||
|
||||
| Bootstrap semantic | Light value | Dark value | CF token |
|
||||
|---|---|---|---|
|
||||
| `--primary` | `#FF4B3E` (Coral) | `#FF4B3E` | Coral Accent |
|
||||
| `--secondary` | `#8F8F8F` (Mascot Grey) | `#8F8F8F` | Mascot Grey |
|
||||
| `--success` | `#4AA664` | `#4AA664` | -- (standard green) |
|
||||
| `--info` | `#7FB7C6` (Sky Secondary) | `#7FB7C6` | Sky Secondary |
|
||||
| `--warning` | `#F5C518` (Gold) | `#F5C518` | Gold Eye |
|
||||
| `--danger` | `#ff7a73` (Soft Red) | `#ff7a73` | Soft Red |
|
||||
| `--light` | `#F4F4F4` (Mascot White) | `#F4F4F4` | Mascot White |
|
||||
| `--dark` | `#1E1E1E` (Ink) | `#1E1E1E` | Ink Outline |
|
||||
|
||||
**Note:** `--primary` is Coral (the action color), not Sky. `--info` is Sky
|
||||
Secondary. This is deliberate — Coral is the CTA/interaction color across the
|
||||
site; Sky is the ambient brand surface.
|
||||
|
||||
---
|
||||
|
||||
## Dark mode color strategy
|
||||
|
||||
The theme supports full light/dark mode switching. Key differences:
|
||||
|
||||
| Property | Light | Dark | Why |
|
||||
|---|---|---|---|
|
||||
| `--color-primary` | `#7FB7C6` (Sky Secondary) | `#9CCEDB` (Sky Primary) | Lighter sky reads better against dark backgrounds |
|
||||
| `--body-color` | `#1E1E1E` (Ink) | `#E6EBF1` (Light gray) | Ink is the text color in light; light gray in dark |
|
||||
| `--body-bg` | `#FFFFFF` | `#0E1318` (Near-black) | |
|
||||
| `--heading-color` | `#1E1E1E` | `#F4F4F4` (Mascot White) | |
|
||||
| `--nav-bg-color` | `#1E1E1E` (Ink) | `#151B22` (Dark neutral) | Ink nav is structural in light; neutral in dark so nav doesn't compete with content |
|
||||
| `--navbar-active-color` | `#FF4B3E` (Coral) | `#FF4B3E` (Coral) | Same — coral stays the active indicator |
|
||||
| `--link-color` | `#FF4B3E` (Coral) | `#FF4B3E` (Coral) | Same — coral links in both modes |
|
||||
| `--link-hover-color` | `#E03828` (Darker coral) | `#E03828` | Same |
|
||||
| `--code-color` | `#FF4B3E` | `#FF7A6F` (Lighter coral) | Softer in dark for readability |
|
||||
| `--secondary-bg` | `#F4F4F4` | `#151B22` | Card backgrounds, dropdowns |
|
||||
| `--card-bg` | `#F4F4F4` (via `--secondary-bg`) | `#151B22` | |
|
||||
| `--border-color` | `#D6D6D6` | `#2b323b` | |
|
||||
|
||||
The `--sky` token is mode-invariant (`#a3cde2` in both). This means
|
||||
`.custom.sky` cards and `--sky`-based surfaces look the same regardless of
|
||||
mode — the surrounding page contrast changes, not the card itself.
|
||||
|
||||
---
|
||||
|
||||
## Typography variables
|
||||
|
||||
Typography is mode-invariant — defined once in the theme files and reinforced
|
||||
by `user.css`.
|
||||
|
||||
| Variable | Value | Notes |
|
||||
|---|---|---|
|
||||
| `--body-font-family` | `'Fredoka', 'Nunito', -apple-system, ...` | Full stack in both theme files + `user.css` |
|
||||
| `--body-font-size` | `1rem` | |
|
||||
| `--body-font-weight` | `400` | Nunito for body text |
|
||||
| `--body-line-height` | `1.5` | |
|
||||
| `--font-monospace` | `SFMono-Regular, Menlo, Monaco, ...` | Standard monospace stack |
|
||||
|
||||
Weight hierarchy is enforced by `user.css`, not the theme files — see
|
||||
[brand-reference.md](./brand-reference.md#typography).
|
||||
|
||||
---
|
||||
|
||||
## Border & radius
|
||||
|
||||
| Variable | Value | Notes |
|
||||
|---|---|---|
|
||||
| `--border-radius` | `0.875rem` | Baseline for all CF components |
|
||||
| `--border-radius-sm` | `0.5rem` | Badges, small controls |
|
||||
| `--border-radius-lg` | `1.25rem` | Hero cards |
|
||||
| `--border-radius-xl` | `1.5rem` | |
|
||||
| `--border-radius-pill` | `50rem` | Fully rounded (pills, FABs) |
|
||||
| `--card-border-radius` | `1rem` | Cards slightly larger than baseline |
|
||||
| `--border-color` | `#D6D6D6` (light) / `#2b323b` (dark) | |
|
||||
|
||||
---
|
||||
|
||||
## Container color map
|
||||
|
||||
MokoOnyx defines several page-region containers. These are the CF color
|
||||
assignments:
|
||||
|
||||
| Container | Light bg | Dark bg | Notes |
|
||||
|---|---|---|---|
|
||||
| Header | `light_skybackground.png` | (image) | Background image, not a flat color |
|
||||
| Below Topbar | `#F4F4F4` (Mascot White) | `#151B22` | Soft neutral strip |
|
||||
| Top A | `none` (transparent) | `none` | Inherits page bg |
|
||||
| Top B | `var(--sky)` = `#a3cde2` | `var(--sky)` | Sky-tinted — triggers contrast overrides |
|
||||
| TOC | `var(--secondary-bg)` | `var(--secondary-bg)` | Sidebar table of contents |
|
||||
| Sidebar | `#F4F4F4` | `#151B22` | 0.75rem radius |
|
||||
| Bottom A | `#7FB7C6` (Sky Secondary) | varies | Sky-tinted — triggers contrast overrides |
|
||||
| Bottom B | `#1E1E1E` (Ink) | `#0E1318` | Dark strip, typically footer area |
|
||||
|
||||
**Contrast implications:** Top B and Bottom A use sky backgrounds, which means
|
||||
links inside them are automatically flipped to ink via the scoped override in
|
||||
`user.css`. See [accessibility.md](./accessibility.md#coral-on-sky-links-fail-aa--fixed).
|
||||
|
||||
---
|
||||
|
||||
## Button variants
|
||||
|
||||
All buttons use ink (`#1E1E1E`) text for AA contrast. The `.btn-dark` variant
|
||||
uses Mascot White text instead.
|
||||
|
||||
### Solid buttons
|
||||
|
||||
| Class | Background | Hover bg | CF token |
|
||||
|---|---|---|---|
|
||||
| `.btn-primary` | `#FF4B3E` (Coral) | `#FF6B60` | Coral Accent |
|
||||
| `.btn-secondary` | `#9CCEDB` (Sky Primary) | `#7FB7C6` | Sky Primary |
|
||||
| `.btn-success` | `#78D694` | `#9CE3B2` | -- |
|
||||
| `.btn-info` | `#9CCEDB` (Sky Primary) | `#7FB7C6` | Sky Primary |
|
||||
| `.btn-warning` | `#F5C518` (Gold) | `#FFD84A` | Gold Eye |
|
||||
| `.btn-danger` | `#ff7a73` (Soft Red) | `#e5615a` | Soft Red |
|
||||
| `.btn-light` | `#F4F4F4` (Mascot White) | `#FFFFFF` | Mascot White |
|
||||
| `.btn-dark` | `#1E1E1E` (Ink) | `#333333` | Ink Outline |
|
||||
|
||||
### Outline buttons
|
||||
|
||||
Outline variants use the brand color as text/border color and fill on hover:
|
||||
|
||||
| Class | Text/border | Hover fill |
|
||||
|---|---|---|
|
||||
| `.btn-outline-primary` | Coral `#FF4B3E` | Coral |
|
||||
| `.btn-outline-secondary` | Sky `#9CCEDB` | Sky |
|
||||
| `.btn-outline-success` | `#78D694` | Green |
|
||||
| `.btn-outline-info` | Sky `#9CCEDB` | Sky |
|
||||
| `.btn-outline-warning` | Gold `#F5C518` | Gold |
|
||||
| `.btn-outline-danger` | `#c0453e` | Soft Red |
|
||||
| `.btn-outline-light` | Mascot White | Mascot White |
|
||||
| `.btn-outline-dark` | `#B8C3CB` | `#B8C3CB` |
|
||||
|
||||
All solid buttons have `--btn-border-color: #1E1E1E` (ink outline) for the
|
||||
sticker/outlined aesthetic. Outline buttons swap to ink border on hover.
|
||||
|
||||
---
|
||||
|
||||
## Hero system
|
||||
|
||||
Two hero variants for banner sections:
|
||||
|
||||
| Variant | Background | Overlay | Text color |
|
||||
|---|---|---|---|
|
||||
| Primary | Sky Primary `#9CCEDB` | 55% sky gradient | Ink `#1E1E1E` |
|
||||
| Secondary | Ink `#1E1E1E` | 78% ink overlay | Mascot White `#F4F4F4` |
|
||||
|
||||
Hero card dimensions: `max-width: 800px`, `padding: 3rem 2rem`,
|
||||
`border-radius: 1.25rem`. Alt card is narrower at `600px`.
|
||||
|
||||
---
|
||||
|
||||
## Block colors
|
||||
|
||||
Used for module position color rotation (top-a, top-b, bottom-a, bottom-b):
|
||||
|
||||
| Block | Background | Text | Typical use |
|
||||
|---|---|---|---|
|
||||
| Block 1 | `var(--secondary-bg)` | `var(--body-color)` | Neutral modules |
|
||||
| Block 2 | Coral `#FF4B3E` | Mascot White | CTA modules |
|
||||
| Block 3 | Gold `#F5C518` | Gold | Highlight modules |
|
||||
| Block 4 | Mascot White `#F4F4F4` | Sky Primary | Light modules |
|
||||
|
||||
Additional block overrides:
|
||||
|
||||
| Variable | Value | Use |
|
||||
|---|---|---|
|
||||
| `--block-highlight-bg` | Gold 18% opacity | Subtle gold wash |
|
||||
| `--block-cta-bg` | Coral solid | Call-to-action blocks |
|
||||
| `--block-alert-bg` | Coral 18% opacity | Alert/notice blocks |
|
||||
|
||||
---
|
||||
|
||||
## Editing guidelines
|
||||
|
||||
1. **Edit brand tokens, not internals.** If you need to change a color, find
|
||||
the brand token it maps to and change that. The 900+ downstream variables
|
||||
inherit automatically.
|
||||
|
||||
2. **Edit in both theme files.** Every color change in `light.custom.css`
|
||||
likely needs a corresponding change in `dark.custom.css`.
|
||||
|
||||
3. **Run a contrast audit** after any color change. See
|
||||
[accessibility.md](./accessibility.md#audit-tools) for tools.
|
||||
|
||||
4. **Bump the file version** in the header comment on every edit.
|
||||
|
||||
5. **Clear Joomla cache** after deploying — see
|
||||
[deployment.md](deployment) for the full workflow.
|
||||
|
||||
---
|
||||
|
||||
## Metadata
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Document Type | reference |
|
||||
| Domain | CSS Variables |
|
||||
| Applies To | All CSS changes in light.custom.css, dark.custom.css, user.css |
|
||||
| Jurisdiction | Moko Consulting |
|
||||
| Owner | Moko Consulting |
|
||||
| Repo | mokoconsulting-tech/client-clarksvillefurs |
|
||||
| Path | ./docs/css-variables.md |
|
||||
| Version | 00.01.00 |
|
||||
| Status | Active |
|
||||
| Last Reviewed | 2026-04-22 |
|
||||
| Reviewed By | Claude |
|
||||
|
||||
## Revision History
|
||||
|
||||
| Date | Author | Change | Notes |
|
||||
|---|---|---|---|
|
||||
| 2026-04-22 | Claude | Initial creation | Replaces deleted CSS_VARIABLES.md with focused reference |
|
||||
|
||||
---
|
||||
|
||||
*Repo: [client-clarksvillefurs](https://git.mokoconsulting.tech/ClarksvilleFurs/client-waas-clarksvillefurs) · [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
|
||||
|
||||
| Revision | Date | Author | Description |
|
||||
|---|---|---|---|
|
||||
| 1.0 | 2026-05-09 | Moko Consulting | Initial version |
|
||||
@@ -0,0 +1,180 @@
|
||||
← [Home](Home)
|
||||
|
||||
# Deployment
|
||||
|
||||
## Environments
|
||||
|
||||
| Environment | URL | Purpose |
|
||||
|---|---|---|
|
||||
| Development | `clarksvillefurs.dev.mokoconsulting.tech` | Moko internal staging — first stop for all changes |
|
||||
| Production | `clarksvillefurs.com` | Live site |
|
||||
|
||||
Development mirrors production's Joomla version, template, extensions, and
|
||||
data. Testing on dev first is required for every theme change.
|
||||
|
||||
## Theme package deliverables
|
||||
|
||||
A theme-only deploy consists of three CSS files and, if changed, the font file:
|
||||
|
||||
```
|
||||
deploy/
|
||||
├── images/
|
||||
│ └── branding/
|
||||
│ ├── logo_full_wide.png
|
||||
│ ├── mascot.png
|
||||
│ └── web_logo_full_wide.png
|
||||
└── media/
|
||||
└── templates/
|
||||
└── site/
|
||||
└── mokoonyx/
|
||||
├── css/
|
||||
│ ├── theme/
|
||||
│ │ ├── light.custom.css
|
||||
│ │ └── dark.custom.css
|
||||
│ └── user.css
|
||||
└── fonts/
|
||||
└── Fredoka-Variable.ttf
|
||||
```
|
||||
|
||||
## SFTP deployment (manual, current process)
|
||||
|
||||
Copy SFTP credentials from `docs/templates/sftp-config.json.template` into a
|
||||
local, gitignored `sftp-config.json`. Connect via any SFTP client (Transmit,
|
||||
FileZilla, Cyberduck, rsync over ssh).
|
||||
|
||||
**Upload paths** (relative to Joomla web root):
|
||||
|
||||
- `/media/templates/site/mokoonyx/css/theme/light.custom.css`
|
||||
- `/media/templates/site/mokoonyx/css/theme/dark.custom.css`
|
||||
- `/media/templates/site/mokoonyx/css/user.css`
|
||||
- `/media/templates/site/mokoonyx/fonts/Fredoka-Variable.ttf` *(only if font file changed)*
|
||||
- `/images/branding/*.png` *(only if images changed)*
|
||||
|
||||
**Note:** The template directory on the server may still be
|
||||
`/media/templates/site/mokocassiopeia/` if the MokoCassiopeia → MokoOnyx rename
|
||||
has not yet been completed on that environment. Check the actual directory
|
||||
name with `ls` on the server; the *file contents* reference `mokoonyx` in
|
||||
their headers regardless of the current folder name, which is correct
|
||||
forward-looking metadata.
|
||||
|
||||
## Cache busting after deploy
|
||||
|
||||
Joomla caches heavily. After uploading CSS, always:
|
||||
|
||||
1. Joomla admin → **System → Maintenance → Clear Cache** → check all boxes → Clear Cache
|
||||
2. Joomla admin → **System → Maintenance → Purge Expired Cache**
|
||||
3. Verify cache-bust query string on the CSS URL changed (e.g. `?475b76` → new hash)
|
||||
|
||||
If the query string didn't change, the template file mod-times weren't
|
||||
picked up. Touching any file in the template directory (e.g. via SFTP `touch`
|
||||
or re-saving the template in admin) forces a regeneration.
|
||||
|
||||
Hard-refresh the browser (Ctrl+Shift+R / Cmd+Shift+R) to bypass local cache.
|
||||
|
||||
## Verification checklist
|
||||
|
||||
On the dev environment, after every deploy:
|
||||
|
||||
1. Home page loads without console errors
|
||||
2. Light mode renders as expected (sky header PNG, ink nav, coral CTAs)
|
||||
3. Dark mode toggle works — CSS vars all resolve, no broken fallbacks
|
||||
4. Hero "Your place." renders as coral (not washed pink) in light mode
|
||||
5. `.custom.{sky,red,yellow,green}` cards render with correct tints and readable text
|
||||
6. FAQ page blue callout at top — links are ink, not coral
|
||||
7. Footer / `.container-bottom-a` — sky-secondary bg, ink text, link overrides working
|
||||
8. No FOUC on Fredoka font load (font-display: swap handles this)
|
||||
9. Contrast spot-checks on any new text/bg pair using browser DevTools
|
||||
|
||||
If any check fails, roll back (reupload previous version) before promoting
|
||||
to production.
|
||||
|
||||
## Automated dev → live sync (daily cron)
|
||||
|
||||
Dev and live share the same database, so only the filesystem needs syncing.
|
||||
A cron job on the dev server runs `rsync` daily at **3:00 AM server time** to
|
||||
push filesystem changes to live.
|
||||
|
||||
### How it works
|
||||
|
||||
| Component | Location (dev server) |
|
||||
|---|---|
|
||||
| Script | `/home/clarksvillefurs/scripts/sync-dev-to-live.sh` |
|
||||
| SSH key | `~/.ssh/id_sync_to_live` (ed25519, authorized on live) |
|
||||
| Cron entry | `0 3 * * * /home/clarksvillefurs/scripts/sync-dev-to-live.sh` |
|
||||
| Log file | `/home/clarksvillefurs/scripts/logs/sync-dev-to-live.log` |
|
||||
|
||||
The script uses `rsync -avz --delete` with excludes for environment-specific
|
||||
files (`configuration.php`, `.htaccess`, `cache/`, `tmp/`, `logs/`,
|
||||
dev-only files, DreamHost system files). It includes a PID-based lock file
|
||||
to prevent overlapping runs.
|
||||
|
||||
### Manual run
|
||||
|
||||
SSH into the dev server and execute directly:
|
||||
|
||||
```bash
|
||||
/home/clarksvillefurs/scripts/sync-dev-to-live.sh
|
||||
cat /home/clarksvillefurs/scripts/logs/sync-dev-to-live.log
|
||||
```
|
||||
|
||||
### Updating the script
|
||||
|
||||
The canonical copy lives in the repo at `scripts/sync-dev-to-live.sh`.
|
||||
After editing, SCP it to the dev server:
|
||||
|
||||
```bash
|
||||
scp scripts/sync-dev-to-live.sh clarksvillefurs@dev.mokoconsulting.tech:/home/clarksvillefurs/scripts/
|
||||
ssh clarksvillefurs@dev.mokoconsulting.tech "sed -i 's/\r$//' /home/clarksvillefurs/scripts/sync-dev-to-live.sh"
|
||||
```
|
||||
|
||||
The `sed` command strips Windows line endings (required for bash execution).
|
||||
|
||||
## Production promotion (manual)
|
||||
|
||||
Only after full dev verification:
|
||||
|
||||
1. Upload the same files to production SFTP (or wait for the next automated sync at 3 AM)
|
||||
2. Run the same cache-clear sequence in production Joomla admin
|
||||
3. Verify the same checklist in an incognito window against the production URL
|
||||
4. Tag the git commit with the release version (`git tag v02.06.00 && git push --tags`)
|
||||
|
||||
## Rollback
|
||||
|
||||
Keep the previous working version of each CSS file in `/deploy/archive/vXX.YY.ZZ/`
|
||||
before uploading. If production starts throwing errors or visibly breaks:
|
||||
|
||||
1. SFTP upload the previous version back into place
|
||||
2. Clear caches
|
||||
3. Verify the rollback worked
|
||||
4. Root-cause the failure on dev before re-attempting
|
||||
|
||||
## Metadata
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Document Type | guide |
|
||||
| Domain | DevOps |
|
||||
| Applies To | All theme and template deployments |
|
||||
| Jurisdiction | Moko Consulting |
|
||||
| Owner | Moko Consulting |
|
||||
| Repo | mokoconsulting-tech/client-clarksvillefurs |
|
||||
| Path | ./docs/deployment.md |
|
||||
| Version | 00.02.00 |
|
||||
| Status | Active |
|
||||
| Last Reviewed | 2026-04-26 |
|
||||
| Reviewed By | Claude |
|
||||
|
||||
## Revision History
|
||||
|
||||
| Date | Author | Change | Notes |
|
||||
|---|---|---|---|
|
||||
| 2026-04-26 | Claude | Added automated dev→live sync section | Cron rsync workflow, script reference, manual run instructions |
|
||||
| 2026-04-21 | Claude | Initial creation | SFTP workflow, cache-busting, rollback |
|
||||
|
||||
---
|
||||
|
||||
*Repo: [client-clarksvillefurs](https://git.mokoconsulting.tech/ClarksvilleFurs/client-waas-clarksvillefurs) · [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
|
||||
|
||||
| Revision | Date | Author | Description |
|
||||
|---|---|---|---|
|
||||
| 1.0 | 2026-05-09 | Moko Consulting | Initial version |
|
||||
@@ -0,0 +1,248 @@
|
||||
← [Home](Home)
|
||||
|
||||
# Migration Plan — Events and News
|
||||
|
||||
End-to-end plan for enabling Clarksville Furs managers to author event
|
||||
listings and news posts that automatically cross-post to Discord,
|
||||
Telegram, and Facebook.
|
||||
|
||||
## Goal
|
||||
|
||||
Give the **Event Authors** Joomla group a self-service workflow:
|
||||
create an article in the Events or News category, attach an image,
|
||||
publish — and have the post appear on all CF social channels within
|
||||
minutes, with no webmaster intervention.
|
||||
|
||||
## Stakeholders
|
||||
|
||||
| Role | Responsibility |
|
||||
|---|---|
|
||||
| Moko Consulting | Technical implementation, plugin configuration, documentation, training |
|
||||
| Webmaster | Account provisioning, 2FA setup, day-to-day oversight |
|
||||
| Event Authors | Article creation and publishing |
|
||||
|
||||
---
|
||||
|
||||
## Phase 1 — Infrastructure
|
||||
|
||||
Set up the Joomla categories, user group, and plugin wiring.
|
||||
|
||||
### 1.1 Create content categories
|
||||
|
||||
- [ ] **Events** category under `com_content` (published, public access)
|
||||
- [ ] **News** category under `com_content` (published, public access)
|
||||
— News (ID: 16) already exists; verify description and alias
|
||||
|
||||
### 1.2 Create the Event Authors user group
|
||||
|
||||
- [ ] Create Joomla user group **Event Authors** (child of Registered)
|
||||
- [ ] Grant article-create and article-edit-own permissions on the
|
||||
Events and News categories
|
||||
- [ ] Deny publish permission — articles default to Unpublished until
|
||||
a moderator (or the webmaster) approves, unless the author also
|
||||
holds a higher group
|
||||
- [ ] Assign initial members
|
||||
|
||||
### 1.3 Configure MokoDiscordHook
|
||||
|
||||
MokoDiscordHook fires `onContentAfterSave` and sends a Discord embed.
|
||||
|
||||
- [ ] Install / verify MokoDiscordHook plugin is enabled
|
||||
- [ ] Set the target Discord webhook URL for #server-announcements
|
||||
- [ ] Configure category trigger: Events category ID, News category ID
|
||||
- [ ] Embed fields mapped:
|
||||
- **Title** ← article title
|
||||
- **Description** ← article intro text
|
||||
- **Image** ← intro image URL
|
||||
- **Link** ← full article URL on clarksvillefurs.com
|
||||
|
||||
### 1.4 Configure Perfect Publisher
|
||||
|
||||
Perfect Publisher posts to Facebook and Telegram via the Rule Engine.
|
||||
|
||||
- [ ] Install / verify Perfect Publisher is enabled
|
||||
- [ ] Connect Facebook group (clarksvillefurs) — verify Page token is valid
|
||||
- [ ] Connect Telegram channel (@ClarksvilleFurs) — verify
|
||||
bot token and channel membership
|
||||
- [ ] Create Rule Engine rules:
|
||||
- **Rule: Events → FB + Telegram** — category match on Events,
|
||||
action = publish to FB Page + Telegram channel
|
||||
- **Rule: News → FB + Telegram** — category match on News,
|
||||
action = publish to FB Page + Telegram channel
|
||||
- [ ] Post content mapped:
|
||||
- **Facebook**: intro text as post body, article URL as link
|
||||
(link card pulls `og:title`, `og:image`, `og:description`)
|
||||
- **Telegram**: intro text + article URL as message body
|
||||
(link preview pulls from Open Graph meta tags)
|
||||
|
||||
### 1.5 Verify Open Graph tags
|
||||
|
||||
- [ ] Confirm Joomla outputs `og:title`, `og:description`, `og:image`
|
||||
for articles (MokoOnyx or a plugin handles this)
|
||||
- [ ] Test with Facebook Sharing Debugger and Telegram @webpagebot
|
||||
|
||||
---
|
||||
|
||||
## Phase 2 — Dry run
|
||||
|
||||
Validate the full pipeline end-to-end before handing off to authors.
|
||||
|
||||
### 2.1 Test article pipeline
|
||||
|
||||
- [ ] Create a test article in the Events category with:
|
||||
- Title following style guide format: `Test Event — Downtown Clarksville`
|
||||
- 1–2 sentence intro text
|
||||
- Intro image (1200x630 JPG, with alt text)
|
||||
- Publish date set to now
|
||||
- Status = Published
|
||||
- [ ] Verify article appears on the website Events listing
|
||||
- [ ] Verify Discord embed arrives in #server-announcements
|
||||
- Title, description, image, link all correct
|
||||
- [ ] Verify Telegram message arrives in @ClarksvilleFurs
|
||||
- Message text, link preview card all correct
|
||||
- [ ] Verify Facebook post appears on clarksvillefurs group
|
||||
- Post text, link card image and title all correct
|
||||
- [ ] Repeat for a News category article
|
||||
- [ ] Delete or unpublish test articles after verification
|
||||
|
||||
### 2.2 Test author permissions
|
||||
|
||||
- [ ] Log in as an Event Authors member (not a super admin)
|
||||
- [ ] Confirm the user can create articles in Events and News
|
||||
- [ ] Confirm the user cannot edit other users' articles
|
||||
- [ ] Confirm the user cannot access admin areas beyond Content
|
||||
|
||||
### 2.3 Test edge cases
|
||||
|
||||
- [ ] Article with no intro image — cross-posts should still work
|
||||
(no image in embed, but no error)
|
||||
- [ ] Article with a very long title (70+ characters) — check
|
||||
truncation on Discord embed
|
||||
- [ ] Article saved as Unpublished — cross-posts should NOT fire
|
||||
- [ ] Article edited after publishing — Discord embed does NOT update
|
||||
(expected; document this for authors)
|
||||
|
||||
---
|
||||
|
||||
## Phase 3 — Documentation and training
|
||||
|
||||
Author the manager-facing documentation and record the walkthrough.
|
||||
|
||||
### 3.1 Authoring documentation
|
||||
|
||||
All files live under `docs/authoring/`. See the
|
||||
[Authoring Documentation Index](authoring-README) for the full
|
||||
list and reading order.
|
||||
|
||||
| Document | Purpose |
|
||||
|---|---|
|
||||
| [README](authoring-README) | Index, audience, reading order |
|
||||
| [Quick Reference](authoring-quick-reference) | One-page cheat sheet — log in through publish |
|
||||
| [Style Guide](authoring-style-guide) | Voice, tone, title format, image specs, don'ts |
|
||||
| [Cross-Post Preview](authoring-cross-post-preview) | Field-to-surface mapping with worked example |
|
||||
| [Screencast Script](authoring-screencast-script) | 8-scene spoken script for the walkthrough recording |
|
||||
|
||||
### 3.2 Dry-run checklist for docs
|
||||
|
||||
Each document must have:
|
||||
|
||||
- [ ] Moko HTML-comment file header (Copyright, SPDX, FILE INFORMATION)
|
||||
- [ ] DEFGROUP: `ClarksvilleFurs.Documentation`
|
||||
- [ ] INGROUP: `ClarksvilleFurs`
|
||||
- [ ] VERSION starting at `00.01.00`
|
||||
- [ ] Metadata table and Revision History table at the bottom
|
||||
- [ ] Pure Markdown body — no HTML except the file header
|
||||
- [ ] Placeholder tokens for values TBD:
|
||||
`[LAUNCH DATE]` (the only remaining placeholder)
|
||||
|
||||
### 3.3 Record walkthrough
|
||||
|
||||
- [ ] Record the screencast using the
|
||||
[Screencast Script](authoring-screencast-script)
|
||||
- [ ] Presenter: Moko Consulting
|
||||
- [ ] Runtime target: 5–8 minutes
|
||||
- [ ] Upload to a location accessible to Event Authors (Google Drive,
|
||||
YouTube unlisted, or embedded on the site)
|
||||
- [ ] Link from the authoring README
|
||||
|
||||
### 3.4 Onboard first authors
|
||||
|
||||
- [ ] Schedule a live walkthrough session with initial Event Authors
|
||||
- [ ] Share the authoring docs link
|
||||
- [ ] Have each author create a test article and verify cross-posts
|
||||
- [ ] Collect feedback and update docs as needed
|
||||
|
||||
---
|
||||
|
||||
## Phase 4 — Launch
|
||||
|
||||
Go live and hand off to the team.
|
||||
|
||||
### 4.1 Fill in placeholders
|
||||
|
||||
- [ ] Replace `[LAUNCH DATE]` across all authoring docs
|
||||
- [x] ~~Replace `[CF Discord channel name]`~~ → #server-announcements
|
||||
- [x] ~~Replace `[FB Page ID]`~~ → clarksvillefurs (Facebook group)
|
||||
- [x] ~~Replace `[Telegram channel handle]`~~ → @ClarksvilleFurs
|
||||
- [x] ~~Replace `[Webmaster email]`~~ → Contact Us page (clarksvillefurs.com/contact-us)
|
||||
|
||||
### 4.2 Publish
|
||||
|
||||
- [ ] Merge authoring docs to main branch
|
||||
- [ ] Enable auto-publish permissions for Event Authors (if dry run
|
||||
proved they don't need moderator approval)
|
||||
- [ ] Announce in Discord and Telegram that the Events page is live
|
||||
- [ ] Monitor first 5 real posts for cross-post issues
|
||||
|
||||
### 4.3 Post-launch
|
||||
|
||||
- [ ] Review cross-post analytics after 2 weeks
|
||||
- [ ] Update docs based on author feedback
|
||||
- [ ] Consider adding a menu item for Events on the main navigation
|
||||
(currently hidden: `menu_show=0` on item 457)
|
||||
|
||||
---
|
||||
|
||||
## Constraints
|
||||
|
||||
- **MokoDiscordHook**: embed with title, intro text, image, link.
|
||||
Fires `onContentAfterSave` for configured categories. Does NOT
|
||||
update embeds if the article is edited after initial save.
|
||||
- **Perfect Publisher**: native FB Page post + Telegram channel post,
|
||||
triggered by Rule Engine on category match. Link previews depend
|
||||
on Open Graph meta tags being present and correct.
|
||||
- **No invented features**: this plan only uses capabilities that
|
||||
exist in the installed plugins. If a feature isn't listed here,
|
||||
it doesn't exist.
|
||||
|
||||
---
|
||||
|
||||
## Metadata
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Document Type | plan |
|
||||
| Domain | Content Authoring |
|
||||
| Applies To | Events and News authoring workflow |
|
||||
| Jurisdiction | Moko Consulting |
|
||||
| Owner | Moko Consulting |
|
||||
| Repo | mokoconsulting-tech/client-clarksvillefurs |
|
||||
| Path | ./docs/migration-plan-events.md |
|
||||
| Version | 00.01.00 |
|
||||
| Status | Draft |
|
||||
| Last Reviewed | 2026-04-26 |
|
||||
| Reviewed By | Claude |
|
||||
|
||||
## Revision History
|
||||
|
||||
| Date | Author | Change | Notes |
|
||||
|---|---|---|---|
|
||||
| 2026-04-26 | Claude | Initial creation | 4-phase plan: infrastructure, dry run, documentation, launch |
|
||||
|
||||
---
|
||||
|
||||
*Repo: [client-clarksvillefurs](https://git.mokoconsulting.tech/ClarksvilleFurs/client-waas-clarksvillefurs) · [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
|
||||
|
||||
| Revision | Date | Author | Description |
|
||||
|---|---|---|---|
|
||||
| 1.0 | 2026-05-09 | Moko Consulting | Initial version |
|
||||
@@ -0,0 +1,151 @@
|
||||
← [Home](Home)
|
||||
|
||||
# Theme Architecture
|
||||
|
||||
The CF theme rides on top of MokoOnyx (Joomla 5 template). MokoOnyx provides
|
||||
everything structural (layout, scaffolding, responsive grid, component behavior).
|
||||
CF's theme layer only changes colors, fonts, and introduces a small library of
|
||||
utility classes.
|
||||
|
||||
## File roster
|
||||
|
||||
Three CSS files make up the CF theme layer. They live under the MokoOnyx
|
||||
template directory and survive template updates because MokoOnyx's CSS cascade
|
||||
is ordered to read the `.custom` files after its own `.standard` files.
|
||||
|
||||
```
|
||||
/media/templates/site/mokoonyx/
|
||||
├── css/
|
||||
│ ├── theme/
|
||||
│ │ ├── light.custom.css ← light-mode palette
|
||||
│ │ └── dark.custom.css ← dark-mode palette
|
||||
│ ├── user.css ← persistent overrides (fonts, utilities)
|
||||
│ └── theme/
|
||||
│ ├── light.standard.css ← template default, do NOT edit
|
||||
│ └── dark.standard.css ← template default, do NOT edit
|
||||
└── fonts/
|
||||
└── Fredoka-Variable.ttf ← brand font
|
||||
```
|
||||
|
||||
## Load order
|
||||
|
||||
MokoOnyx loads stylesheets in this order on every page. Later files override
|
||||
earlier files per CSS cascade rules:
|
||||
|
||||
1. `template.base.css` — Bootstrap 5.3 + MokoOnyx layout primitives
|
||||
2. `fonts/osaka.css` — template's default heading font (overridden later)
|
||||
3. `theme/light.standard.css` — Bootstrap palette + MokoOnyx variable defaults
|
||||
4. `theme/dark.standard.css` — same, dark-mode scoped under `:root[data-bs-theme='dark']`
|
||||
5. `theme/light.custom.css` — **CF palette** (this is ours)
|
||||
6. `theme/dark.custom.css` — **CF dark palette** (this is ours)
|
||||
7. `user.css` — **persistent overrides** (this is ours)
|
||||
8. `a11y-high-contrast.css` — accessibility toggle
|
||||
9. `bootstrap.css` — Bootstrap component styles (read vars set above)
|
||||
|
||||
The CF files sit between the template's defaults and Bootstrap's final component
|
||||
pass, so our variable values flow into every Bootstrap component that reads them.
|
||||
|
||||
## What each CF file is allowed to change
|
||||
|
||||
### `light.custom.css` and `dark.custom.css`
|
||||
|
||||
**Purpose:** Full color palette for each theme mode. These files are a
|
||||
comprehensive redeclaration of every MokoOnyx / Bootstrap 5 custom property in
|
||||
the template's scaffold — 684 variables per file at the time of writing.
|
||||
|
||||
**Scope of edits:**
|
||||
|
||||
- All `--color-*` brand tokens
|
||||
- All Bootstrap contextual colors (`--primary`, `--secondary`, `--success`, `--info`, `--warning`, `--danger`, `--light`, `--dark`) and their `-rgb`, `-text-emphasis`, `-bg-subtle`, `-border-subtle` variants
|
||||
- Typography tokens that should vary by mode (none currently — font stack is mode-invariant and lives in `user.css`)
|
||||
- All container backgrounds (`--container-top-a-*`, `--container-top-b-*`, `--container-bottom-a-*`, `--container-bottom-b-*`, `--container-sidebar-*`, `--container-toc-*`, `--container-below-topbar-*`)
|
||||
- Hero variant styling (`--hero-primary-*`, `--hero-secondary-*`, `--hero-card-*`, `--hero-alt-card-*`)
|
||||
- Block color rotation (`--block-color-1` through `-4`, plus overrides)
|
||||
- All Bootstrap component defaults (accordion, alert, badge, breadcrumb, card, dropdown, list-group, modal, nav-tabs, nav-pills, offcanvas, pagination, popover, progress, spinner, table, toast, tooltip)
|
||||
- Button variants (`.btn-primary` through `.btn-dark`, `.btn-outline-*`, `.btn-link`) — live at stylesheet root, not nested, following the MokoOnyx scaffold convention
|
||||
|
||||
**Not in scope:** typography, layout, spacing outside Bootstrap's defaults.
|
||||
Those belong in `user.css`.
|
||||
|
||||
### `user.css`
|
||||
|
||||
**Purpose:** Persistent non-color overrides. Edits here survive template updates
|
||||
and color changes without touching the palette files.
|
||||
|
||||
**Scope of edits:**
|
||||
|
||||
- `@font-face` loading for Fredoka
|
||||
- `@import` for Nunito from Google Fonts
|
||||
- Global font-stack override via `:root { --body-font-family }`
|
||||
- Typography weight hierarchy (per brand guide)
|
||||
- `.site-title` override to beat Osaka
|
||||
- Rounded-corner enforcement on `.form-control`, `.form-select`, `.alert`, `.badge`, `.input-group-text`, `.btn`
|
||||
- `.btn` base sizing (`padding: 0.65rem 1.5rem`) and `.btn-lg` variant
|
||||
- Opt-in utility classes: `.cf-sticker`, `.cf-brand-callout`, `.cf-brand-accent`
|
||||
- Tinted card classes: `.custom.sky`, `.custom.red`, `.custom.yellow`, `.custom.green`
|
||||
- Blue-background contrast override (scoped ink-link treatment inside sky surfaces)
|
||||
- Decorative `.text-danger` → coral compatibility rule for headings
|
||||
- `:focus-visible` accessibility outline
|
||||
- Link underline offset for body text
|
||||
|
||||
## Versioning
|
||||
|
||||
All three files use zero-padded semver in their `FILE INFORMATION` header
|
||||
comment. Version is displayed prominently near the top of each file and must be
|
||||
bumped on every edit.
|
||||
|
||||
Current versions (as of last update):
|
||||
|
||||
| File | Version |
|
||||
|---|---|
|
||||
| `light.custom.css` | 02.04.00 |
|
||||
| `dark.custom.css` | 02.02.00 |
|
||||
| `user.css` | 01.05.00 |
|
||||
|
||||
## Cache busting
|
||||
|
||||
Joomla cache-busts CSS via a query string appended to every asset URL (e.g.
|
||||
`?475b76`). The cache key is regenerated when any template file changes on
|
||||
disk. A deploy should always be followed by a template rebuild (Joomla admin →
|
||||
System → Maintenance → Clear Cache) to make browsers pick up the new version.
|
||||
|
||||
## Safe-edit checklist
|
||||
|
||||
Before committing any CSS change:
|
||||
|
||||
1. Brace balance — count `{` and `}` occurrences, must match
|
||||
2. File version bumped in header comment
|
||||
3. No direct hex usage where a `var(--*)` exists — always prefer the token
|
||||
4. Contrast audit for any color change touching text/background pairs
|
||||
5. Both light and dark mode tested (toggle in the site header)
|
||||
6. File header comment still present and valid
|
||||
|
||||
## Metadata
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Document Type | reference |
|
||||
| Domain | Theme Architecture |
|
||||
| Applies To | All CSS changes in this repo |
|
||||
| Jurisdiction | Moko Consulting |
|
||||
| Owner | Moko Consulting |
|
||||
| Repo | mokoconsulting-tech/client-clarksvillefurs |
|
||||
| Path | ./docs/theme-architecture.md |
|
||||
| Version | 00.01.00 |
|
||||
| Status | Active |
|
||||
| Last Reviewed | 2026-04-21 |
|
||||
| Reviewed By | Claude |
|
||||
|
||||
## Revision History
|
||||
|
||||
| Date | Author | Change | Notes |
|
||||
|---|---|---|---|
|
||||
| 2026-04-21 | Claude | Initial creation | Based on v02.06.00 theme package |
|
||||
|
||||
---
|
||||
|
||||
*Repo: [client-clarksvillefurs](https://git.mokoconsulting.tech/ClarksvilleFurs/client-waas-clarksvillefurs) · [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
|
||||
|
||||
| Revision | Date | Author | Description |
|
||||
|---|---|---|---|
|
||||
| 1.0 | 2026-05-09 | Moko Consulting | Initial version |
|
||||
Reference in New Issue
Block a user