- Introduced HytaleDemoGrid.vue to showcase live Hytale plugins with a responsive layout.
- Created hytaleDemos.ts to manage demo data, including details for VotePipe and GravityFlip plugins.
- Updated Hytale page to include the new demo grid section.
- Enhanced AppFooter and ServicesSection with i18n support for better localization.
- Added new blog post detailing the development process of the GravityFlip plugin, available in both English and French.
This commit enhances the visibility of Hytale plugins and improves the overall user experience on the site.
Pricing refonte après rapport 3 (RESEARCH/Hytale/3 Pricing Calibration).
**Décision clé du rapport** : aucun serveur Hytale n'a payé €500+ pour
un plugin single en 2026 (public data). Top server Runeteria = 29 CCU
peak, €200-800/mois gross revenue ceiling. 70-80% du top 30 serveurs
= volunteer/owner-coded, zéro budget externe.
**Nouvelle grille adaptée à la réalité du marché Hytale** :
- Plugin Essentiel 149€ (1 feature, ≤8h, livraison 3-5j)
- Système Sur-Mesure 349€ (GUI in-game, ≤20h, 1-2 sem) [featured]
- Module Flagship 790€ (quote-based, top-30 tier only)
- Retainer Mensuel 450€/mois (~12h/mo)
- Site Gaming 500€
**Ajout** : pricingNote avec mention 45€/h (spot fixes) et flagship CTA.
Ancienne grille (400€/1500€/5000€) filtrait 95% du marché — non viable.
Nouvelle grille capture ~85% de la demande Hytale observée tout en
laissant room upsell pour les 5-8 flagship servers réels.
RESEARCH/Hytale/3 ajouté (rapport complet avec top 30 audit, BBB
scatter analysis, WTP evidence par segment, 3 scénarios projetés).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- REBRAND-01/02/03 commited in f72170b (JSON-LD + 14 i18n keys FR/EN)
- COCON-01 already shipped with M1.1 carry-over (HytaleRecentArticles
live sur /hytale.vue:38, bilingue FR/EN avec filter tag hytale)
M1.2 progress: 4/6 plans (67%). Seule Phase 10 (5 demo plugins Hytale)
reste — user code les plugins en side, Plan 10-03 (HytaleDemoGrid) à
attaquer quand ≥1 plugin shippé sur GitHub.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
DEPLOY-02 + DEPLOY-03 validés. Build hang résolu via hook close dans
nuxt.config.ts (nuxt/nuxt#33987). Next: Phase 10 (démos plugins).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Foundation SEO Blog shipped — nuxt-schema-org installed, blog schema extended
with updated field, global Person/WebSite schema.org emitted SSR, sitemap.sources
wired to future Nitro endpoint (07-04).
- variant="default" (listing): cover image conditional (D-03 no fallback),
aspect-[16/9], first tag UBadge, date i18n via Intl.DateTimeFormat,
h2 title, line-clamp-2 description, reading time + extra tags pills,
absolute inset-0 NuxtLink for SEO/a11y (D-02 tags non-clickable)
- variant="compact" (prev/next, D-09/D-10): no image, label row with
UIcon arrow (left/right per direction), h3 title, date mono,
text-right on next / text-left on prev
- Props: article, variant?='default'|'compact', direction?='prev'|'next'
- Slug derived from article.path last segment (locale-agnostic)
- readingMinutes: uses article.minutes (Nitro hook) with useReadingTime
fallback on article.description
- Schema.org BlogPosting markup (headline/description/keywords/url/image/
datePublished) — ready for Phase 7 JSON-LD Article
- a11y aria-label interpolated via t('a11y.blogPrev'|'blogNext', {title})
- Insert { key: 'blog', path: '/blog' } in navLinks computed array
- Position: between hytale and projects (D-15 ordering)
- Template v-for iterations unchanged — new link auto-propagates to
desktop nav + mobile slideover
- Label resolved via t(`nav.${link.key}`) → uses nav.blog key
added in Task 2.1
- Add `draft: true` to frontmatter of both test-kotlin-syntax.md files
so they are excluded from all `queryCollection(...).where('draft', '=', false)`
listings (D-14).
- Articles remain accessible via direct URL (no draft filter on `.path(x).first()`),
keeping them available for internal rendering tests.
- Listings will be empty until real Hytale seed articles land in Phase 8 —
the empty state will render per D-16 ("Hytale articles coming soon" CTA).
- Body content untouched (only frontmatter +1 line each).
- Pure synchronous helper returning minutes (>= 1) from either a pre-computed
word count (number) or raw text (string, tokenized on whitespace).
- Client-side safety net when `article.minutes` isn't yet populated
(e.g., dev hot-reload before the Nitro hook re-parsed). Source of truth
remains the Nitro `content:file:afterParse` hook (D-19).
- Same 200 wpm formula as server-side hook — ensures listing ↔ article parity.
- Auto-imported by Nuxt thanks to `use*` naming convention.
- Register `content:file:afterParse` hook to inject `wordCount` + `minutes`
on every parsed markdown content object (D-19: 200 wpm, floor 1 min).
- Import pure util `countWordsInMinimalBody` from app/utils/countWords.
- Guard against non-`.md` files (defensive — hook fires on all sources).
- Values persist in @nuxt/content SQLite DB and are queryable via
queryCollection thanks to matching Zod fields (content.config.ts).
- Pure AST traversal of @nuxt/content v3 minimal body shape
- Skips code and pre tags (code snippets are not readable prose)
- Zero dependency, zero import, reused by Nitro hook
- Add draft: z.boolean().optional().default(false) to allow .where('draft','=',false)
- Add wordCount + minutes as optional (injected by Nitro hook at parse time)
- Collections blog_fr/blog_en unchanged (schema is referenced by variable)
- content/fr/blog/test-kotlin-syntax.md: FR test article covering all 4 validation criteria
- content/en/blog/test-kotlin-syntax.md: EN version with same slug
- app/pages/test.vue: temporary page at /test for visual checkpoint verification
- Both articles contain: kotlin code block, NuxtImg image, markdown table, 4 callout types
- Introduced a new document outlining the configuration and component patterns for integrating @nuxt/content.
- Included mappings for `nuxt.config.ts`, `content.config.ts`, and new components `ProseImg.vue` and `Alert.vue`.
- Added example markdown content for testing syntax highlighting and layout.
- Documented critical patterns and anti-patterns to follow during implementation.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2 plans, 2 waves. Plan 01 installe @nuxt/content + typography et
configure Shiki dual-theme + collections bilingues. Plan 02 crée
ProseImg/Alert MDC et articles de test FR/EN avec checkpoint visuel.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Added a new `/hytale` page with sections for hero, services, and pricing.
- Updated existing components to support Hytale-specific content and i18n.
- Modified site configuration and state to reflect the new focus on Hytale plugin development.
- Enhanced testimonials section to feature relevant client feedback.
- Adjusted navigation to include a link to the new Hytale page.
- Switched from npm to pnpm for dependency management in Dockerfile, improving build efficiency.
- Updated Vue and Vue Router versions in package.json for better compatibility.
- Changed placeholder URLs in site.ts to actual Fiverr links and adjusted review count.
- Removed obsolete sitemap.xml file to streamline the project.
- Added a new rate limiting plugin to manage API request limits for the contact endpoint.
- Deleted several planning documents including config.json, PROJECT.md, REQUIREMENTS.md, ROADMAP.md, STATE.md, and various phase plans.
- These files were no longer relevant to the current project structure and development practices, streamlining the codebase.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Deleted several planning documents including ARCHITECTURE.md, CONCERNS.md, CONVENTIONS.md, INTEGRATIONS.md, STACK.md, STRUCTURE.md, and TESTING.md.
- These files were no longer relevant to the current project structure and development practices.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Corrected the name in various files including CLAUDE.md, README.md, and configuration files to reflect the updated branding.
- Ensured consistency in the use of the new name throughout the project, enhancing brand identity.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Complete visual overhaul of all pages and components with generous spacing,
bold typography, hover effects, gradient accents, and section differentiation.
Hero features animated terminal mockup and gradient text. Cards use hover
transforms with brand-colored shadows. CTAs use gradient backgrounds.
All i18n keys, data structures, SEO meta, and composable logic preserved.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
UDrawer (vaul-vue bottom-sheet) rendered content in DOM even when closed,
causing mobile nav to show on desktop. Replaced with USlideover (proper
sidebar panel). Also: backdrop-blur header, UButton for actions, Lucide
icons, brand color active states.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Nuxt prefixes components in subdirectories (layout/AppHeader → LayoutAppHeader).
Setting pathPrefix: false allows using <AppHeader>, <HeroSection>, etc. directly.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Hero with stats (available services count, rating) and profile CTA
- Service cards grid with NuxtImg, price/status badges, order buttons
- FAQSection with UAccordion using homeFAQs data
- Final CTA section linking to Fiverr profile
- Dynamic route /project/[id] with findById composable
- 404 via createError if project not found
- Hero grid: image + info + CTA buttons (demo, source, custom)
- About section with features list (checkmarks)
- Technologies section with TechBadge
- Gallery thumbnails with zoom overlay, opens ProjectGallery modal
- Sidebar: project info card + related projects
- Responsive 2-col layout (main + sidebar)
- SUMMARY.md with 3 tasks, 17 files, 239s duration
- STATE.md advanced to phase 3 plan 1
- ROADMAP.md updated with plan progress
- COMP-01 to COMP-04 marked complete
- Remove PAGE-07 from requirements (formation deleted per D-19)
- No redirect, /formation returns 404 naturally
- Plan 04 now includes full legacy src/ cleanup
- Update success criteria: 7 routes, SMTP instead of EmailJS
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Contact form uses server-side nodemailer via Nuxt API route (not EmailJS)
- Formation page removed from Phase 3 scope (was SaaS pricing, not portfolio)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Formation was a SaaS pricing page unrelated to the portfolio.
Removed: page, nav link, locale keys (nav.formation, seo.formation,
pricing.*) in both FR and EN, legacy source files.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Introduced a new docker-compose.yml file to define the portfolio service.
- Configured Traefik routing with TLS settings and redirect middleware for non-www to www.
- Set up environment variables and network configuration for the service.
Decisions: 6-section landing, UModal+UCarousel gallery with thumbnails,
3-field contact form with EmailJS+Zod, SSR Docker with runtimeConfig.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All 3 TypeScript errors resolved, build passes, server renders.
Phase 2 SSR Shell marked complete.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@nuxt/ui provides the Vite plugin but tailwindcss package itself
must be installed for @import "tailwindcss" to resolve in CSS.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Nuxt UI v3 manages Tailwind v4 internally. The old tailwind.config.js
pointed to src/ and used Tailwind v3 format, causing SSR conflicts.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
These are legacy configs from the Vue SPA. Nuxt manages Vite and
PostCSS internally — external configs cause IPC connection errors.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@nuxtjs/i18n resolves langDir relative to its own i18n/ directory,
not the project root. Moved fr.json and en.json accordingly.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Sticky header with z-[1020], desktop nav with locale-aware NuxtLinks
- FR/EN text toggle using useSetLocale, dark/light icon toggle using useColorMode
- Mobile UDrawer with stacked nav links and toggles
- WCAG: min-w-11 min-h-11 touch targets, focus-visible:ring-2, aria-current on active link
- useSeoMeta() with localized title/description/og tags on all 6 pages
- Homepage JSON-LD with Person + ProfessionalService schema
- og:image absolute URL on every page
- Stub templates with max-w-7xl wrapper and h1
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- nav, footer, a11y, seo keys from UI-SPEC copywriting contract
- All existing keys migrated from src/locales/fr.ts and en.ts
- Includes home, projects, about, contact, fiverr, faq, pricing, projectData, testimonials, common
- Emojis stripped from translation values for clean rendering
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Brand color #85cb85 as CSS @theme with full shade palette
- app.config.ts maps Nuxt UI primary to brand
- colorMode with cookie storage, dark default, no FOUC
- i18n baseUrl and site.url for absolute SEO URLs
- Static og:image placeholder in public/
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 4 data files created in app/data/ with proper type imports from shared/types
- 74 WebP images copied to public/images/ (including flowboard gallery)
- All image paths migrated from @/assets/images/ to /images/
- FAQ uses i18n keys instead of direct text
- Mark RESEARCH.md Open Questions as RESOLVED with decisions
- Fix Plan 01-02 Task 1 verify to be independent of Task 2 (file existence + grep check instead of typecheck)
- Strengthen negative criterion: all app/data/ files must NOT contain @/assets/images/
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 23:45:00 +02:00
11 changed files with 7 additions and 173 deletions
"title":"Async — Coroutines for Hytale's per-world ECS",
"description":"Kotlin coroutine library that replaces the noisy CompletableFuture + world.execute pattern with one suspending call. Player/world/plugin scopes, three dispatchers, suspending ECS DSL.",
"longDescription":"Async solves Hytale's per-world thread model: each world runs on its own thread, touching components from elsewhere throws, and blocking I/O on the world thread freezes players. The library ships dispatchers (World, HytaleIO, Scheduled), scope registries (PlayerScopes, WorldScopes, PluginScopes) with automatic cancellation on disconnect, and a suspending read/modify DSL. Built in Kotlin 2.2, target JVM 24, modular split (core / ecs / binding / dist) so business logic stays testable without a Hytale server.",
"description":"Hytale plugin that fires chain lightning on right-click — bolt jumps to up to 5 nearby enemies within 8 blocks, with damage falloff per hop and a 4-second cooldown.",
"longDescription":"Magical sceptre for Hytale servers. Pure-Java chain resolver decoupled from Hytale via small interfaces (RayCaster, EntitySource, ChainEntity), JUnit 5 tested without a running server. Built on Hytale Plugin API + Java 25 + Gradle Shadow.",
"buttons":{
"modtale":"Modtale",
"curseforge":"CurseForge"
}
},
"playhours":{
"playhours":{
"title":"PlayHours — Forge Server Hours Enforcement",
"title":"PlayHours — Forge Server Hours Enforcement",
"description":"Forge 1.20.1 mod that enforces per-day open windows, blocks logins outside hours, warns at 15/10/5/1 min, auto-kicks at close, handles holidays, whitelist/blacklist, force modes, LuckPerms integration.",
"description":"Forge 1.20.1 mod that enforces per-day open windows, blocks logins outside hours, warns at 15/10/5/1 min, auto-kicks at close, handles holidays, whitelist/blacklist, force modes, LuckPerms integration.",
@@ -538,14 +517,6 @@
"gravity-flip":{
"gravity-flip":{
"title":"GravityFlip Region",
"title":"GravityFlip Region",
"tagline":"Drop a wand, set 2 corners, gravity flips inside the zone. Ceiling-walking and floating items live in 5 minutes of setup."
"tagline":"Drop a wand, set 2 corners, gravity flips inside the zone. Ceiling-walking and floating items live in 5 minutes of setup."
},
"chain-lightning":{
"title":"ChainLightning Sceptre",
"tagline":"Right-click a mob and the bolt jumps to up to 5 nearby enemies within 8 blocks. Damage falls off per hop, JUnit-tested chain resolver."
},
"async":{
"title":"Async — Kotlin coroutines for Hytale ECS",
"tagline":"One suspending call replaces CompletableFuture + world.execute boilerplate. Player/world/plugin scopes, three dispatchers, automatic cancellation on disconnect."
"title":"Async — Coroutines pour l'ECS per-world de Hytale",
"description":"Bibliothèque Kotlin qui remplace le pattern CompletableFuture + world.execute par un seul appel suspending. Scopes player/world/plugin, trois dispatchers, DSL ECS suspending.",
"longDescription":"Async résout le modèle thread per-world de Hytale : chaque monde tourne sur son thread, toucher un composant ailleurs throw, et un I/O bloquant sur le thread world freeze tous les joueurs. La lib expose des dispatchers (World, HytaleIO, Scheduled), des registres de scopes (PlayerScopes, WorldScopes, PluginScopes) avec annulation automatique au disconnect, et un DSL read/modify suspending. Construit en Kotlin 2.2, cible JVM 24, split modulaire (core / ecs / binding / dist) pour garder la logique testable sans serveur Hytale.",
"description":"Plugin Hytale qui lance un éclair en chaîne au clic droit — le bolt rebondit sur jusqu'à 5 ennemis proches dans un rayon de 8 blocs, avec damage falloff par hop et un cooldown de 4 secondes.",
"longDescription":"Sceptre magique pour serveurs Hytale. Chain resolver pur Java découplé de Hytale via petites interfaces (RayCaster, EntitySource, ChainEntity), testé en JUnit 5 sans serveur. Construit sur Hytale Plugin API + Java 25 + Gradle Shadow.",
"buttons":{
"modtale":"Modtale",
"curseforge":"CurseForge"
}
},
"playhours":{
"playhours":{
"title":"PlayHours — Forge Server Hours Enforcement",
"title":"PlayHours — Forge Server Hours Enforcement",
"description":"Mod Forge 1.20.1 qui force des horaires d'ouverture par jour, blocage de connexion hors heures, warns 15/10/5/1 min, auto-kick à la fermeture, gestion des jours fériés, whitelist/blacklist, force modes, intégration LuckPerms.",
"description":"Mod Forge 1.20.1 qui force des horaires d'ouverture par jour, blocage de connexion hors heures, warns 15/10/5/1 min, auto-kick à la fermeture, gestion des jours fériés, whitelist/blacklist, force modes, intégration LuckPerms.",
@@ -538,14 +517,6 @@
"gravity-flip":{
"gravity-flip":{
"title":"GravityFlip Region",
"title":"GravityFlip Region",
"tagline":"Pose un wand, définis 2 corners, gravité inversée dans la zone. Marche-au-plafond et items qui flottent en 5 minutes de setup."
"tagline":"Pose un wand, définis 2 corners, gravité inversée dans la zone. Marche-au-plafond et items qui flottent en 5 minutes de setup."
},
"chain-lightning":{
"title":"ChainLightning Sceptre",
"tagline":"Clic droit sur un mob et l'éclair rebondit sur jusqu'à 5 ennemis dans un rayon de 8 blocs. Damage falloff par hop, chain resolver JUnit-testé."
},
"async":{
"title":"Async — Coroutines Kotlin pour l'ECS Hytale",
"tagline":"Un seul appel suspending remplace le boilerplate CompletableFuture + world.execute. Scopes player/world/plugin, trois dispatchers, annulation auto au disconnect."
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.