Generate only what you need with .luis

With @for, @if, and @fun, generate only what you need. With Observed, only the styles in use are produced.

styles.luis
/* Use the flexibility of object variables */
--colors: {
  brand:  #0069c6;
  accent: #0098a7;
  text:   #0f1923;
};

--space: { sm: 8px; md: 16px; lg: 32px; };
--cols: [1-4];

@for(n, var(--cols)) {
  .grid-${n}?! {
    grid-template-columns: repeat(${n}, 1fr);
  }
}

.card {
  padding: var(--space.md);
  color:   var(--colors.text);
  border:  1px solid var(--colors.brand);
}
output.css
/* grid-1, grid-2, grid-3 defined as Initial Observed
are not generated when absent from the DOM */

.grid-4 { grid-template-columns: repeat(4, 1fr); }
/* grid-4 was in the DOM, so it was generated */

.card {
  padding: 16px;
  color:   #0f1923;
  border:  1px solid #0069c6;
}

Flexible language

LentyStyle brings the source language, compiler, browser runtime, hybrid, and SSR flows into one ecosystem.

Object & Array Variables

Go beyond standard CSS variables. Define object and array variables like --colors: { brand: #0069c6; } and --range: [1-8].

@for / @if Control Flow

Write loops and conditions to generate CSS. Utility class sets, conditional rule generation — all at compile time.

@fun Functions

CSS functions with Block Emit, Inline Value Return, and Property Inline Return modes. Local variables and the ${expr} expression engine included.

Observed Selectors

Dynamic DOM presence tracking with ?. Only the rules you need are generated with ?!.

Hybrid & SSR

Route-aware CSS generation. Build-time snapshot or request-time orchestration.

Guard & Security

Guard subpaths in Core provide a fail-closed security layer for runtime URL policy, hybrid source validation, and SSR envelope scanning.

Use what you need

Add the Core, Hybrid, or SSR package to match your usage model.

@lentystyle/core

Main package exposing the compiler, runtime, and public guard surfaces.

@lentystyle/hybrid

Route-aware CSS generation over build-time HTML snapshots.

@lentystyle/ssr

Request-time CSS orchestration and server-side integration flow.

.luis

The .luis language adds a programmatic layer on top of CSS while keeping full CSS validity. The learning curve is minimal.

  • Full CSS validity
    Standard CSS works directly inside .luis.
  • Object/Array variables
    Flexible access in Array and Object variables like var(--theme.color), var(--breaks[0]), var(--breaks[0].sm).
  • Compile-time calculations
    Expressions like ${i * 4}px, ${(i + 2) * 3}px are written statically into CSS.
  • Import chain
    In the compiler/build flow .luis and CSS files can be imported; the browser runtime does not separately fetch .luis import targets.

/* Define a token object */
--palette: {
  primary:   #0069c6;
  secondary: #0098a7;
  bg:        #f8fafc;
};

/* Access by key */
.hero {
  background: var(--palette.bg);
  color:      var(--palette.primary);
  border: 1px solid var(--palette.secondary);
}

/* .hero { background: #f8fafc; } */

/* Define a number array */
--spacing: [1, 2, 3, 4, 6, 8, 12];

/* Generate utility classes */
@for(n, var(--spacing)) {
  .p-${n}   { padding: ${n * 4}px; }
  .m-${n}   { margin:  ${n * 4}px; }
  .gap-${n} { gap:     ${n * 4}px; }
}

/* Iterate over object */
@for(key, var(--palette)) {
  .text-${key} {
    color: var(--palette[${key}]);
  }
}

/* Function definition */
@fun: shadow(blur, color) {
  box-shadow: 0 4px ${blur}px
              ${blur / 2}px
              ${color};
}

/* Block emit usage */
.card {
  @fun.shadow(24, rgba(0,0,0,0.08));
  padding: 24px;
}

/* Inline value return */
@fun: fontSize(pix) { ${pix / 16}rem; }
.title { font-size: @fun.fontSize(24); }
/* → font-size: 1.5rem */

/* ? — dynamic observed selector
Rule is active when .card is in the DOM.
Rule is inactive when .card is not in the DOM. DOM is tracked.
If .card is added to the DOM later, the rule becomes active. */
.card? {
  transition: transform 160ms ease;
}

/* Interaction state remains as native CSS */
.card:hover {
  transform: translateY(-4px);
}

/* ?! — initial snapshot
Rule is active if .card is in the DOM. DOM is not tracked. */
@for(i, [1-4]) {
  .grid-${i}?! {
    grid-template-columns: repeat(${i}, 1fr);
  }
}

From source to CSS

1

Write .luis

Object variables, loops, conditions, functions, and standard CSS together.

2

Compiler Runs

Output: standard CSS, warnings, and metadata required for runtime flows.

3

Choose a Flow

Compiler-only, browser runtime, hybrid snapshot, or SSR.

4

CSS Applied

Static CSS is applied directly; if runtime is used, the initial source set is compiled.

You'll love writing styles.

Open the setup guide, choose your usage model, and compile your first .luis source into real CSS output.