A music player that connects to your cloud/distributed storage.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: try not to mention themes or facets, make it an implementation detail.

+176 -243
+2 -12
_config.ts
··· 179 179 180 180 // HELPERS 181 181 182 - site.filter("facetOrThemeURI", (text) => { 182 + site.filter("facetURI", (text) => { 183 183 if (text.includes("://")) { 184 184 return text; 185 185 } else { ··· 194 194 key = "uri"; 195 195 } 196 196 197 - return `facets/l/?${key}=${encodeURIComponent(text)}`; 198 - }); 199 - 200 - site.filter("themeLoaderURL", (text) => { 201 - let key = "path"; 202 - 203 - if (text.includes("://")) { 204 - key = "uri"; 205 - } 206 - 207 - return `themes/l/?${key}=${encodeURIComponent(text)}`; 197 + return `kitchen/l/?${key}=${encodeURIComponent(text)}`; 208 198 }); 209 199 210 200 ////////////////////////////////////////////
+78
src/_agency.vto
··· 1 + <!-- AGENCY --> 2 + <section> 3 + <h2 id="agency">Agency</h2> 4 + 5 + <p> 6 + The goal is for every user, no matter their knowledge level, to have agency over their data and their software. One can start with making small changes and gradually progress to making big changes. 7 + </p> 8 + 9 + <p> 10 + You can store your user-data in various places, and easily export, import and sync it. 11 + </p> 12 + 13 + <h3>Take control</h3> 14 + 15 + <ul class="columns"> 16 + <div class="element"> 17 + <!-- 1 --> 18 + <li> 19 + <p> 20 + <i class="ph-fill ph-storefront"></i> <strong>Level 1</strong>: Pick your restaurant, food comes in all shapes and sizes. The equivalent of choosing a Diffuse <a href="themes/">theme</a>. 21 + </p> 22 + </li> 23 + <!-- 2 --> 24 + <li> 25 + <p> 26 + <i class="ph-fill ph-basket"></i> <strong>Level 2</strong>: Take out food from various places, eg. cheese shop + bakery. You choose how you combine the foods and from where you order them. That's <a href="facets/">facets</a>. 27 + </p> 28 + </li> 29 + <!-- 3 --> 30 + <li> 31 + <p> 32 + <i class="ph-fill ph-pepper"></i> <strong>Level 3</strong>: Now that you know which food is good and how to make combinations, you might make a slight customization, add a little something of your own (eg. add some spice). However, you're not quite confident enough which spice to pick, so you hire some help. 33 + </p> 34 + <p> 35 + This can be done using the <a href="facets/#builder">facets builder</a> which allows you to build on top of a familiar preconfigured foundation and load custom facets. People might share their own, or maybe you use an LLM to generate something for you (eg. an album art gallery). 36 + </p> 37 + </li> 38 + <!-- 4 --> 39 + <li> 40 + <p> 41 + <i class="ph-fill ph-knife"></i> <strong>Level 4</strong>: You learned a bit from watching and talking to the help you hired, so you decide to take things in your own hands. 42 + </p> 43 + <p> 44 + You continue to use the <a href="facets/#builder">facets builder</a> but learn a bit of <a href="https://htmlforpeople.com">HTML</a>, <a href="https://javascript.info">Javascript</a> and <a href="https://htmlforpeople.com/css-basics/">CSS</a>; so you're able to write your own facet. 45 + </p> 46 + </li> 47 + </div> 48 + <div class="element"> 49 + <!-- 5 --> 50 + <li> 51 + <p> 52 + <i class="ph-fill ph-cooking-pot"></i> <strong>Level 5</strong>: At this point you're confident enough to make a meal from scratch. You can start very simple, eg. just throwing a steak in the pan with some butter and some salt to it. Then later add some baked potatoes and go from there. 53 + </p> 54 + <p> 55 + A similar tool comes into play here, the <a href="themes/#builder">themes builder</a>. Same concept as the facets builder, but now you need to specify the foundation yourself. You can use the <a href="#elements">elements</a> listed below to do so. The code for these is available from this website or through the <a href="https://jsr.io/@toko/diffuse">Javascript package</a>. 56 + </p> 57 + </li> 58 + <!-- 6 --> 59 + <li> 60 + <p> 61 + <i class="ph-fill ph-storefront"></i> <strong>Level 6</strong>: You open your own restaurant. 62 + </p> 63 + <p> 64 + You can host the theme you made on any web server, it's only HTML after all. Only difference is that you'll have to create the entire HTML tree, not just the body element, as is the case with the theme builder. 65 + </p> 66 + </li> 67 + <!-- 7 --> 68 + <li> 69 + <p> 70 + <i class="ph-fill ph-chef-hat"></i> <strong>Level 7</strong>: You got promoted to master chef. Time to open your own restaurant chain. 71 + </p> 72 + <p> 73 + You can self-host Diffuse, it's <a href="https://tangled.org/tokono.ma/diffuse/blob/v4/">open-source</a>! Or you present your own collection of elements. 74 + </p> 75 + </li> 76 + </div> 77 + </ul> 78 + </section>
+1 -1
src/_components/facets/examples.vto
··· 1 1 <ul> 2 2 {{ for index, item of items }} 3 - <li data-uri="{{ item.url |> facetOrThemeURI }}" data-name="{{item.title}}" style="margin-top: var(--space-md)"> 3 + <li data-uri="{{ item.url |> facetURI }}" data-name="{{item.title}}" style="margin-top: var(--space-md)"> 4 4 <div style="display: flex; gap: var(--space-xs); justify-content: space-between;"> 5 5 <a href="{{ item.url |> facetLoaderURL }}"> 6 6 {{item.title}}
+1 -1
src/_components/facets/grid.vto
··· 21 21 data-description="{{item.desc.trim()}}" 22 22 data-name="{{item.title}}" 23 23 data-kind="{{item.kind ?? `interface`}}" 24 - data-uri="{{ item.url |> facetOrThemeURI }}" 24 + data-uri="{{ item.url |> facetURI }}" 25 25 > 26 26 <div class="grid-item__contents"> 27 27 <div class="grid-item__title">
+8 -8
src/_components/facets/nav.vto
··· 2 2 {{ set slug = (cat) => cat.toLowerCase().replace(/\s+/g, '-') }} 3 3 4 4 <nav> 5 - <a href="facets/guide/" class="button {{ colorClass("facets/guide/") }} button--border"> 5 + <a href="kitchen/guide/" class="button {{ colorClass("kitchen/guide/") }} button--border"> 6 6 <span class="with-icon"> 7 7 <i class="ph-fill ph-book-open-text"></i> 8 8 Guide 9 9 </span> 10 10 </a> 11 11 12 - <a href="facets/you/" class="button {{ colorClass("facets/you/") }} button--border"> 12 + <a href="kitchen/you/" class="button {{ colorClass("kitchen/you/") }} button--border"> 13 13 <span class="with-icon"> 14 14 <i class="ph-fill ph-person"></i> 15 15 Your collection 16 16 </span> 17 17 </a> 18 18 19 - <a href="facets/" class="button {{ colorClass("facets/") }} button--border"> 19 + <a href="kitchen/" class="button {{ colorClass("kitchen/") }} button--border"> 20 20 <span class="with-icon"> 21 21 <i class="ph-fill ph-sparkle"></i> 22 22 Featured 23 23 </span> 24 24 </a> 25 25 26 - <a href="facets/build/" class="button {{ colorClass("facets/build/") }} button--border"> 26 + <a href="kitchen/build/" class="button {{ colorClass("kitchen/build/") }} button--border"> 27 27 <span class="with-icon"> 28 28 <i class="ph-fill ph-hammer"></i> 29 29 Build ··· 32 32 33 33 <div class="divider"></div> 34 34 35 - <a href="facets/data/" class="button {{ colorClass("facets/data/") }} button--border"> 35 + <a href="kitchen/data/" class="button {{ colorClass("kitchen/data/") }} button--border"> 36 36 Input & Output 37 37 </a> 38 38 39 - <a href="facets/playback/" class="button {{ colorClass("facets/playback/") }} button--border"> 39 + <a href="kitchen/playback/" class="button {{ colorClass("kitchen/playback/") }} button--border"> 40 40 Playback 41 41 </a> 42 42 43 - <a href="facets/browsing/" class="button {{ colorClass("facets/browsing/") }} button--border"> 43 + <a href="kitchen/browsing/" class="button {{ colorClass("kitchen/browsing/") }} button--border"> 44 44 Browsing 45 45 </a> 46 46 47 - <a href="facets/misc/" class="button {{ colorClass("facets/misc/") }} button--border"> 47 + <a href="kitchen/misc/" class="button {{ colorClass("kitchen/misc/") }} button--border"> 48 48 <span class="with-icon"> 49 49 <i class="ph-fill ph-treasure-chest"></i> 50 50 </span>
-45
src/_components/themes.vto
··· 1 - <ul> 2 - {{ for index, item of items }} 3 - <li data-uri="{{ item.url |> facetOrThemeURI }}" data-name="{{item.title}}"> 4 - <div style="position: relative;"> 5 - <a href="{{ item.url |> themeLoaderURL }}"> 6 - {{item.title}} 7 - </a> 8 - <button 9 - class="button--fixed button--transparent" 10 - popovertarget="theme-menu-{{id}}-{{index}}" 11 - style="anchor-name: --theme-anchor-{{id}}-{{index}}; position: absolute; right: 0; top: 50%; transform: translateY(-50%);" 12 - > 13 - <i class="ph-fill ph-dots-three-circle"></i> 14 - </button> 15 - </div> 16 - <div class="list-description"> 17 - {{item.desc |> md(true)}} 18 - </div> 19 - 20 - <!-- Dropdown Menu --> 21 - <div 22 - id="theme-menu-{{id}}-{{index}}" 23 - class="dropdown" 24 - style="position-anchor: --theme-anchor-{{id}}-{{index}}" 25 - popover 26 - > 27 - <a href="{{ item.url |> themeLoaderURL }}"> 28 - <span class="with-icon"> 29 - <i class="ph-fill ph-globe"></i> Open 30 - </span> 31 - </a> 32 - <a rel="save"> 33 - <span class="with-icon"> 34 - <i class="ph-fill ph-download"></i> Save 35 - </span> 36 - </a> 37 - <a rel="fork"> 38 - <span class="with-icon"> 39 - <i class="ph-fill ph-cursor-text"></i> Edit 40 - </span> 41 - </a> 42 - </div> 43 - </li> 44 - {{ /for }} 45 - </ul>
+1 -3
src/_data/facets.json
··· 41 41 "kind": "prelude", 42 42 "category": "Data", 43 43 "featured": true, 44 - "desc": "Process all your audio inputs automatically when opening any interface facet." 44 + "desc": "Process all your audio inputs automatically when opening any interface." 45 45 }, 46 46 { 47 47 "url": "facets/misc/scrobble/index.html", 48 48 "title": "Scrobble", 49 49 "kind": "prelude", 50 50 "category": "Misc", 51 - "featured": true, 52 51 "desc": "Enable scrobbling, keep track of what you're listening to." 53 52 }, 54 53 { 55 54 "url": "facets/misc/scrobble/last.fm/index.html", 56 55 "title": "Scrobble / Last.fm", 57 56 "category": "Misc", 58 - "featured": true, 59 57 "desc": "Enable Last.fm scrobbling." 60 58 }, 61 59 {
+1 -1
src/_includes/layouts/facets-category.vto src/_includes/layouts/kitchen-category.vto
··· 1 1 --- 2 - layout: layouts/facets.vto 2 + layout: layouts/kitchen.vto 3 3 --- 4 4 5 5 <section>
+2 -2
src/_includes/layouts/facets.vto src/_includes/layouts/kitchen.vto
··· 11 11 - vendor/@phosphor-icons/fill/style.css 12 12 13 13 scripts: 14 - - facets/common/ppr.js 14 + - kitchen/common/ppr.js 15 15 - common/pages/version-upgrade.js 16 16 --- 17 17 ··· 30 30 {{ await comp.diffuse.status() }} 31 31 </div> 32 32 <p class="construct dither-mask" style="margin-top: 0; max-width: none;"> 33 - Facets 33 + Kitchen 34 34 </p> 35 35 </div> 36 36 <div class="dither-mask filler filler--bg-twist-2"></div>
-35
src/definitions/output/theme.json
··· 1 - { 2 - "lexicon": 1, 3 - "id": "sh.diffuse.output.theme", 4 - "defs": { 5 - "main": { 6 - "type": "record", 7 - "record": { 8 - "type": "object", 9 - "required": ["id", "name"], 10 - "properties": { 11 - "id": { 12 - "type": "string", 13 - "description": "A unique identifier" 14 - }, 15 - "cid": { 16 - "type": "string", 17 - "description": "A DASL CID representing the UTF8 encoded HTML (raw 0x55 codec)" 18 - }, 19 - "createdAt": { "type": "string", "format": "datetime" }, 20 - "description": { "type": "string" }, 21 - "html": { 22 - "type": "string", 23 - "description": "The UTF8 HTML string that makes up the theme" 24 - }, 25 - "name": { "type": "string" }, 26 - "updatedAt": { "type": "string", "format": "datetime" }, 27 - "uri": { 28 - "type": "string", 29 - "description": "An optional URI that points at the theme; can be used to update this artifact" 30 - } 31 - } 32 - } 33 - } 34 - } 35 - }
+2 -2
src/facets/build.vto src/kitchen/build.vto
··· 1 1 --- 2 - layout: layouts/facets.vto 2 + layout: layouts/kitchen.vto 3 3 base: ../../ 4 - title: Build | Facets | Diffuse 4 + title: Build | Kitchen | Diffuse 5 5 6 6 examples: 7 7 - url: "facets/examples/now-playing/index.html"
+5 -4
src/facets/category.page.ts src/kitchen/category.page.ts
··· 5 5 desc: string; 6 6 } 7 7 8 - export const layout = "layouts/facets-category.vto"; 8 + export const layout = "layouts/kitchen-category.vto"; 9 9 10 10 export default function* ({ facets }: { facets: Facet[] }) { 11 - const categories = [...new Set(facets.map((f) => f.category))].sort() as string[]; 11 + const categories = [...new Set(facets.map((f) => f.category))] 12 + .sort() as string[]; 12 13 13 14 for (const category of categories) { 14 15 const slug = category.toLowerCase().replace(/\s+/g, "-"); 15 16 yield { 16 - url: `/facets/${slug}/`, 17 - title: `${category} | Facets | Diffuse`, 17 + url: `/kitchen/${slug}/`, 18 + title: `${category} | Kitchen | Diffuse`, 18 19 category, 19 20 slug, 20 21 categoryFacets: facets.filter((f) => f.category === category),
src/facets/common/build.js src/kitchen/common/build.js
src/facets/common/crud.js src/kitchen/common/crud.js
src/facets/common/grid.js src/kitchen/common/grid.js
src/facets/common/output.js src/kitchen/common/output.js
+6 -6
src/facets/common/ppr.js src/kitchen/common/ppr.js
··· 7 7 8 8 /** 9 9 * Strips the app's base path prefix from an absolute pathname, 10 - * returning a root-relative path like "/facets/build". 10 + * returning a root-relative path like "/kitchen/build". 11 11 * 12 12 * @param {string} pathname 13 13 */ ··· 29 29 await Grid.monitorToggleButtonStates(); 30 30 31 31 switch (path) { 32 - case "/facets/build": 32 + case "/kitchen/build": 33 33 Build.renderEditor(); 34 34 Build.handleBuildFormSubmit(); 35 35 Build.listenForExamplesEdit(); 36 36 await Build.editFacetFromURL(); 37 37 break; 38 - case "/facets/you": 38 + case "/kitchen/you": 39 39 await You.renderList(); 40 40 break; 41 41 default: ··· 45 45 46 46 initJsBasedOnPage(new URL(location.href)); 47 47 48 - // Partial page updates for facets navigation using the Navigation API. 48 + // Partial page updates for kitchen navigation using the Navigation API. 49 49 // Intercepts nav link clicks, fetches the new page, and swaps <main> content 50 50 // instead of doing a full page load. 51 51 ··· 63 63 const url = new URL(event.destination.url); 64 64 if (url.origin !== location.origin) return; 65 65 66 - // Only intercept /facets/[section]/ paths (not deeper sub-paths like /facets/misc/*) 66 + // Only intercept /kitchen/[section]/ paths (not deeper sub-paths like /kitchen/misc/*) 67 67 const relative = relativePathname(url.pathname); 68 68 const parts = relative.split("/").filter(Boolean); 69 - if (parts[0] !== "facets") return; 69 + if (parts[0] !== "kitchen") return; 70 70 if (parts.length > 2) return; 71 71 72 72 // Skip the loader page
+2 -2
src/facets/common/you.js src/kitchen/common/you.js
··· 40 40 <p> 41 41 <span> 42 42 You haven't saved anything yet. Add a facet by browsing the <a 43 - href="facets/" 43 + href="kitchen/" 44 44 >featured ones</a> or any of the other categories. You can click the toggle 45 45 to quickly add or remove from your collection. Alternatively, add one using 46 46 an URI: ··· 287 287 <a 288 288 class="button button--transparent" 289 289 title="Edit" 290 - href="facets/build/?id=${encodeURIComponent(c.id)}" 290 + href="kitchen/build/?id=${encodeURIComponent(c.id)}" 291 291 > 292 292 <i class="ph-fill ph-code-block"></i> 293 293 </a>
+2 -2
src/facets/guide.vto src/kitchen/guide.vto
··· 1 1 --- 2 - layout: layouts/facets.vto 2 + layout: layouts/kitchen.vto 3 3 base: ../../ 4 - title: Guide | Facets | Diffuse 4 + title: Guide | Kitchen | Diffuse 5 5 --- 6 6 7 7 <h1 hidden>Guide</h1>
+2 -2
src/facets/index.vto src/kitchen/index.vto
··· 1 1 --- 2 - layout: layouts/facets.vto 2 + layout: layouts/kitchen.vto 3 3 base: ../ 4 - title: Featured | Facets | Diffuse 4 + title: Featured | Kitchen | Diffuse 5 5 --- 6 6 7 7 <h1 hidden>Featured</h1>
src/facets/l/index.js src/kitchen/l/index.js
src/facets/l/index.vto src/kitchen/l/index.vto
+2 -2
src/facets/you.vto src/kitchen/you.vto
··· 1 1 --- 2 - layout: layouts/facets.vto 2 + layout: layouts/kitchen.vto 3 3 base: ../../ 4 - title: Your collection | Facets | Diffuse 4 + title: Your collection | Kitchen | Diffuse 5 5 --- 6 6 7 7 <h1 hidden>Your collection</h1>
+61 -115
src/index.vto
··· 193 193 desc: > 194 194 Used to track progress of (long) audio playback. 195 195 todo: true 196 - - title: "Output / Theme" 197 - desc: > 198 - Theme pointer or HTML snippet. 199 - url: "definitions/output/theme.json" 200 196 - title: "Output / Track" 201 197 desc: > 202 198 Represents audio that can be played, or a placeholder for a source of tracks. Contains a URI that will resolve to the audio. ··· 235 231 Your audio<br />your data<br />your rules 236 232 </p> 237 233 <p> 238 - Diffuse is a collection of components and software that make it possible to listen to audio from various sources on your devices and the web, and to create the ideal digital audio listening experience for you. 234 + Diffuse is cooperative and malleable software that makes it possible to listen to audio from various sources on your devices and the web, and to create the ideal digital audio listening experience for you. 239 235 </p> 240 236 <p style="align-items: center; display: flex; gap: var(--space-2xs); opacity: 0.55;"> 241 237 <i class="ph-fill ph-crane"></i> ··· 243 239 </p> 244 240 <ul class="table-of-contents"> 245 241 <li><a href="#usage">Usage</a></li> 246 - <li><a href="#themes">Themes</a></li> 247 - <li><a href="#facets">Facets</a></li> 248 - <li><a href="#agency">Agency</a></li> 249 - <li><a href="#elements">Elements</a></li> 242 + <li><a href="#developers">Developers</a></li> 250 243 <li><a href="#definitions">Definitions</a></li> 251 244 <li><a href="#links">Links</a></li> 252 245 </ul> ··· 264 257 <div class="columns"> 265 258 <div class="element"> 266 259 <p> 267 - The easiest way to start is by exploring the software. If you prefer a traditional pre&shy;packaged application approach, you can check out <a href="themes/">themes</a>. Themes can look and function entirely different from each other, so make sure to explore! 260 + <strong style="color: var(--accent)">Diffuse is not exactly your typical streaming service, we have to add sources of audio so we have stuff to play.</strong> This button below adds some demo content, so you can experiment with the software right away. 268 261 </p> 269 262 270 263 <p> 271 - Alternatively, there's <a href="facets/">facets</a> which allows you to use any component from any theme interchange&shy;ably, among pieces that are not in themes; each in a separate browser tab. Each tab talks to each other, so you can for example browse audio in one tab and play it in another. 264 + <button id="add-sample-content"> 265 + <span>Add sample content</span> 266 + </button> 272 267 </p> 273 268 </div> 274 269 275 270 <div class="element"> 276 271 <p> 277 - <strong style="color: var(--accent); font-weight: 700;">Diffuse is not your typical streaming service though, you have to add sources of audio.</strong> To start you can try out the demo by clicking the button below, or, go to a <a href="themes/">theme</a> or <a href="facets/">facet</a> that lets you add your audio input. 272 + If you do already have a place where you keep your audio files and want to connect it first thing, browse through all the various services that can be connected to Diffuse. 278 273 </p> 279 274 275 + <p><em>Look for "Connect ..."</em></p> 276 + 280 277 <p> 281 - <button id="add-sample-content"> 282 - <span>Add sample content</span> 283 - </button> 278 + <a class="button" href="kitchen/data/" target="_blank">Discover integrations</a> 284 279 </p> 285 280 </div> 286 281 </div> 287 - </section> 288 282 289 - <!-- THEMES & FACETS --> 290 - <div class="columns"> 291 - <section> 292 - <h2 id="themes">Themes</h2> 293 - 294 - <p> 295 - Themes each provide a traditional browser web application built on the Diffuse elements. They focus on delivering <strong>a great encompassing experience in a single window</strong>. They represent the opposite of facets, but can optionally delegate functionality to facets if they wish to do so. 296 - </p> 297 - 298 - <p> 299 - <a class="button button--alt" href="themes/">Explore</a> 300 - </p> 301 - </section> 302 - 303 - <section> 304 - <h2 id="facets">Facets</h2> 305 - 306 - <p> 307 - Facets are various user interfaces, with their own logic, each loaded in their own web page. Every used Diffuse component is configured so that it operates in broadcast mode, making all the pages communicate with each other. <strong>You choose the features you want in your software.</strong> 308 - </p> 309 - 310 - <p> 311 - <a class="button button--alt" href="facets/">Explore</a> 312 - </p> 313 - </section> 314 - </div> 283 + <div class="columns" style="margin-top: var(--space-xl)"> 284 + <div class="element"> 285 + <p> 286 + Great, one of the hardest parts is already done. Now we should explore what is possible with our audio. Because Diffuse is cooperative and malleable software, our interface can look like anything, and we can pick the features we like. That might sound overwhelming, so let's keep it simple for now. 287 + </p> 288 + </div> 315 289 316 - <!-- AGENCY --> 317 - <section> 318 - <h2 id="agency">Agency</h2> 290 + <div class="element"> 291 + <p> 292 + <strong>Let's pick an interface</strong> that automatically puts audio from our collection into the queue, and another to play what got put into the queue. 293 + </p> 319 294 320 - <p> 321 - The goal is for every user, no matter their knowledge level, to have agency over their data and their software. One can start with making small changes and gradually progress to making big changes. 322 - </p> 295 + <p> 296 + <span class="button-row"> 297 + <a class="button button--bg-twist-2" href="{{ ('facets/playback/auto-queue/index.html') |> facetLoaderURL }}" target="_blank"> 298 + <span class="with-icon"> 299 + <i class="ph-fill ph-number-circle-one"></i> 300 + Fill up queue 301 + </span> 302 + </a> 303 + <a class="button button--bg-twist-2" href="{{ ('themes/blur/artwork-controller/facet/index.html') |> facetLoaderURL }}" target="_blank"> 304 + <span class="with-icon"> 305 + <i class="ph-fill ph-number-circle-two"></i> 306 + Play audio 307 + </span> 308 + </a> 309 + </span> 310 + </p> 311 + </div> 312 + </div> 323 313 324 - <p> 325 - You can store your user-data in various places, and easily export, import and sync it. 326 - </p> 314 + <div class="columns" style="margin-top: var(--space-xl)"> 315 + <div class="element"> 316 + <p> 317 + <em>So you said I could pick the features and interfaces that I liked, how does that work?</em> 318 + </p> 327 319 328 - <h3>Take control</h3> 320 + <p> 321 + To do that, we have to visit our <strong style="color: var(--accent-twist-4)">kitchen</strong>. There you'll be able to browse through all the features and interfaces that are provided by Diffuse. To use a feature, you click the toggle to enable it, this will add it to your software. Interfaces can be added too, but it's not required, you can try them out right away by clicking the link in their title. 322 + </p> 329 323 330 - <ul class="columns"> 331 - <div class="element"> 332 - <!-- 1 --> 333 - <li> 334 - <p> 335 - <i class="ph-fill ph-storefront"></i> <strong>Level 1</strong>: Pick your restaurant, food comes in all shapes and sizes. The equivalent of choosing a Diffuse <a href="themes/">theme</a>. 336 - </p> 337 - </li> 338 - <!-- 2 --> 339 - <li> 340 - <p> 341 - <i class="ph-fill ph-basket"></i> <strong>Level 2</strong>: Take out food from various places, eg. cheese shop + bakery. You choose how you combine the foods and from where you order them. That's <a href="facets/">facets</a>. 342 - </p> 343 - </li> 344 - <!-- 3 --> 345 - <li> 346 - <p> 347 - <i class="ph-fill ph-pepper"></i> <strong>Level 3</strong>: Now that you know which food is good and how to make combinations, you might make a slight customization, add a little something of your own (eg. add some spice). However, you're not quite confident enough which spice to pick, so you hire some help. 348 - </p> 349 - <p> 350 - This can be done using the <a href="facets/#builder">facets builder</a> which allows you to build on top of a familiar preconfigured foundation and load custom facets. People might share their own, or maybe you use an LLM to generate something for you (eg. an album art gallery). 351 - </p> 352 - </li> 353 - <!-- 4 --> 354 - <li> 355 - <p> 356 - <i class="ph-fill ph-knife"></i> <strong>Level 4</strong>: You learned a bit from watching and talking to the help you hired, so you decide to take things in your own hands. 357 - </p> 358 - <p> 359 - You continue to use the <a href="facets/#builder">facets builder</a> but learn a bit of <a href="https://htmlforpeople.com">HTML</a>, <a href="https://javascript.info">Javascript</a> and <a href="https://htmlforpeople.com/css-basics/">CSS</a>; so you're able to write your own facet. 360 - </p> 361 - </li> 324 + <p> 325 + <a class="button button--bg-twist-4" href="kitchen/" target="_blank">Explore the kitchen</a> 326 + </p> 362 327 </div> 328 + 363 329 <div class="element"> 364 - <!-- 5 --> 365 - <li> 366 - <p> 367 - <i class="ph-fill ph-cooking-pot"></i> <strong>Level 5</strong>: At this point you're confident enough to make a meal from scratch. You can start very simple, eg. just throwing a steak in the pan with some butter and some salt to it. Then later add some baked potatoes and go from there. 368 - </p> 369 - <p> 370 - A similar tool comes into play here, the <a href="themes/#builder">themes builder</a>. Same concept as the facets builder, but now you need to specify the foundation yourself. You can use the <a href="#elements">elements</a> listed below to do so. The code for these is available from this website or through the <a href="https://jsr.io/@toko/diffuse">Javascript package</a>. 371 - </p> 372 - </li> 373 - <!-- 6 --> 374 - <li> 375 - <p> 376 - <i class="ph-fill ph-storefront"></i> <strong>Level 6</strong>: You open your own restaurant. 377 - </p> 378 - <p> 379 - You can host the theme you made on any web server, it's only HTML after all. Only difference is that you'll have to create the entire HTML tree, not just the body element, as is the case with the theme builder. 380 - </p> 381 - </li> 382 - <!-- 7 --> 383 - <li> 384 - <p> 385 - <i class="ph-fill ph-chef-hat"></i> <strong>Level 7</strong>: You got promoted to master chef. Time to open your own restaurant chain. 386 - </p> 387 - <p> 388 - You can self-host Diffuse, it's <a href="https://tangled.org/tokono.ma/diffuse/blob/v4/">open-source</a>! Or you present your own collection of elements. 389 - </p> 390 - </li> 330 + <p> 331 + <em>What is a feature exactly?</em> 332 + </p> 333 + 334 + <p> 335 + A <strong style="color: var(--accent-twist-4)">feature</strong> is a piece of code that expands the capabilities of your software or that makes it behave in a certain kind of way. It runs each time you open an interface, but may not necessarily be activated. 336 + </p> 391 337 </div> 392 - </ul> 338 + </div> 393 339 </section> 394 340 395 341 <!-- ELEMENTS --> 396 342 <section> 397 - <h2 id="elements">Elements</h2> 343 + <h2 id="developers">Developers</h2> 398 344 399 345 <p> 400 - The (web) components of the system. These custom elements are then recombined into an entire music player and browser, or whatever you want to build. 346 + If you're a programmer, you can use the (web) components of the system. These custom elements can be combined into an entire music player and browser, or whatever you want to build. 401 347 </p> 402 348 403 349 <p> 404 - Consume these using the facets <a href="facets/#builder">builder</a>, the Javascript <a href="https://jsr.io/@toko/diffuse">package</a>, or the linked Javascript files down below. 350 + Consume these using the kitchen <a href="facets/#builder">build tool</a>, the Javascript <a href="https://jsr.io/@toko/diffuse">package</a>, or the linked Javascript files down below. 405 351 </p> 406 352 407 353 <div class="columns">