- CLAUDE.md: expanded with critical rules, hook syntax, DB conventions, web-base endpoint - docs/modular-system.md: modules, general sections, global vars, multiv2 - docs/builder-fields.md: all field types, c-if/c-for/c-class, c-form, built-in components - docs/twig-filters.md: get, hook, module, queryDB, imagec, translate, raw, etc. - docs/hooks-and-api.md: PHP hooks, CmsApi CRUD, table schemas, field formats - docs/css-js-conventions.md: Tailwind, BEM, CSS vars, Vue 3 integration, CmsApi JS Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2.4 KiB
2.4 KiB
CSS & JavaScript Conventions
CSS
Tailwind First
Use Tailwind CSS as the primary styling method. Only use custom CSS when Tailwind is insufficient.
<!-- Good: Tailwind classes -->
<div class="flex items-center gap-4 p-6 bg-white rounded-lg shadow-md">
<h2 class="text-2xl font-bold text-gray-900">Title</h2>
</div>
<!-- Custom CSS only when needed (animations, complex selectors, etc.) -->
BEM for Custom CSS
When custom CSS is needed, scope everything under a root class using BEM naming:
/* Root class in kebab-case */
.hero-section { }
.hero-section__title { }
.hero-section__image { }
.hero-section--dark { }
Never use global classes without a module prefix.
CSS Variables
Acai provides theme variables:
var(--main-color) /* Primary brand color */
var(--main-color-light) /* Lighter variant */
var(--main-color-dark) /* Darker variant */
Utility Classes (Built-in)
| Class | Description |
|---|---|
transition3s |
0.3s smooth transition |
click-a-child |
Makes parent clickable via child <a> tag |
line-clamp2 / line-clamp3 / line-clamp5 |
Text truncation with ellipsis |
filter-white |
CSS filter to make images/icons white |
lazyload |
Lazy loading (use with data-src) |
JavaScript
Module Scripts (script.js)
Keep JavaScript scoped to the module. Use section_id for targeting:
// Scope to this module instance
const section = document.getElementById('{{ section_id }}');
if (section) {
const buttons = section.querySelectorAll('.btn');
// ...
}
CmsApi (Client-Side)
// Call a hook
CmsApi.hook('/hooks/module_id/', { action: 'getData', id: 123 }, function(response) {
console.log(response);
});
Vue 3 Integration
For complex interactivity, use Vue 3 via CDN with Composition API:
<div id="app-{{ section_id }}">
<p>${ message }</p>
<button @click="increment">${ count }</button>
</div>
<script>
const { createApp, ref } = Vue;
createApp({
delimiters: ['${', '}'], // Avoid conflict with Twig {{ }}
setup() {
const message = ref('Hello');
const count = ref(0);
const increment = () => count.value++;
return { message, count, increment };
}
}).mount('#app-{{ section_id }}');
</script>
Important: Use '${' and '}' as Vue delimiters to avoid conflicts with Twig's {{ }} syntax.