@karnstack/kino 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Karn
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,136 @@
1
+ <p align="center">
2
+ <img src="./assets/kino-banner.png" alt="kino" width="720" />
3
+ </p>
4
+
5
+ <p align="center">
6
+ A themeable React video player with a pluggable-provider architecture —
7
+ translucent glass chrome, keyboard-first controls, and a small typed surface.
8
+ Mux is the first provider.
9
+ </p>
10
+
11
+ <p align="center">
12
+ <a href="https://www.npmjs.com/package/@karnstack/kino"><img alt="npm" src="https://img.shields.io/badge/npm-%40karnstack%2Fkino-10b981?logo=npm&logoColor=white"></a>
13
+ &nbsp;
14
+ <a href="./LICENSE"><img alt="license MIT" src="https://img.shields.io/badge/license-MIT-10b981"></a>
15
+ &nbsp;
16
+ <a href="https://kino.karnstack.com"><img alt="live playground" src="https://img.shields.io/badge/playground-kino.karnstack.com-10b981"></a>
17
+ </p>
18
+
19
+ <p align="center">
20
+ <a href="https://kino.karnstack.com">
21
+ <img src="./assets/playground.png" alt="The kino playground" width="100%" />
22
+ </a>
23
+ </p>
24
+
25
+ > **[Try it live → kino.karnstack.com](https://kino.karnstack.com)** — drop in any public Mux playback ID, pick an accent, and play with the real glass UI.
26
+
27
+ kino ships the player UI and a provider contract. Each provider adapts a streaming engine to that contract, so the same glass chrome can sit on top of different backends. The Mux provider is built on the `@mux/mux-video` custom element.
28
+
29
+ ## Install
30
+
31
+ ```sh
32
+ pnpm add @karnstack/kino
33
+ ```
34
+
35
+ The Mux engine (`@mux/mux-video`) is pulled in transitively, so you do not install it yourself. React 19 is a peer dependency (`react` and `react-dom` `>=19`).
36
+
37
+ ## Quick start
38
+
39
+ ```tsx
40
+ import { MuxPlayer } from "@karnstack/kino/mux"
41
+ import "@karnstack/kino/styles.css"
42
+
43
+ export function Clip() {
44
+ return (
45
+ <MuxPlayer
46
+ playbackId="your-playback-id"
47
+ tokens={{ playback, thumbnail, storyboard }}
48
+ accentColor="oklch(50.8% 0.118 165.612)"
49
+ />
50
+ )
51
+ }
52
+ ```
53
+
54
+ Give the player a sized container. It fills `100%` width and height of its parent, so wrap it in an element with the aspect ratio or dimensions you want.
55
+
56
+ ### Tokens are passed in
57
+
58
+ kino is auth-agnostic. For signed playback you mint the `playback`, `thumbnail`, and `storyboard` tokens server-side and hand them to the player through the `tokens` prop. The player never holds a signing key and never talks to your auth layer; it only appends the tokens you give it to the media, thumbnail, and storyboard URLs. For public playback you can omit `tokens` entirely.
59
+
60
+ ## Theming
61
+
62
+ The quickest knob is the `accentColor` prop, which drives the scrubber fill, active menu items, and range controls.
63
+
64
+ ```tsx
65
+ <MuxPlayer playbackId="..." accentColor="oklch(50.8% 0.118 165.612)" />
66
+ ```
67
+
68
+ For deeper control, every visual is driven by CSS custom properties on the `.kino` root. Override them in your own stylesheet, or pass a `theme` object of property/value pairs to set them inline.
69
+
70
+ | Custom property | Default | Role |
71
+ | ----------------------- | --------------------------------------------- | --------------------------------------------- |
72
+ | `--kino-accent` | `oklch(50.8% 0.118 165.612)` | Accent color (progress, active items, ranges) |
73
+ | `--kino-radius` | `12px` | Corner radius of glass surfaces |
74
+ | `--kino-surface` | `color-mix(in oklab, black 55%, transparent)` | Glass surface fill |
75
+ | `--kino-surface-strong` | `color-mix(in oklab, black 70%, transparent)` | Stronger surface (idle play button) |
76
+ | `--kino-border` | `color-mix(in oklab, white 14%, transparent)` | Hairline borders |
77
+ | `--kino-text` | `oklch(98% 0 0)` | Primary text and icons |
78
+ | `--kino-text-dim` | `color-mix(in oklab, white 65%, transparent)` | Secondary text (timecode) |
79
+ | `--kino-blur` | `18px` | Backdrop blur radius |
80
+ | `--kino-shadow` | `0 8px 40px rgba(0, 0, 0, 0.45)` | Surface drop shadow |
81
+ | `--kino-ease` | `cubic-bezier(0.22, 1, 0.36, 1)` | Shared transition easing |
82
+
83
+ ```css
84
+ .kino {
85
+ --kino-accent: oklch(70% 0.15 250);
86
+ --kino-radius: 16px;
87
+ --kino-blur: 24px;
88
+ }
89
+ ```
90
+
91
+ ## Keyboard shortcuts
92
+
93
+ The player is keyboard-first. Shortcuts are ignored while a text input, textarea, select, or contenteditable element is focused, and modifier-key combinations (Ctrl/Cmd/Alt) are passed through.
94
+
95
+ | Key | Action |
96
+ | ------------- | --------------------------------------------- |
97
+ | `Space` / `K` | Play / pause |
98
+ | `<` / `>` | Decrease / increase playback rate (0.25 step) |
99
+ | `M` | Toggle mute |
100
+ | `C` | Toggle captions |
101
+ | `S` | Open the speed menu |
102
+ | `F` | Toggle fullscreen |
103
+ | `0`-`9` | Seek to 0%-90% of the duration |
104
+
105
+ ## Capability gating
106
+
107
+ Controls hide themselves when the active provider or platform cannot support them, rather than presenting a dead button. The provider reports a capability set, and each control checks it:
108
+
109
+ - Quality switching is hidden when the engine exposes no renditions, and is off on iOS where the system owns adaptive playback.
110
+ - Custom-chrome fullscreen is off on iOS (the platform uses its native fullscreen for the underlying video element).
111
+ - Picture-in-picture is hidden when the browser does not support it.
112
+ - The captions menu appears only when the media actually carries subtitle or caption tracks.
113
+
114
+ ## Local development
115
+
116
+ ```sh
117
+ pnpm install
118
+ pnpm dev # demo harness at http://localhost:5173
119
+ pnpm test # vitest
120
+ pnpm build # bundle to dist/
121
+ pnpm typecheck # tsc --noEmit
122
+ pnpm lint # eslint
123
+ ```
124
+
125
+ `pnpm dev` runs the playground in `demo/` — the real kino glass UI on the Mux provider, playing public sample assets. Paste any public Mux playback ID, switch accent colors, and tweak the corner radius live; no Mux account or signed tokens required. The same playground is deployed at [kino.karnstack.com](https://kino.karnstack.com).
126
+
127
+ ## Roadmap
128
+
129
+ - More providers: YouTube, file, and Vimeo
130
+ - AirPlay support
131
+ - Chapters
132
+ - Documented headless primitives for fully custom chrome
133
+
134
+ ## License
135
+
136
+ MIT