# Lys > Zero-dependency CSS + TS slide engine. Turns `
` elements into accessible, navigable presentations. Visually unopinionated, behaviorally opinionated. Designed for LLM-generated single-file HTML. ## HTML Contract Slides are `
` elements inside a `
` container. Use standard HTML elements inside each article. ### Data Attributes (on `
`) | Attribute | Purpose | Example | |---|---|---| | `data-notes` | Speaker notes (text) | `data-notes="Mention Q3 figures"` | | `data-transition` | Transition mode (`"fade"` enables fade for the deck) | `data-transition="fade"` | | `data-class` | CSS classes added to the slide | `data-class="title-slide dark"` | | `data-background` | Background shorthand (color, gradient, URL) | `data-background="#1a1a2e"` | | `data-timing` | Suggested duration in seconds | `data-timing="30"` | ## CSS Tokens Set `--lys-*` properties on `:root`, `[data-lys]`, or individual `
` elements to customize. | Token | Default | |---|---| | `--lys-aspect-ratio` | `16 / 9` | | `--lys-slide-padding` | `4cqi` | | `--lys-transition-duration` | `300ms` | | `--lys-transition-easing` | `ease-in-out` | | `--lys-font-size-base` | `clamp(0.75rem, 2.5cqi, 1.5rem)` | | `--lys-slide-gap` | `0` | | `--lys-slide-max-width` | `100vw` | | `--lys-slide-max-height` | `100vh` | | `--lys-focus-ring` | `2px solid currentColor` | | `--lys-backdrop` | `light-dark(#fff, #000)` | ## Events Emitted on the `[data-lys]` container element, with `bubbles: true`. - **`lys:ready`** — `{ detail: { instance } }` — Initialization complete. The instance exposes the JS API below. - **`lys:slidechange`** — `{ detail: { from: number, to: number, slide: HTMLElement } }` — Slide changed. ## JS API ``` Lys.init() → Lys[] // Auto-discover all [data-lys] containers Lys.from(el) → Lys // Get or create instance (idempotent) new Lys(el) → Lys // Create instance for a container instance.next() // Next slide (no-op at end) instance.prev() // Previous slide (no-op at start) instance.goTo(index | id) // Jump by 0-based index or article id instance.destroy() // Remove listeners, revert state instance.current → number // 0-based current slide index (-1 if empty) instance.total → number // Total slide count instance.slide → HTMLElement|null // Current slide element ``` Navigation: Arrow keys, Space/Shift+Space, Home/End, touch swipe, hash routing (`#slide=3` or `#slide=intro`). IIFE build auto-initializes on DOMContentLoaded. ESM build exposes `Lys` for manual control. ## Inline Example ```html My Deck

Title

Subtitle text here.

Second Slide

  • Point one
  • Point two
``` ## File Sizes | File | Raw | Gzip | |---|---|---| | `lys.css` | 2.7 KB | 0.9 KB | | `lys.iife.js` | 5.7 KB | 2.2 KB |