hypnagaga_old/.github/copilot-instructions.md
2026-01-08 01:35:35 -05:00

8.1 KiB
Raw Permalink Blame History

Hypnagaga - Eleventy Project

A vision quest, of sorts.

Quick Start

npm install              # Install dependencies
npm start                # Dev server at localhost:8080
npm run build            # Production build
npm run colors           # Regenerate color tokens
npm run test:a11y        # Run accessibility tests

Key Files to Know:

  • eleventy.config.js - Main Eleventy config (imports from src/_config/)
  • src/_config/ - Modular config (collections, filters, events, plugins, shortcodes)
  • src/assets/scripts - scripts are built from here
  • src/assets/css/global - global CSS is built from here
  • src/assets/css/local - inline CSS for certain pages is built from here
  • src/_data/designTokens/ - Design tokens (colors, spacing, fonts)
  • src/pages/ - Contains written content (markdown files) that is processed as JavaScript Nunjuks template
  • dist/ - the project builds to here

Configuration Architecture

ESM-based modular config in src/_config/ - all files use export syntax:

  • collections.js - Eleventy collections (getAllPosts, tagList, tracksByProject)
  • events.js - Build hooks (CSS/JS compilation, pagefind indexing)
  • filters.js - Template filters (dates, markdown, slugify)
  • plugins.js - Eleventy plugins (image transform, WebC, RSS, syntax highlighting)
  • shortcodes.js - Reusable functions, used within Nunjuks templates.

Each category imports from subdirectories (e.g., filters/dates.js) and exports a consolidated object.

CSS Architecture

  1. Based on eleventy-excellent, which uses a progressive enhancement philosphy for a responsive design.

  2. The global CSS bundle is organized with cascade layers. The local CSS bundle, used for per-page or omponent-specific styles, does not utilize cascade layers. As a result, all CSS blocks included have a higher specificity than global styles, regardless of the selector specificity in the global CSS bundle.

  3. Tailwind is used primarily to generate utility classes on demand. It goes through each defined group (groups) and then grabs the values > generates Custom Property values > sticks them to the result. Finally, using postcssJs and postcss, an object that Tailwind can understand is created. The addComponents function sticks that custom properties block on the @components layer. Lastly, this function creates custom utilities that I can use in markup, such as gutter-m or flow-space-s. Its all rigged up to the design tokens Custom Property block. Its damn useful, especially when tweaking layout compositions in context.

  4. Everything is built using PostCSS from src/assets/css/.

. ├── src │ ├── css-utils │ │ ├── clamp-generator.js │ │ └── tokens-to-tailwind.js │ ├── css │ │ ├── blocks │ │ │ └── prose.css │ │ ├── compositions │ │ │ ├── cluster.css │ │ │ ├── flow.css │ │ │ ├── grid.css │ │ │ ├── repel.css │ │ │ ├── sidebar.css │ │ │ ├── switcher.css │ │ │ └── wrapper.css │ │ ├── global │ │ │ ├── fonts.css │ │ │ ├── global-styles.css │ │ │ ├── reset.css │ │ │ └── variables.css │ │ ├── utilities │ │ │ ├── region.css │ │ │ └── visually-hidden.css │ │ └── global.css │ └── design-tokens │ ├── colors.json │ ├── fonts.json │ ├── spacing.json │ ├── text-leading.json │ ├── text-sizes.json │ ├── text-weights.json │ └── viewports.json ├── tailwind.config.js └── postcss.config.js

  1. I try to maintain a decent source order for specificity purposes as you can see. The @import tailwindcss/components is where that block of Custom Properties generated in the Tailwind config gets put. Because everything else that layer does is disabled in config, its nice and clean. The CUBE parts are all imported using the extremely useful import-glob PostCSS plugin. This allows new files to be added to directories and imported straight away. Its very Sass-like, but I like that.

  2. There are layouts in src/assets/css/global/compositions.

Image Handling

  1. ** Primarily accomplished** by extending the {% imageKeys {...} %} shortcode processed from within content markdown files.

Images are processed to WebP/JPEG, multiple widths, and optimized. Source paths are prepended with ./src automatically in shortcodes.

Design Tokens & Tailwind

  • We only use Tailwind to generate class names. All our CSS lives in src/assets/css/ and uses an opinionated, responsive design. It is bundled in dist/bundle/
  • src/assets/css/local - Local inline CSS. Overrides inlined for one-off pages, sections of content, and other endevours. src/assets/css/global is used for site-wide classes of core styling and animation features.
  • Design tokens stored as JSON in src/_data/designTokens/ (colors, spacing, fonts, viewports)
  • tokensToTailwind() and clampGenerator() utilities convert tokens to Tailwind config
  • Tailwind is customized to generate utilities from design tokens (e.g., mt-xs-s, bg-magenta)
  • Custom properties generated via Tailwind plugin (e.g., --color-cyan, --space-m)
  • Run npm run colors after editing colorsBase.json to regenerate colors.json with shades
  • Tailwind's preflight/reset is disabled - custom reset in src/assets/css/global/reset.css

Build Process

Before Eleventy runs (eleventy.before event):

  1. buildAllCss() processes CSS with PostCSS (import-glob → tailwind → autoprefixer → cssnano)
    • Global CSS: src/assets/css/global/global.csssrc/_includes/css/global.css (inlined)
    • Local CSS: src/assets/css/local/**/*.csssrc/_includes/css/ (per-page bundles)
    • Component CSS: src/assets/css/components/**/*.cssdist/assets/css/components/
  2. buildAllJs() bundles JS with esbuild
    • Inline bundle: src/assets/scripts/bundle/**/*.jssrc/_includes/scripts/
    • Defer bundle: similar process
    • Component scripts: src/assets/scripts/components/**/*.jsdist/assets/components/

After Eleventy builds (eleventy.after event):

  • buildPagefind() generates search index (only in production)

Watch targets: src/assets/**/*.{css,js,svg,png,jpeg}, src/_includes/**/*.webc, dist/

Text Animations

Use the animateText shortcode or markdown-it-attrs classes:

{% animateText "Hello", "shiver", "1.5" %}  {# content, animation, speed #}

(defined in src/assets/css/global/utilities/text-animations.css) Safelist these classes in tailwind.config.js so they're not purged.

Pages and Projects

Digital Mixed CD project

The project's core feature is a hierarchical music mix/track system:

  • Projects (e.g., "TomorrowsBacon") contain multiple tracks
  • Tracks are individual markdown files in src/pages/projects/mixes/{project-name}/
  • Tracks have frontmatter: project, track_number, artist, album, albumArt, start_time
  • Collection tracksByProject (defined in src/_config/collections.js) groups and sorts tracks by project
  • Layouts: mix.njk shows track list, mix-track.njk shows individual track with prev/next navigation
  • Turbo Drive provides SPA-like navigation between tracks without full page reloads

Collections

  • allPosts: All markdown files in src/posts/**/*.md (reversed chronological)
  • tagList: Unique tags across all content (excludes 'posts', 'docs', 'all', 'mix', 'project')
  • goPages: Pages with go: frontmatter for URL redirects (output to _redirects)
  • tracksByProject: Tracks grouped by project, sorted by track_number

Turbo Drive Navigation

  • <turbo-frame id="main-content"> in layouts wraps main content
  • Import Turbo in defer bundle: {% js "defer" %} import * as Turbo from '/assets/components/turbo.js'; {% endjs %}