MonorailCSS Configuration

MonorailCSS provides a Tailwind-like CSS framework specifically designed for MyLittleContentEngine. This reference covers all configuration options, built-in styles, and customization capabilities.

MonorailCssOptions

The MonorailCssOptions class provides the primary configuration interface for customizing the CSS framework:

public class MonorailCssOptions
{
    public Func<int> PrimaryHue { get; init; } = () => 250;
    public Func<string> BaseColorName { get; init; } = () => ColorNames.Gray;
    public Func<int, (int, int, int)> ColorSchemeGenerator { get; init; } = 
        primary => (primary + 180, primary + 90, primary - 90);
    public Func<CssFrameworkSettings, CssFrameworkSettings> CustomCssFrameworkSettings { get; init; } = 
        settings => settings;
}

Configuration Properties

PrimaryHue

  • Type: Func<int>
  • Default: () => 250 (blue)
  • Range: 0-360 (HSL hue degrees)
  • Purpose: Sets the primary color for your site theme

Example Usage:

builder.Services.AddMonorailCss(options => new MonorailCssOptions
{
    PrimaryHue = () => 200  // Cyan/teal theme
});

BaseColorName

  • Type: Func<string>
  • Default: () => ColorNames.Gray
  • Options: ColorNames.Gray, ColorNames.Slate, ColorNames.Zinc, ColorNames.Neutral, ColorNames.Stone
  • Purpose: Sets the neutral color palette used for text, backgrounds, and borders

Example Usage:

builder.Services.AddMonorailCss(options => new MonorailCssOptions
{
    BaseColorName = () => ColorNames.Slate  // Cooler neutral tones
});

ColorSchemeGenerator

  • Type: Func<int, (int, int, int)>
  • Default: primary => (primary + 180, primary + 90, primary - 90)
  • Purpose: Generates accent and tertiary colors based on primary hue
  • Returns: Tuple of (accent, tertiary-one, tertiary-two) hue values

Default Behavior:

  • Accent: Primary + 180° (complementary color)
  • Tertiary One: Primary + 90° (for syntax highlighting)
  • Tertiary Two: Primary - 90° (for syntax highlighting)

Example Usage:

builder.Services.AddMonorailCss(options => new MonorailCssOptions
{
    ColorSchemeGenerator = primaryHue => (
        primaryHue + 120,  // Triadic accent
        primaryHue + 60,   // Analogous tertiary one
        primaryHue - 60    // Analogous tertiary two
    )
});

CustomCssFrameworkSettings

  • Type: Func<CssFrameworkSettings, CssFrameworkSettings>
  • Default: settings => settings (no modification)
  • Purpose: Allows deep customization of the underlying CSS framework

Example Usage:

builder.Services.AddMonorailCss(options => new MonorailCssOptions
{
    CustomCssFrameworkSettings = settings => settings with
    {
        // Add custom utility classes or modify existing ones
        Applies = settings.Applies.Add(".my-custom-class", "bg-primary-500 text-white p-4")
    }
});

Built-in Component Styles

MonorailCSS includes pre-configured styles for common components. You can modify these using the CustomCssFrameworkSettings option.

builder.Services.AddMonorailCss(_ =>
{
    return new MonorailCssOptions
    {
        CustomCssFrameworkSettings = defaultSettings => defaultSettings with
        {
            Applies = defaultSettings.Applies.SetItem(".hljs-deletion", "text-amber-700 dark:text-amber-300")
        }
    };
});

Tab Components

return ImmutableDictionary.Create<string, string>()
    .AddRange(new Dictionary<string, string>
    {
        {
            ".tab-container",
            "flex flex-col bg-base-100 border border-base-300/75 shadow-xs rounded rounded-xl overflow-x-auto dark:bg-base-950/25 dark:border-base-700/50"
        },
        { 
            ".tab-list", 
            "flex flex-row flex-wrap px-4 pt-1 bg-base-200/90 gap-x-2 lg:gap-x-4 dark:bg-base-800/50" },
        {
            ".tab-button",
            "whitespace-nowrap border-b border-transparent py-2 text-xs text-base-900/90 font-medium transition-colors hover:text-accent-500 disabled:pointer-events-none disabled:opacity-50 data-[selected=true]:text-accent-700 data-[selected=true]:border-accent-700 dark:text-base-100/90 dark:hover:text-accent-300 dark:data-[selected=true]:text-accent-400 dark:data-[selected=true]:border-accent-400"
        },
        {
            ".tab-panel", 
            "hidden data-[selected=true]:block py-3 "
        },
    });

Code Highlighting

return ImmutableDictionary.Create<string, string>()
    .AddRange(new Dictionary<string, string>
    {
        {
            ".code-highlight-wrapper .standalone-code-container",
            "bg-white/50 border border-base-300/75 shadow-xs rounded rounded-xl overflow-x-auto dark:bg-black/20 dark:border-base-700/50"
        },
        {
            ".code-highlight-wrapper pre ",
            "py-2 px-4 md:px-4  overflow-x-auto  font-mono text-xs md:text-sm  leading-relaxed w-full dark:scheme-dark"
        },
        {
            ".code-highlight-wrapper .standalone-code-highlight pre",
            "text-base-900/90 dark:text-base-100/90"
        },
        {
            ".code-highlight-wrapper pre code",
            "font-mono"
        },
                
        // Code transformation line containers
        {
            ".code-highlight-wrapper .line",
            "inline-block transition-all duration-300 px-4  -mx-4  w-[calc(100%+2rem)] relative"
        },
        {
            ".code-highlight-wrapper pre.has-focused .line",
            "blur-[0.095rem] opacity-75"
        },
                
        {
            ".code-highlight-wrapper pre.has-focused:hover .line",
            "blur-[0] opacity-100"
        },

                
        // Line highlighting
        {
            ".code-highlight-wrapper .line.highlight",
            "bg-primary-700/20 dark:bg-primary-500/20"
        },
                
        // Diff notation
        {
            ".code-highlight-wrapper .line.diff-add",
            "bg-emerald-600/20 dark:bg-emerald-900/20 before:font-bold before:content-['+'] before:hidden md:before:block before:text-sm before:absolute before:left-1 before:green:text-green-500 before:text-green-700"
        },
        {
            ".code-highlight-wrapper .line.diff-remove",
            "bg-red-600/20 dark:bg-red-900/20 opacity-50 before:font-bold before:content-['-'] before:hidden md:before:block before:text-sm before:absolute before:left-1 before:dark:text-red-500 before:text-red-700"
        },
                
        // Focus and blur
        {
            ".code-highlight-wrapper pre.has-focused  .line.focused",
            "blur-[0] opacity-100"
        },

        // Error and warning states
        {
            ".code-highlight-wrapper .line.error",
            "bg-red-300/50 dark:bg-red-500/20"
        },
        {
            ".code-highlight-wrapper .line.warning",
            "bg-amber-300/50 dark:bg-amber-400/20"
        },
                
        // Word highlighting
        {
            ".code-highlight-wrapper .word-highlight",
            "border border-primary-600 dark:border-primary-300/25 rounded px-0.5 py-0 bg-primary-100/25 dark:bg-primary-500/10"
        },
        {
            ".code-highlight-wrapper .word-highlight-with-message",
            "border border-b border-primary-600 dark:border-primary-300/25 rounded px-1 py-1 bg-primary-100/25 dark:bg-primary-500/10 relative "
        },
        {
            ".code-highlight-wrapper .word-highlight-wrapper",
            "relative inline-block"
        },
        {
            ".code-highlight-wrapper .word-highlight-message",
            "font-sans font-semilight tracking-loose absolute top-full left-0 mt-3 px-2 py-1 text-xs text-base-800 bg-base-200/25 dark:bg-base-700/10 dark:text-base-400 rounded border border-base-500/50 whitespace-nowrap z-10 select-none pointer-events-none"
        },
        {
            ".word-highlight-arrow-container",
            "absolute -top-1.5 left-10 transform -translate-x-1/2"
        },
        {
            ".word-highlight-arrow-outer",
            "w-0 h-0 border-l-6 border-r-6 border-b-6 border-l-transparent border-r-transparent border-b-base-500/50"
        },
        {
            ".word-highlight-arrow-inner",
            "absolute w-0 h-0 border-l-5 border-r-5 border-b-5 border-l-transparent border-r-transparent border-b-base-200/25 dark:border-b-base-700/10 top-0 left-1/2 transform -translate-x-1/2"
        },
        {
            ".code-highlight-wrapper .word-highlight-message::selection",
            "bg-transparent"
        },
        {
            ".code-highlight-wrapper .line:has(.word-highlight-wrapper)",
            "mb-12"
        },
    });

Markdown Alert Blocks

const string alertFormatString =
    "fill-{0}-700 dark:fill-{0}-500 bg-{0}-100/75 border-{0}-500/20 dark:border-{0}-500/30 dark:bg-{0}-900/25 text-{0}-800 dark:text-{0}-200";

         
        
return ImmutableDictionary.Create<string, string>()
    .AddRange(new Dictionary<string, string>
    {
        // Markdig Alert Styles
        { ".markdown-alert", "my-6 p-4 flex flex-row gap-2.5 rounded-2xl border text-sm" },
        { ".markdown-alert a", "underline" },
        { ".markdown-alert-note", string.Format(alertFormatString, "emerald") },
        { ".markdown-alert-tip", string.Format(alertFormatString, "blue") },
        { ".markdown-alert-caution", string.Format(alertFormatString, "amber") },
        { ".markdown-alert-warning", string.Format(alertFormatString, "rose") },
        { ".markdown-alert-important", string.Format(alertFormatString, "sky") },
        { ".markdown-alert-title span", "hidden" },
        { ".markdown-alert svg", "h-4 w-4 mt-0.5" },
    });

Syntax Highlighting

MonorailCSS provides a complete syntax highlighting theme using the generated color palettes:

Color Mapping

  • Comments: Base colors with reduced opacity, italic
  • Keywords: Primary color palette
  • Strings/Numbers: Tertiary-one color palette
  • Functions: Accent color palette
  • Variables: Tertiary-two color palette
  • Operators: Base colors

Configuration

return ImmutableDictionary.Create<string, string>()
    .AddRange(new Dictionary<string, string>
    {
        // Base highlight.js styles
        { ".hljs", "text-base-900 dark:text-base-200" },

        // Comments
        { ".hljs-comment", "text-base-600 italic dark:text-base-400" },
        { ".hljs-quote", "text-base-800/50 italic dark:text-base-300" },

        // Keywords and control flow
        { ".hljs-keyword", "text-primary-800 dark:text-primary-300" },
        { ".hljs-selector-tag", "text-primary-700 dark:text-primary-300" },
        { ".hljs-literal", "text-primary-800 dark:text-primary-300" },
        { ".hljs-type", "text-base-700 dark:text-base-300" },

        // Strings and characters
        { ".hljs-string", "text-tertiary-one-800 dark:text-tertiary-one-300" },
        { ".hljs-number", "text-tertiary-one-800 dark:text-tertiary-one-300" },
        { ".hljs-regexp", "text-tertiary-one-800 dark:text-tertiary-one-300" },

        // Functions and methods
        { ".hljs-function", "text-accent-800 dark:text-accent-300" },
        { ".hljs-title", "text-accent-800 dark:text-accent-300" },
        { ".hljs-params", "text-accent-800 dark:text-accent-300" },

        // Variables and identifiers
        { ".hljs-variable", "text-tertiary-two-800 dark:text-tertiary-two-300" },
        { ".hljs-name", "text-tertiary-two-800 dark:text-tertiary-two-300" },
        { ".hljs-attr", "text-tertiary-two-800 dark:text-tertiary-two-300" },
        { ".hljs-symbol", "text-tertiary-two-800 dark:text-tertiary-two-300" },

        // Operators and punctuation
        { ".hljs-operator", "text-base-800 dark:text-base-300" },
        { ".hljs-punctuation", "text-base-800 dark:text-base-300" },

        // Special elements
        { ".hljs-built_in", "text-accent-700 dark:text-accent-300" },
        { ".hljs-class", "text-primary-800 dark:text-primary-300" },
        { ".hljs-meta", "text-base-800 dark:text-base-300" },
        { ".hljs-tag", "text-primary-800 dark:text-primary-300" },
        { ".hljs-attribute", "text-tertiary-two-800 dark:text-tertiary-two-300" },
        { ".hljs-addition", "text-green-800 dark:text-green-300" },
        { ".hljs-deletion", "text-red-800 dark:text-red-300" },
        { ".hljs-link", "text-blue-800 dark:text-blue-300" },
    });