@social.io/catalog 2.0.0 → 2.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.
@@ -0,0 +1,393 @@
1
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
2
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
3
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
4
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
5
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
6
+ var _, done = false;
7
+ for (var i = decorators.length - 1; i >= 0; i--) {
8
+ var context = {};
9
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
10
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
11
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
12
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
13
+ if (kind === "accessor") {
14
+ if (result === void 0) continue;
15
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
16
+ if (_ = accept(result.get)) descriptor.get = _;
17
+ if (_ = accept(result.set)) descriptor.set = _;
18
+ if (_ = accept(result.init)) initializers.unshift(_);
19
+ }
20
+ else if (_ = accept(result)) {
21
+ if (kind === "field") initializers.unshift(_);
22
+ else descriptor[key] = _;
23
+ }
24
+ }
25
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
26
+ done = true;
27
+ };
28
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
29
+ var useValue = arguments.length > 2;
30
+ for (var i = 0; i < initializers.length; i++) {
31
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
32
+ }
33
+ return useValue ? value : void 0;
34
+ };
35
+ import { DeesElement, css, customElement, html, property, } from '@design.estate/dees-element';
36
+ import { SioLogoRenderer, sioLogoAspect } from './sio-logo-render.js';
37
+ import { sioElementStyles } from './tokens.js';
38
+ /**
39
+ * The social.io faceted S brand mark from the v8 design prototype.
40
+ *
41
+ * The canvas renderer preserves the exact eight-facet geometry and supports
42
+ * entrance, hover-wave, dismiss, and loading animations. Motion is disabled
43
+ * when the visitor requests reduced motion.
44
+ */
45
+ let SioLogo = (() => {
46
+ let _classDecorators = [customElement('sio-logo')];
47
+ let _classDescriptor;
48
+ let _classExtraInitializers = [];
49
+ let _classThis;
50
+ let _classSuper = DeesElement;
51
+ let _size_decorators;
52
+ let _size_initializers = [];
53
+ let _size_extraInitializers = [];
54
+ let _background_decorators;
55
+ let _background_initializers = [];
56
+ let _background_extraInitializers = [];
57
+ let _gap_decorators;
58
+ let _gap_initializers = [];
59
+ let _gap_extraInitializers = [];
60
+ let _radius_decorators;
61
+ let _radius_initializers = [];
62
+ let _radius_extraInitializers = [];
63
+ let _square_decorators;
64
+ let _square_initializers = [];
65
+ let _square_extraInitializers = [];
66
+ let _mono_decorators;
67
+ let _mono_initializers = [];
68
+ let _mono_extraInitializers = [];
69
+ let _theme_decorators;
70
+ let _theme_initializers = [];
71
+ let _theme_extraInitializers = [];
72
+ let _loading_decorators;
73
+ let _loading_initializers = [];
74
+ let _loading_extraInitializers = [];
75
+ let _noEntrance_decorators;
76
+ let _noEntrance_initializers = [];
77
+ let _noEntrance_extraInitializers = [];
78
+ let _noHover_decorators;
79
+ let _noHover_initializers = [];
80
+ let _noHover_extraInitializers = [];
81
+ var SioLogo = class extends _classSuper {
82
+ static { _classThis = this; }
83
+ static {
84
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
85
+ _size_decorators = [property({ type: Number })];
86
+ _background_decorators = [property({ type: String })];
87
+ _gap_decorators = [property({ type: Number })];
88
+ _radius_decorators = [property({ type: Number })];
89
+ _square_decorators = [property({ type: Boolean })];
90
+ _mono_decorators = [property({ type: String })];
91
+ _theme_decorators = [property({ type: String })];
92
+ _loading_decorators = [property({ type: Boolean, reflect: true })];
93
+ _noEntrance_decorators = [property({ type: Boolean, attribute: 'no-entrance' })];
94
+ _noHover_decorators = [property({ type: Boolean, attribute: 'no-hover' })];
95
+ __esDecorate(this, null, _size_decorators, { kind: "accessor", name: "size", static: false, private: false, access: { has: obj => "size" in obj, get: obj => obj.size, set: (obj, value) => { obj.size = value; } }, metadata: _metadata }, _size_initializers, _size_extraInitializers);
96
+ __esDecorate(this, null, _background_decorators, { kind: "accessor", name: "background", static: false, private: false, access: { has: obj => "background" in obj, get: obj => obj.background, set: (obj, value) => { obj.background = value; } }, metadata: _metadata }, _background_initializers, _background_extraInitializers);
97
+ __esDecorate(this, null, _gap_decorators, { kind: "accessor", name: "gap", static: false, private: false, access: { has: obj => "gap" in obj, get: obj => obj.gap, set: (obj, value) => { obj.gap = value; } }, metadata: _metadata }, _gap_initializers, _gap_extraInitializers);
98
+ __esDecorate(this, null, _radius_decorators, { kind: "accessor", name: "radius", static: false, private: false, access: { has: obj => "radius" in obj, get: obj => obj.radius, set: (obj, value) => { obj.radius = value; } }, metadata: _metadata }, _radius_initializers, _radius_extraInitializers);
99
+ __esDecorate(this, null, _square_decorators, { kind: "accessor", name: "square", static: false, private: false, access: { has: obj => "square" in obj, get: obj => obj.square, set: (obj, value) => { obj.square = value; } }, metadata: _metadata }, _square_initializers, _square_extraInitializers);
100
+ __esDecorate(this, null, _mono_decorators, { kind: "accessor", name: "mono", static: false, private: false, access: { has: obj => "mono" in obj, get: obj => obj.mono, set: (obj, value) => { obj.mono = value; } }, metadata: _metadata }, _mono_initializers, _mono_extraInitializers);
101
+ __esDecorate(this, null, _theme_decorators, { kind: "accessor", name: "theme", static: false, private: false, access: { has: obj => "theme" in obj, get: obj => obj.theme, set: (obj, value) => { obj.theme = value; } }, metadata: _metadata }, _theme_initializers, _theme_extraInitializers);
102
+ __esDecorate(this, null, _loading_decorators, { kind: "accessor", name: "loading", static: false, private: false, access: { has: obj => "loading" in obj, get: obj => obj.loading, set: (obj, value) => { obj.loading = value; } }, metadata: _metadata }, _loading_initializers, _loading_extraInitializers);
103
+ __esDecorate(this, null, _noEntrance_decorators, { kind: "accessor", name: "noEntrance", static: false, private: false, access: { has: obj => "noEntrance" in obj, get: obj => obj.noEntrance, set: (obj, value) => { obj.noEntrance = value; } }, metadata: _metadata }, _noEntrance_initializers, _noEntrance_extraInitializers);
104
+ __esDecorate(this, null, _noHover_decorators, { kind: "accessor", name: "noHover", static: false, private: false, access: { has: obj => "noHover" in obj, get: obj => obj.noHover, set: (obj, value) => { obj.noHover = value; } }, metadata: _metadata }, _noHover_initializers, _noHover_extraInitializers);
105
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
106
+ SioLogo = _classThis = _classDescriptor.value;
107
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
108
+ }
109
+ static demo = () => html `
110
+ <div style="display:flex;align-items:center;gap:32px;padding:24px;background:#101012;">
111
+ <sio-logo size="120" theme="dark"></sio-logo>
112
+ <sio-logo size="120" square background="#556270" radius="22" theme="dark"></sio-logo>
113
+ <sio-logo size="120" loading theme="dark"></sio-logo>
114
+ <sio-logo size="120" mono="#ffffff" no-entrance theme="dark"></sio-logo>
115
+ </div>
116
+ `;
117
+ #size_accessor_storage = __runInitializers(this, _size_initializers, 40);
118
+ /** rendered height in CSS pixels; tight-crop width follows the brand aspect */
119
+ get size() { return this.#size_accessor_storage; }
120
+ set size(value) { this.#size_accessor_storage = value; }
121
+ #background_accessor_storage = (__runInitializers(this, _size_extraInitializers), __runInitializers(this, _background_initializers, 'transparent'));
122
+ get background() { return this.#background_accessor_storage; }
123
+ set background(value) { this.#background_accessor_storage = value; }
124
+ #gap_accessor_storage = (__runInitializers(this, _background_extraInitializers), __runInitializers(this, _gap_initializers, 2));
125
+ /** inward inset per facet, in 500px design-grid units */
126
+ get gap() { return this.#gap_accessor_storage; }
127
+ set gap(value) { this.#gap_accessor_storage = value; }
128
+ #radius_accessor_storage = (__runInitializers(this, _gap_extraInitializers), __runInitializers(this, _radius_initializers, 16));
129
+ /** facet corner radius, in 500px design-grid units */
130
+ get radius() { return this.#radius_accessor_storage; }
131
+ set radius(value) { this.#radius_accessor_storage = value; }
132
+ #square_accessor_storage = (__runInitializers(this, _radius_extraInitializers), __runInitializers(this, _square_initializers, false));
133
+ /** render on a square tile instead of the tight S crop */
134
+ get square() { return this.#square_accessor_storage; }
135
+ set square(value) { this.#square_accessor_storage = value; }
136
+ #mono_accessor_storage = (__runInitializers(this, _square_extraInitializers), __runInitializers(this, _mono_initializers, ''));
137
+ /** collapse the palette to one color while retaining facet depth */
138
+ get mono() { return this.#mono_accessor_storage; }
139
+ set mono(value) { this.#mono_accessor_storage = value; }
140
+ #theme_accessor_storage = (__runInitializers(this, _mono_extraInitializers), __runInitializers(this, _theme_initializers, 'auto'));
141
+ /** backdrop palette; auto follows the nearest opaque surface */
142
+ get theme() { return this.#theme_accessor_storage; }
143
+ set theme(value) { this.#theme_accessor_storage = value; }
144
+ #loading_accessor_storage = (__runInitializers(this, _theme_extraInitializers), __runInitializers(this, _loading_initializers, false));
145
+ get loading() { return this.#loading_accessor_storage; }
146
+ set loading(value) { this.#loading_accessor_storage = value; }
147
+ #noEntrance_accessor_storage = (__runInitializers(this, _loading_extraInitializers), __runInitializers(this, _noEntrance_initializers, false));
148
+ get noEntrance() { return this.#noEntrance_accessor_storage; }
149
+ set noEntrance(value) { this.#noEntrance_accessor_storage = value; }
150
+ #noHover_accessor_storage = (__runInitializers(this, _noEntrance_extraInitializers), __runInitializers(this, _noHover_initializers, false));
151
+ get noHover() { return this.#noHover_accessor_storage; }
152
+ set noHover(value) { this.#noHover_accessor_storage = value; }
153
+ static styles = [
154
+ ...sioElementStyles,
155
+ css `
156
+ :host {
157
+ display: inline-flex;
158
+ flex: none;
159
+ line-height: 0;
160
+ }
161
+ canvas {
162
+ display: block;
163
+ }
164
+ `,
165
+ ];
166
+ renderer = (__runInitializers(this, _noHover_extraInitializers), null);
167
+ themeObserver = null;
168
+ colorSchemeMedia = null;
169
+ reducedMotionMedia = null;
170
+ lastDevicePixelRatio = 0;
171
+ lifecycleGeneration = 0;
172
+ handlePointerEnter = () => {
173
+ if (!this.noHover && !this.loading && !this.prefersReducedMotion())
174
+ this.wave();
175
+ };
176
+ handleAmbientChange = () => {
177
+ this.syncRenderer(this.loading ? 'loading' : null);
178
+ };
179
+ handleReducedMotionChange = () => {
180
+ this.syncRenderer(this.loading ? 'loading' : null);
181
+ };
182
+ handleResize = () => {
183
+ const currentDevicePixelRatio = window.devicePixelRatio || 1;
184
+ if (currentDevicePixelRatio === this.lastDevicePixelRatio)
185
+ return;
186
+ this.syncRenderer(this.loading ? 'loading' : null);
187
+ };
188
+ async connectedCallback() {
189
+ const generation = ++this.lifecycleGeneration;
190
+ const connection = super.connectedCallback();
191
+ this.ensureAccessibleHost();
192
+ this.addEventListener('mouseenter', this.handlePointerEnter);
193
+ window.addEventListener('resize', this.handleResize);
194
+ this.observeReducedMotion();
195
+ await connection;
196
+ if (!this.isConnected || generation !== this.lifecycleGeneration)
197
+ return;
198
+ if (this.hasUpdated) {
199
+ this.observeAmbientTheme();
200
+ this.syncRenderer(this.loading ? 'loading' : null);
201
+ }
202
+ }
203
+ async disconnectedCallback() {
204
+ const generation = ++this.lifecycleGeneration;
205
+ this.cleanupOwnedResources();
206
+ await super.disconnectedCallback();
207
+ if (!this.isConnected && generation === this.lifecycleGeneration) {
208
+ this.cleanupOwnedResources();
209
+ }
210
+ }
211
+ cleanupOwnedResources() {
212
+ this.removeEventListener('mouseenter', this.handlePointerEnter);
213
+ window.removeEventListener('resize', this.handleResize);
214
+ this.stopAmbientThemeObservation();
215
+ this.stopReducedMotionObservation();
216
+ this.renderer?.stop();
217
+ }
218
+ render() {
219
+ const height = this.normalizedSize;
220
+ const width = this.square ? height : Math.round(height * sioLogoAspect);
221
+ return html `<canvas aria-hidden="true" style="width:${width}px;height:${height}px"></canvas>`;
222
+ }
223
+ firstUpdated(changedProperties) {
224
+ super.firstUpdated(changedProperties);
225
+ const canvas = this.shadowRoot?.querySelector('canvas');
226
+ const context = canvas?.getContext('2d');
227
+ if (!context)
228
+ return;
229
+ this.renderer = new SioLogoRenderer(context, this.getRendererOptions());
230
+ if (!this.isConnected) {
231
+ this.renderer.drawStatic();
232
+ return;
233
+ }
234
+ this.observeAmbientTheme();
235
+ if (this.loading && !this.prefersReducedMotion())
236
+ this.renderer.start('loading');
237
+ else if (!this.noEntrance && !this.prefersReducedMotion())
238
+ this.renderer.start('in');
239
+ else
240
+ this.renderer.drawStatic();
241
+ }
242
+ updated(changedProperties) {
243
+ if (!this.isConnected) {
244
+ this.stopAmbientThemeObservation();
245
+ this.renderer?.stop();
246
+ return;
247
+ }
248
+ const redrawProperties = [
249
+ 'size',
250
+ 'gap',
251
+ 'radius',
252
+ 'square',
253
+ 'background',
254
+ 'mono',
255
+ 'theme',
256
+ ];
257
+ if (redrawProperties.some((propertyName) => changedProperties.has(propertyName))) {
258
+ this.syncRenderer(this.loading ? 'loading' : null);
259
+ }
260
+ if (changedProperties.has('theme')) {
261
+ this.stopAmbientThemeObservation();
262
+ this.observeAmbientTheme();
263
+ }
264
+ if (changedProperties.has('loading')) {
265
+ this.syncRenderer(this.loading ? 'loading' : null);
266
+ }
267
+ }
268
+ themeChanged() {
269
+ this.syncRenderer(this.loading ? 'loading' : null);
270
+ }
271
+ play() {
272
+ if (!this.renderer || !this.isConnected)
273
+ return;
274
+ if (this.prefersReducedMotion())
275
+ this.renderer.drawStatic();
276
+ else
277
+ this.renderer.start('in');
278
+ }
279
+ wave() {
280
+ if (!this.renderer || !this.isConnected)
281
+ return;
282
+ if (this.prefersReducedMotion())
283
+ this.renderer.drawStatic();
284
+ else
285
+ this.renderer.start('wave');
286
+ }
287
+ dismiss() {
288
+ if (!this.renderer || !this.isConnected)
289
+ return;
290
+ if (this.prefersReducedMotion())
291
+ this.renderer.clear();
292
+ else
293
+ this.renderer.start('out');
294
+ }
295
+ get normalizedSize() {
296
+ return Number.isFinite(this.size) ? Math.max(1, this.size) : 40;
297
+ }
298
+ getRendererOptions() {
299
+ this.lastDevicePixelRatio = window.devicePixelRatio || 1;
300
+ return {
301
+ size: this.normalizedSize,
302
+ dpr: this.lastDevicePixelRatio,
303
+ gap: Number.isFinite(this.gap) ? Math.max(0, this.gap) : 2,
304
+ radius: Number.isFinite(this.radius) ? Math.max(0, this.radius) : 16,
305
+ square: this.square,
306
+ background: this.background,
307
+ mono: this.mono,
308
+ light: this.isLightBackdrop(),
309
+ };
310
+ }
311
+ syncRenderer(animation = null) {
312
+ if (!this.renderer)
313
+ return;
314
+ this.renderer.stop();
315
+ this.renderer.setOptions(this.getRendererOptions());
316
+ if (animation && this.isConnected && !this.prefersReducedMotion()) {
317
+ this.renderer.start(animation);
318
+ }
319
+ else
320
+ this.renderer.drawStatic();
321
+ }
322
+ prefersReducedMotion() {
323
+ return this.reducedMotionMedia?.matches ??
324
+ window.matchMedia?.('(prefers-reduced-motion: reduce)').matches ??
325
+ false;
326
+ }
327
+ isLightBackdrop() {
328
+ if (this.theme === 'light')
329
+ return true;
330
+ if (this.theme === 'dark')
331
+ return false;
332
+ let element = this;
333
+ while (element) {
334
+ const color = getComputedStyle(element).backgroundColor;
335
+ const match = color.match(/rgba?\(\s*([\d.]+)[,\s]+([\d.]+)[,\s]+([\d.]+)(?:\s*[,/]\s*([\d.]+))?\s*\)/);
336
+ if (match) {
337
+ const alpha = match[4] === undefined ? 1 : Number.parseFloat(match[4]);
338
+ if (alpha > 0.2) {
339
+ const luminance = (0.2126 * Number(match[1]) +
340
+ 0.7152 * Number(match[2]) +
341
+ 0.0722 * Number(match[3])) /
342
+ 255;
343
+ return luminance > 0.55;
344
+ }
345
+ }
346
+ const root = element.getRootNode();
347
+ element = element.parentElement || (root instanceof ShadowRoot ? root.host : null);
348
+ }
349
+ return window.matchMedia?.('(prefers-color-scheme: light)').matches ?? false;
350
+ }
351
+ observeAmbientTheme() {
352
+ if (this.theme !== 'auto' || this.themeObserver)
353
+ return;
354
+ this.themeObserver = new MutationObserver(this.handleAmbientChange);
355
+ this.themeObserver.observe(document.documentElement, {
356
+ attributes: true,
357
+ attributeFilter: ['data-sio-theme', 'data-theme', 'class', 'style'],
358
+ });
359
+ this.colorSchemeMedia = window.matchMedia?.('(prefers-color-scheme: light)') ?? null;
360
+ this.colorSchemeMedia?.addEventListener('change', this.handleAmbientChange);
361
+ }
362
+ stopAmbientThemeObservation() {
363
+ this.themeObserver?.disconnect();
364
+ this.themeObserver = null;
365
+ this.colorSchemeMedia?.removeEventListener('change', this.handleAmbientChange);
366
+ this.colorSchemeMedia = null;
367
+ }
368
+ observeReducedMotion() {
369
+ if (this.reducedMotionMedia)
370
+ return;
371
+ this.reducedMotionMedia = window.matchMedia?.('(prefers-reduced-motion: reduce)') ?? null;
372
+ this.reducedMotionMedia?.addEventListener('change', this.handleReducedMotionChange);
373
+ }
374
+ stopReducedMotionObservation() {
375
+ this.reducedMotionMedia?.removeEventListener('change', this.handleReducedMotionChange);
376
+ this.reducedMotionMedia = null;
377
+ }
378
+ ensureAccessibleHost() {
379
+ if (this.hasAttribute('aria-hidden'))
380
+ return;
381
+ if (!this.hasAttribute('role'))
382
+ this.setAttribute('role', 'img');
383
+ if (!this.hasAttribute('aria-label'))
384
+ this.setAttribute('aria-label', 'social.io');
385
+ }
386
+ static {
387
+ __runInitializers(_classThis, _classExtraInitializers);
388
+ }
389
+ };
390
+ return SioLogo = _classThis;
391
+ })();
392
+ export { SioLogo };
393
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lvLWxvZ28uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90c193ZWIvZWxlbWVudHMvc2lvLWxvZ28udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLE9BQU8sRUFDTCxXQUFXLEVBQ1gsR0FBRyxFQUNILGFBQWEsRUFDYixJQUFJLEVBQ0osUUFBUSxHQUVULE1BQU0sNkJBQTZCLENBQUM7QUFDckMsT0FBTyxFQUFFLGVBQWUsRUFBRSxhQUFhLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUN0RSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFVL0M7Ozs7OztHQU1HO0lBRVUsT0FBTzs0QkFEbkIsYUFBYSxDQUFDLFVBQVUsQ0FBQzs7OztzQkFDRyxXQUFXOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O3VCQUFuQixTQUFRLFdBQVc7Ozs7Z0NBV3JDLFFBQVEsQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsQ0FBQztzQ0FHMUIsUUFBUSxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxDQUFDOytCQUkxQixRQUFRLENBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLENBQUM7a0NBSTFCLFFBQVEsQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsQ0FBQztrQ0FJMUIsUUFBUSxDQUFDLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxDQUFDO2dDQUkzQixRQUFRLENBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLENBQUM7aUNBSTFCLFFBQVEsQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsQ0FBQzttQ0FHMUIsUUFBUSxDQUFDLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUM7c0NBRzFDLFFBQVEsQ0FBQyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLGFB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
@@ -21,8 +21,8 @@ export interface ISioTabChangeDetail {
21
21
  *
22
22
  * A liquid-glass bar (blur 28px saturate 180%, 0.5px top hairline) with one
23
23
  * flex-equal tab per channel: 22px icon over a 10.5px label. The active tab
24
- * lights up in its channel color; 30px bottom padding clears the iOS home
25
- * indicator. Selecting a tab dispatches `tab-change` with `{ id, channel }`
24
+ * lights up in its channel color; safe-area-aware bottom padding clears the
25
+ * iOS home indicator. Selecting a tab dispatches `tab-change` with `{ id, channel }`
26
26
  * (bubbles, composed).
27
27
  */
28
28
  export declare class SioTabBar extends DeesElement {
@@ -58,8 +58,8 @@ const calendarChannel = {
58
58
  *
59
59
  * A liquid-glass bar (blur 28px saturate 180%, 0.5px top hairline) with one
60
60
  * flex-equal tab per channel: 22px icon over a 10.5px label. The active tab
61
- * lights up in its channel color; 30px bottom padding clears the iOS home
62
- * indicator. Selecting a tab dispatches `tab-change` with `{ id, channel }`
61
+ * lights up in its channel color; safe-area-aware bottom padding clears the
62
+ * iOS home indicator. Selecting a tab dispatches `tab-change` with `{ id, channel }`
63
63
  * (bubbles, composed).
64
64
  */
65
65
  let SioTabBar = (() => {
@@ -139,7 +139,7 @@ let SioTabBar = (() => {
139
139
  /* toolbar glass, hairline on the top edge (the bar sits at the bottom) */
140
140
  .bar {
141
141
  display: flex;
142
- padding: 8px 0 30px; /* 30px clears the iOS home indicator */
142
+ padding: 8px 0 max(30px, var(--sio-safe-area-bottom, env(safe-area-inset-bottom, 0px)));
143
143
  background: var(--sio-toolbar-glass-bg);
144
144
  backdrop-filter: blur(28px) saturate(180%);
145
145
  -webkit-backdrop-filter: blur(28px) saturate(180%);
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@social.io/catalog",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "private": false,
5
- "description": "v7 Apple-native design system and web components for social.io",
5
+ "description": "Apple-native v8 design system and web components for social.io",
6
6
  "exports": {
7
7
  ".": "./dist_ts_web/index.js"
8
8
  },
@@ -16,11 +16,11 @@
16
16
  },
17
17
  "devDependencies": {
18
18
  "@git.zone/tsbuild": "^4.4.2",
19
- "@git.zone/tsbundle": "^2.10.0",
19
+ "@git.zone/tsbundle": "^2.11.2",
20
20
  "@git.zone/tsrun": "^2.0.5",
21
21
  "@git.zone/tstest": "^3.6.6",
22
- "@git.zone/tswatch": "^3.3.2",
23
- "@types/node": "^26.1.0",
22
+ "@git.zone/tswatch": "^3.3.5",
23
+ "@types/node": "^26.1.1",
24
24
  "@design.estate/dees-wcctools": "^3.9.0"
25
25
  },
26
26
  "files": [
package/readme.hints.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @social.io/catalog — hints
2
2
 
3
- ## v2 architecture (v7 design program)
3
+ ## v2 architecture (v8 design program)
4
4
 
5
5
  - Pure web-component catalog: Lit via `@design.estate/dees-element` with
6
6
  standard TC39 decorators (`@property({ ... }) public accessor x`,
@@ -8,7 +8,7 @@
8
8
  media-recorder stack was removed.
9
9
  - Every element: `@customElement('sio-...')`, a
10
10
  `declare global { interface HTMLElementTagNameMap }` entry, a
11
- `public static demo = () => html\`...\`` with realistic v7 content, and
11
+ `public static demo = () => html\`...\`` with realistic v8 content, and
12
12
  `static styles = [...sioElementStyles, css\`...\`]`.
13
13
  - Entry points:
14
14
  - `ts_web/index.ts` → re-exports `ts_web/elements/index.ts` (the barrel:
@@ -54,9 +54,10 @@
54
54
  - Icons: `sio-icon` is a thin wrapper over the `lucide` npm package
55
55
  (never a CDN), with a small alias map (e.g. `envelope` → `mail`).
56
56
 
57
- ## Component inventory (27 files / 28 elements)
57
+ ## Component inventory (28 files / 29 elements)
58
58
 
59
- Foundation: `sio-icon`, `sio-button`, `sio-kbd`, `sio-chip`
59
+ Foundation: `sio-logo` (faceted canvas mark, theme/DPR/reduced-motion aware),
60
+ `sio-icon`, `sio-button`, `sio-kbd`, `sio-chip`
60
61
  (channel/lane/status palettes), `sio-avatar` + `sio-avatar-stack`,
61
62
  `sio-unread-badge`.
62
63
 
package/readme.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @social.io/catalog
2
2
 
3
- The social.io v7 design system and web component library: Apple-native Lit components for the unified-inbox product family — feed rows, channel navigation, command palette, media primitives, and the embeddable chat-widget suite. Built on [@design.estate/dees-element](https://www.npmjs.com/package/@design.estate/dees-element) (Lit 3, standard TC39 decorators) with a CSS-custom-property token system and full light/dark theming.
3
+ The social.io v8 design system and web component library: Apple-native Lit components for the unified-inbox product family — the faceted social.io brand mark, feed rows, channel navigation, command palette, media primitives, and the embeddable chat-widget suite. Built on [@design.estate/dees-element](https://www.npmjs.com/package/@design.estate/dees-element) (Lit 3, standard TC39 decorators) with a CSS-custom-property token system and full light/dark theming.
4
4
 
5
5
  ## Issue Reporting and Security
6
6
 
@@ -14,7 +14,8 @@ pnpm add @social.io/catalog
14
14
 
15
15
  ## Design System
16
16
 
17
- Every component draws exclusively from the token layer in `tokens.ts`:
17
+ Product UI components draw from the token layer in `tokens.ts`; `sio-logo`
18
+ preserves the canonical v8 facet palette as brand artwork:
18
19
 
19
20
  - **Semantic surfaces** — `--sio-bg`, `--sio-surface`, `--sio-surface-2`, four label levels, and 0.5px hairline separators, switching between iOS-style light (`#F2F2F7`/`#FFFFFF`) and true-black dark (`#000`/`#1C1C1E`).
20
21
  - **Tint** — `--sio-tint` `#0A84FF`, deliberately brightened to `#409CFF` in dark mode, with hover and soft (translucent) variants.
@@ -42,10 +43,19 @@ public static styles = [
42
43
 
43
44
  Components auto-register as custom elements on import.
44
45
 
46
+ ```typescript
47
+ import '@social.io/catalog';
48
+ ```
49
+
50
+ ```html
51
+ <sio-logo size="30" theme="auto" no-entrance></sio-logo>
52
+ ```
53
+
45
54
  ### Foundation
46
55
 
47
56
  | Element | Purpose |
48
57
  | --- | --- |
58
+ | `sio-logo` | Faceted social.io S mark with tight/square layouts, palette modes, and reduced-motion-aware animations |
49
59
  | `sio-icon` | Lucide icon renderer (`icon`, `size`, `color`, `strokeWidth`) |
50
60
  | `sio-button` | Primary / secondary / destructive / outline / ghost variants, sm–lg sizes, status spinner |
51
61
  | `sio-avatar` / `sio-avatar-stack` | Initials-on-tint circles with presence dot, channel badge, overlapping stacks |
@@ -53,6 +63,24 @@ Components auto-register as custom elements on import.
53
63
  | `sio-unread-badge` | Count pills in channel colors, rail-sized variant |
54
64
  | `sio-kbd` | Keyboard-shortcut hint chip (mono, hairline border) |
55
65
 
66
+ #### `sio-logo`
67
+
68
+ | Property | Default | Purpose |
69
+ | --- | --- | --- |
70
+ | `size` | `40` | Mark height in CSS pixels; tight-crop width follows the brand aspect ratio |
71
+ | `background` | `transparent` | Canvas background color |
72
+ | `gap` | `2` | Inset between facets in the 500px design grid |
73
+ | `radius` | `16` | Facet corner radius in the 500px design grid |
74
+ | `square` | `false` | Render on a square tile instead of the tight S crop |
75
+ | `mono` | empty | Use one color while retaining facet depth |
76
+ | `theme` | `auto` | Select `auto`, `light`, or `dark` backdrop palette behavior |
77
+ | `loading` | `false` | Run the looping loading treatment |
78
+ | `no-entrance` | `false` | Disable the entrance animation |
79
+ | `no-hover` | `false` | Disable the pointer wave animation |
80
+
81
+ The public `play()`, `wave()`, and `dismiss()` methods trigger the entrance,
82
+ wave, and exit treatments. All motion respects `prefers-reduced-motion`.
83
+
56
84
  ### Chrome and navigation
57
85
 
58
86
  | Element | Purpose |
@@ -60,9 +88,14 @@ Components auto-register as custom elements on import.
60
88
  | `sio-glass-toolbar` | 44px glass bar with start/center/end slots |
61
89
  | `sio-segmented` | iOS-style segmented control with counts |
62
90
  | `sio-tab-bar` | Mobile bottom glass bar, channel tabs + optional calendar |
63
- | `sio-channel-rail` | 64px desktop rail with per-channel unread badges |
91
+ | `sio-channel-rail` | 64px desktop rail with the built-in v8 brand mark and per-channel unread badges |
64
92
  | `sio-dropdown-menu` | Slot-triggered menu with destructive/disabled items |
65
93
 
94
+ `sio-tab-bar` uses `max(30px, var(--sio-safe-area-bottom,
95
+ env(safe-area-inset-bottom, 0px)))` for its bottom padding. Set
96
+ `--sio-safe-area-bottom` when a screenshot or native shell supplies a known
97
+ system-reserved area.
98
+
66
99
  ### Lists and feed
67
100
 
68
101
  | Element | Purpose |
@@ -118,7 +151,7 @@ Every component ships a `static demo` rendered in the wcctools dashboard, groupe
118
151
 
119
152
  ## License and Legal Information
120
153
 
121
- This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [license.md](./license.md) file.
154
+ This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the repository license file.
122
155
 
123
156
  **Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
124
157
 
@@ -130,7 +163,7 @@ Use of these trademarks must comply with Task Venture Capital GmbH's Trademark G
130
163
 
131
164
  ### Company Information
132
165
 
133
- Task Venture Capital GmbH
166
+ Task Venture Capital GmbH<br>
134
167
  Registered at District Court Bremen HRB 35230 HB, Germany
135
168
 
136
169
  For any legal inquiries or further information, please contact us via email at hello@task.vc.
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@social.io/catalog',
6
- version: '2.0.0',
7
- description: 'v7 Apple-native design system and web components for social.io'
6
+ version: '2.1.0',
7
+ description: 'Apple-native v8 design system and web components for social.io'
8
8
  }
@@ -2,6 +2,7 @@
2
2
  export * from './tokens.js';
3
3
 
4
4
  // foundation
5
+ export * from './sio-logo.js';
5
6
  export * from './sio-icon.js';
6
7
  export * from './sio-button.js';
7
8
  export * from './sio-kbd.js';
@@ -8,6 +8,7 @@ import {
8
8
  } from '@design.estate/dees-element';
9
9
  import { sioElementStyles } from './tokens.js';
10
10
  import './sio-icon.js';
11
+ import './sio-logo.js';
11
12
 
12
13
  declare global {
13
14
  interface HTMLElementTagNameMap {
@@ -123,6 +124,15 @@ export class SioChannelRail extends DeesElement {
123
124
  border-right: var(--sio-hairline) solid var(--sio-separator);
124
125
  }
125
126
 
127
+ .brand {
128
+ height: 35px;
129
+ box-sizing: border-box;
130
+ display: flex;
131
+ align-items: flex-start;
132
+ justify-content: center;
133
+ padding: 2px 0 9px;
134
+ }
135
+
126
136
  .item {
127
137
  appearance: none;
128
138
  border: none;
@@ -204,6 +214,9 @@ export class SioChannelRail extends DeesElement {
204
214
  public render(): TemplateResult {
205
215
  return html`
206
216
  <nav class="rail" part="rail">
217
+ <div class="brand" part="brand">
218
+ <sio-logo size="24" no-entrance no-hover aria-hidden="true"></sio-logo>
219
+ </div>
207
220
  ${this.channels.map(
208
221
  (channel) => html`
209
222
  <button