Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions public/js/admin-app-form.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { clr as rc, el, inp as inpById, q as qSel, qa, qi, tgt } from '/js/utils.js?v=5d2b6f16';
import { clr as rc, el, inp as inpById, q as qSel, qa, qi, tgt } from '/js/utils.js?v=045df327';
import { html, raw, setHtml } from '/js/html.js?v=c71f8903';
import { loadLocalIcons, resolveIcon, iconChain, cdnIconRef, splitIconRef } from '/js/icons.js?v=9c8c550c';
import { state } from '/js/admin-state.js?v=5a5d655f';
Expand All @@ -21,12 +21,13 @@ import {
reveal,
setTogDisabled,
swapContent,
} from '/js/admin-shared.js?v=69f5c7f9';
import { createListbox } from '/js/listbox.js?v=2b633751';
} from '/js/admin-shared.js?v=dc0e02b6';
import { createListbox } from '/js/listbox.js?v=96066369';
import { MAX_LABELS } from '/js/badge-logic.js?v=b3c8b6c2';
import { renderColorControl, BADGE_SWATCHES, BADGE_DEFAULT } from '/js/admin-color-control.js?v=d0c89032';
import { renderColorControl, BADGE_SWATCHES, BADGE_DEFAULT } from '/js/admin-color-control.js?v=a48fbc58';
import { badgeErrorAdvice, TONE } from '/js/admin-error.js?v=10f3cdb1';
import { fluidHoverClear, fluidHoverKb } from '/js/fluid-hover.js?v=cb886e86';
import { iconSvg } from '/js/icon-set.js?v=606a68c6';

export function buildFolderForm(body, item) {
const children = item?.children || [];
Expand Down Expand Up @@ -437,8 +438,7 @@ function renderActLabels(host) {

const _optRow = label => html`${label} <span class="rl-sub">${t('app.optional')}</span>`;

const GRIP_SVG =
'<svg viewBox="0 0 16 16" width="14" height="14" fill="currentColor" focusable="false"><circle cx="6" cy="4" r="1.3"/><circle cx="10" cy="4" r="1.3"/><circle cx="6" cy="8" r="1.3"/><circle cx="10" cy="8" r="1.3"/><circle cx="6" cy="12" r="1.3"/><circle cx="10" cy="12" r="1.3"/></svg>';
const GRIP_SVG = iconSvg('grip', 14);

function addActLabel() {
captureActLabels();
Expand Down
4 changes: 2 additions & 2 deletions public/js/admin-auth.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ag, ap } from '/js/admin-shared.js?v=69f5c7f9';
import { ag, ap } from '/js/admin-shared.js?v=dc0e02b6';
import { t } from '/js/i18n.js?v=1f1ea9c1';
import { pwStrength } from '/js/password-strength.js?v=42f45ac7';
import { el, inp as inpById, qa } from '/js/utils.js?v=5d2b6f16';
import { el, inp as inpById, qa } from '/js/utils.js?v=045df327';

export async function checkAuth(onLogin) {
try {
Expand Down
21 changes: 9 additions & 12 deletions public/js/admin-color-control.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
import { PE_SVG, initInlineEdit, toast, reveal } from '/js/admin-shared.js?v=69f5c7f9';
import { PE_SVG, initInlineEdit, toast, reveal } from '/js/admin-shared.js?v=dc0e02b6';
import { t } from '/js/i18n.js?v=1f1ea9c1';
import { html, raw, setHtml } from '/js/html.js?v=c71f8903';
import { qa, q } from '/js/utils.js?v=5d2b6f16';
import { qa, q } from '/js/utils.js?v=045df327';
import { iconSvg } from '/js/icon-set.js?v=606a68c6';

const CC_SWATCHES = ['#1c1c1e', '#8e8e93', '#f2f2f7', '#ff393c', '#ffcd00', '#35c759', '#0289ff', '#cb30df'];
export const BADGE_DEFAULT = '#1e6ef4';
export const BADGE_SWATCHES = ['#1c1c1e', '#8e8e93', '#f2f2f7', '#ff393c', '#ffcd00', '#35c759', '#1e6ef4', '#cb30df'];
const _ccIco = {
hueLo:
'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><path d="M12 3s6 6.5 6 11a6 6 0 0 1-12 0c0-4.5 6-11 6-11z"/></svg>',
hueHi:
'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 3s6 6.5 6 11a6 6 0 0 1-12 0c0-4.5 6-11 6-11z"/></svg>',
satLo:
'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><circle cx="12" cy="12" r="8"/></svg>',
satHi:
'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><circle cx="12" cy="12" r="8"/><path d="M12 4a8 8 0 0 1 0 16z" fill="currentColor"/></svg>',
brLo: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><circle cx="12" cy="12" r="3.2"/><path d="M12 5V3M12 21v-2M5 12H3M21 12h-2M6.5 6.5 5.4 5.4M18.6 18.6l-1.1-1.1M17.5 6.5l1.1-1.1M5.4 18.6l1.1-1.1"/></svg>',
brHi: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><circle cx="12" cy="12" r="5"/><path d="M12 4V2M12 22v-2M4 12H2M22 12h-2M5.6 5.6 4.2 4.2M19.8 19.8l-1.4-1.4M18.4 5.6l1.4-1.4M4.2 19.8l1.4-1.4"/></svg>',
hueLo: iconSvg('hue-lo', 16),
hueHi: iconSvg('hue-hi', 16),
satLo: iconSvg('sat-lo', 16),
satHi: iconSvg('sat-hi', 16),
brLo: iconSvg('bright-lo', 16),
brHi: iconSvg('bright-hi', 16),
};
/* Normalise the hue before computing `x`. A negative hue otherwise mixes a
wrapped sextant with an unwrapped `x` and yields a negative channel.
Expand Down
2 changes: 1 addition & 1 deletion public/js/admin-drag.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import { applyDrop, canJoinFolder, folderRowZone } from '/js/admin-drag-logic.js?v=6b767e76';
import { state } from '/js/admin-state.js?v=5a5d655f';
import { snapshotItems } from '/js/admin-save-logic.js?v=4f71ef6c';
import { qa } from '/js/utils.js?v=5d2b6f16';
import { qa } from '/js/utils.js?v=045df327';

/** @type {(before: unknown) => void} */
let _save = () => {};
Expand Down
26 changes: 11 additions & 15 deletions public/js/admin-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@
import { collapsedFolders, filter, state } from '/js/admin-state.js?v=5a5d655f';
import { snapshotItems } from '/js/admin-save-logic.js?v=4f71ef6c';
import { reorderItems } from '/js/admin-logic.js?v=e3673bd7';
import { initDrag, wireRowDrag } from '/js/admin-drag.js?v=dbf4e7e6';
import { paintIcon } from '/js/admin-shared.js?v=69f5c7f9';
import { clr as rc, el, qa, setUserText } from '/js/utils.js?v=5d2b6f16';
import { initDrag, wireRowDrag } from '/js/admin-drag.js?v=227e3153';
import { paintIcon } from '/js/admin-shared.js?v=dc0e02b6';
import { clr as rc, el, qa, setUserText } from '/js/utils.js?v=045df327';
import { html, raw, setHtml } from '/js/html.js?v=c71f8903';
import { t } from '/js/i18n.js?v=1f1ea9c1';
import { sizeLabel } from '/js/admin-widget-form.js?v=c4b11d2a';
import { widgetGlyph } from '/js/widget-glyphs.js?v=12b0a947';
import { sizeLabel } from '/js/admin-widget-form.js?v=3237dd3e';
import { widgetGlyph } from '/js/widget-glyphs.js?v=3adb57ad';
import { iconSvg } from '/js/icon-set.js?v=606a68c6';

/** @type {{ openModal: (idx: number|null) => void,
openFolderPicker: (appId: string|null, targetFolderId?: string|null) => void,
Expand All @@ -39,17 +40,12 @@ export function initList(page) {
}

/* Constant markup only. No user data reaches these. */
const FOLDER_ICON =
'<svg width="26" height="26" viewBox="0 0 24 24" aria-hidden="true"><rect x="6" y="6" width="12" height="12" rx="2.6" fill="none" stroke="currentColor" stroke-width="1.7"></rect><circle cx="9.7" cy="9.7" r="1.25" fill="currentColor"></circle><circle cx="14.3" cy="9.7" r="1.25" fill="currentColor"></circle><circle cx="9.7" cy="14.3" r="1.25" fill="currentColor"></circle><circle cx="14.3" cy="14.3" r="1.25" fill="currentColor"></circle></svg>';
const FOLDER_ICON = iconSvg('folder', 26);
const SIZE_ICONS = {
small:
'<svg width="26" height="26" viewBox="0 0 24 24" aria-hidden="true"><rect x="7" y="7" width="10" height="10" rx="2" fill="none" stroke="currentColor" stroke-width="1.6"></rect><circle cx="9.7" cy="9.7" r="1" fill="currentColor"></circle><line x1="9" y1="13.4" x2="13" y2="13.4" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"></line></svg>',
medium:
'<svg width="26" height="26" viewBox="0 0 24 24" aria-hidden="true"><rect x="4" y="8" width="16" height="9" rx="2" fill="none" stroke="currentColor" stroke-width="1.6"></rect><circle cx="7.6" cy="11.4" r="1.1" fill="currentColor"></circle><line x1="10.2" y1="11.4" x2="16.5" y2="11.4" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"></line><line x1="7" y1="14.3" x2="16.5" y2="14.3" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"></line></svg>',
large:
'<svg width="26" height="26" viewBox="0 0 24 24" aria-hidden="true"><rect x="6" y="5.5" width="12" height="13" rx="2" fill="none" stroke="currentColor" stroke-width="1.6"></rect><circle cx="9" cy="9" r="1.2" fill="currentColor"></circle><line x1="8" y1="12.6" x2="16" y2="12.6" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"></line><line x1="8" y1="14.8" x2="16" y2="14.8" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"></line><line x1="8" y1="17" x2="13" y2="17" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"></line></svg>',
xlarge:
'<svg width="26" height="26" viewBox="0 0 24 24" aria-hidden="true"><rect x="7" y="3.5" width="10" height="17" rx="2" fill="none" stroke="currentColor" stroke-width="1.6"></rect><circle cx="9.7" cy="7" r="1.1" fill="currentColor"></circle><line x1="9" y1="10.5" x2="15" y2="10.5" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"></line><line x1="9" y1="12.7" x2="15" y2="12.7" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"></line><line x1="9" y1="14.9" x2="15" y2="14.9" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"></line><line x1="9" y1="17.1" x2="13" y2="17.1" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"></line></svg>',
small: iconSvg('small', 26),
medium: iconSvg('medium', 26),
large: iconSvg('large', 26),
xlarge: iconSvg('xlarge', 26),
};
function svgNode(markup) {
const t = document.createElement('template');
Expand Down
4 changes: 2 additions & 2 deletions public/js/admin-settings.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { toast, ag, ap, reveal, swapContent } from '/js/admin-shared.js?v=69f5c7f9';
import { toast, ag, ap, reveal, swapContent } from '/js/admin-shared.js?v=dc0e02b6';
import { pwStrength } from '/js/password-strength.js?v=42f45ac7';
import { t } from '/js/i18n.js?v=1f1ea9c1';
import {
Expand All @@ -9,7 +9,7 @@ import {
BLOCK,
} from '/js/admin-logic.js?v=e3673bd7';
import { confirmText } from '/js/modal.js?v=11fa1eff';
import { el, inp, setUserText } from '/js/utils.js?v=5d2b6f16';
import { el, inp, setUserText } from '/js/utils.js?v=045df327';

/* Mirrors the server's rule: auth cannot be switched on with no password. */
let _passwordSet = false;
Expand Down
6 changes: 3 additions & 3 deletions public/js/admin-shared.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/* Stateless helpers shared by the admin modules. Mutable state stays out. */
import { recoversSession, toastHoldMs } from '/js/admin-logic.js?v=e3673bd7';
import { el, q } from '/js/utils.js?v=5d2b6f16';
import { el, q } from '/js/utils.js?v=045df327';
import { t } from '/js/i18n.js?v=1f1ea9c1';
import { iconChain } from '/js/icons.js?v=9c8c550c';
import { iconSvg } from '/js/icon-set.js?v=606a68c6';

export const API = '';

Expand Down Expand Up @@ -199,8 +200,7 @@ export function swapContent(node, apply) {
timer = setTimeout(end, 600);
}

export const PE_SVG =
'<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M11 4H6a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-5"/><path d="M18.4 2.6a1.85 1.85 0 0 1 2.6 2.6l-9.1 9.1-3.4 1 1-3.4z"/></svg>';
export const PE_SVG = iconSvg('edit', 17);

/* `root` lets a caller wire a subtree that is not in the document yet. */
/** A function placeholder is resolved on use, not at wiring time: this runs
Expand Down
22 changes: 7 additions & 15 deletions public/js/admin-widget-form.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,14 @@
import { state } from '/js/admin-state.js?v=5a5d655f';
import { PE_SVG, initInlineEdit, swapContent } from '/js/admin-shared.js?v=69f5c7f9';
import { createListbox } from '/js/listbox.js?v=2b633751';
import { renderWidgetConfigForm } from '/js/widget-config-form.js?v=253fcdcd';
import { PE_SVG, initInlineEdit, swapContent } from '/js/admin-shared.js?v=dc0e02b6';
import { createListbox } from '/js/listbox.js?v=96066369';
import { renderWidgetConfigForm } from '/js/widget-config-form.js?v=e998ed94';
import { html, raw, setHtml } from '/js/html.js?v=c71f8903';
import { sizesForView, widgetConfigMode, rejectionLines, carriesTypedValues } from '/js/admin-logic.js?v=e3673bd7';
import { t } from '/js/i18n.js?v=1f1ea9c1';
import { q, qi, qa } from '/js/utils.js?v=5d2b6f16';
import { q, qi, qa } from '/js/utils.js?v=045df327';
import { iconSvg } from '/js/icon-set.js?v=606a68c6';

const SIZE_ICONS = {
small:
'<rect x="7" y="7" width="10" height="10" rx="2" fill="none" stroke="currentColor" stroke-width="1.6"/><circle cx="9.7" cy="9.7" r="1" fill="currentColor"/><line x1="9" y1="13.4" x2="13" y2="13.4" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/>',
medium:
'<rect x="4" y="8" width="16" height="9" rx="2" fill="none" stroke="currentColor" stroke-width="1.6"/><circle cx="7.6" cy="11.4" r="1.1" fill="currentColor"/><line x1="10.2" y1="11.4" x2="16.5" y2="11.4" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/><line x1="7" y1="14.3" x2="16.5" y2="14.3" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/>',
large:
'<rect x="6" y="5.5" width="12" height="13" rx="2" fill="none" stroke="currentColor" stroke-width="1.6"/><circle cx="9" cy="9" r="1.2" fill="currentColor"/><line x1="8" y1="12.6" x2="16" y2="12.6" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/><line x1="8" y1="14.8" x2="16" y2="14.8" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/><line x1="8" y1="17" x2="13" y2="17" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/>',
xlarge:
'<rect x="7" y="3.5" width="10" height="17" rx="2" fill="none" stroke="currentColor" stroke-width="1.6"/><circle cx="9.7" cy="7" r="1.1" fill="currentColor"/><line x1="9" y1="10.5" x2="15" y2="10.5" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/><line x1="9" y1="12.7" x2="15" y2="12.7" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/><line x1="9" y1="14.9" x2="15" y2="14.9" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/><line x1="9" y1="17.1" x2="13" y2="17.1" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/>',
};
const SIZES_WITH_ICONS = new Set(['small', 'medium', 'large', 'xlarge']);

const CUSTOM_SIZES = ['small', 'medium', 'large', 'xlarge'];
function widgetSizes(type) {
Expand Down Expand Up @@ -108,7 +100,7 @@ function _renderWidgetForm(body) {
scard.className = 'grp';
setHtml(
scard,
html`<div class="row tile-row"><div class="tile-grp">${_sizeOpts.map(s => html`<button type="button" class="tile-opt${s === state._wsize ? ' on' : ''}" aria-pressed="${String(s === state._wsize)}" data-size="${s}"><span class="tile-ico"><svg width="26" height="26" viewBox="0 0 24 24" aria-hidden="true">${raw(SIZE_ICONS[s] || SIZE_ICONS.medium)}</svg></span><span class="tile-cap">${sizeLabel(s)}</span></button>`)}</div></div>`,
html`<div class="row tile-row"><div class="tile-grp">${_sizeOpts.map(s => html`<button type="button" class="tile-opt${s === state._wsize ? ' on' : ''}" aria-pressed="${String(s === state._wsize)}" data-size="${s}"><span class="tile-ico">${raw(iconSvg(SIZES_WITH_ICONS.has(s) ? s : 'medium', 38))}</span><span class="tile-cap">${sizeLabel(s)}</span></button>`)}</div></div>`,
);
body.appendChild(scard);
qa('.tile-opt', scard).forEach(b =>
Expand Down
33 changes: 13 additions & 20 deletions public/js/admin.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { buildAppForm, buildFolderForm, captureActLabels, serializeKvRows } from '/js/admin-app-form.js?v=7da1ff10';
import { checkAuth, requireLogin, wirePasswordStrength } from '/js/admin-auth.js?v=e2646986';
import { initList, render, syncFilterUI } from '/js/admin-list.js?v=c5d8bff8';
import { buildAppForm, buildFolderForm, captureActLabels, serializeKvRows } from '/js/admin-app-form.js?v=0b617803';
import { checkAuth, requireLogin, wirePasswordStrength } from '/js/admin-auth.js?v=9833ce5d';
import { initList, render, syncFilterUI } from '/js/admin-list.js?v=1c65c8ad';
import { resolveAdminSection } from '/js/admin-logic.js?v=e3673bd7';
import {
buildAppItem,
Expand All @@ -10,16 +10,17 @@ import {
snapshotItems,
upsertItem,
} from '/js/admin-save-logic.js?v=4f71ef6c';
import { loadSettings, settingsDirty, showBgFields, showWallpaperFile } from '/js/admin-settings.js?v=4d5e9919';
import { ag, ap, initInlineEdit, paintIcon, reveal, setReauthHandler, toast } from '/js/admin-shared.js?v=69f5c7f9';
import { loadSettings, settingsDirty, showBgFields, showWallpaperFile } from '/js/admin-settings.js?v=002dde46';
import { ag, ap, initInlineEdit, paintIcon, reveal, setReauthHandler, toast } from '/js/admin-shared.js?v=dc0e02b6';
import { collapsedFolders, filter, state } from '/js/admin-state.js?v=5a5d655f';
import { buildWidgetForm } from '/js/admin-widget-form.js?v=c4b11d2a';
import { buildWidgetForm } from '/js/admin-widget-form.js?v=3237dd3e';
import { initFluidHover } from '/js/fluid-hover.js?v=cb886e86';
import { initGlideSelect, syncGlideSelect } from '/js/glide-select.js?v=8b39e9d0';
import { createListbox } from '/js/listbox.js?v=2b633751';
import { createListbox } from '/js/listbox.js?v=96066369';
import { html, raw, setHtml } from '/js/html.js?v=c71f8903';
import { initI18n, LANGUAGES, t } from '/js/i18n.js?v=1f1ea9c1';
import { loadLocalIcons } from '/js/icons.js?v=9c8c550c';
import { ensureSprite, iconSvg } from '/js/icon-set.js?v=606a68c6';
import {
clearSkipTls,
convert,
Expand All @@ -32,11 +33,13 @@ import {
import { isMobileLayout, onLayoutChange } from '/js/layout.js?v=e9f4b607';
import { confirmModal, confirmText, openModal as openDialog, promptModal } from '/js/modal.js?v=11fa1eff';
import { readMode, watchSystemTheme, writeMode } from '/js/theme.js?v=787bfdff';
import { el, inp, q, qa, clr as rc, sanitizeCssUrl, setUserText, tgt } from '/js/utils.js?v=5d2b6f16';
import { normalizeColorInput } from '/js/admin-color-control.js?v=d0c89032';
import { el, inp, q, qa, clr as rc, sanitizeCssUrl, setUserText, tgt } from '/js/utils.js?v=045df327';
import { normalizeColorInput } from '/js/admin-color-control.js?v=a48fbc58';
import { parseYamlTolerant, YamlLiteError } from '/js/yaml-lite.js?v=6ebb564c';
import { loadWallpaper, saveWallpaper } from '/js/wallpaper-cache.js?v=c5f8a3e6';

ensureSprite();

/* A class rather than a bare media query. Some phones report a wider CSS
viewport than they have. The rule lives in layout.js, shared with the
dashboard, so the two screens cannot disagree about what mobile means. */
Expand Down Expand Up @@ -190,13 +193,6 @@ function showEditView() {
q('.cp')?.scrollTo?.(0, 0);
}

const TYPE_ICONS = {
app: '<rect x="7" y="7" width="10" height="10" rx="2.6" fill="none" stroke="currentColor" stroke-width="1.7"/>',
widget:
'<rect x="3.5" y="6.5" width="17" height="11" rx="2.2" fill="none" stroke="currentColor" stroke-width="1.7"/><circle cx="7.2" cy="10.2" r="1.5" fill="currentColor"/><line x1="5.6" y1="13.4" x2="17.4" y2="13.4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><line x1="5.6" y1="15.2" x2="17.4" y2="15.2" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>',
folder:
'<rect x="6" y="6" width="12" height="12" rx="2.6" fill="none" stroke="currentColor" stroke-width="1.7"/><circle cx="9.7" cy="9.7" r="1.25" fill="currentColor"/><circle cx="14.3" cy="9.7" r="1.25" fill="currentColor"/><circle cx="9.7" cy="14.3" r="1.25" fill="currentColor"/><circle cx="14.3" cy="14.3" r="1.25" fill="currentColor"/>',
};
/* Read at draw time. The catalog is not loaded when this module evaluates. */
const typeLabels = () => ({ app: t('type.app'), widget: t('type.widget'), folder: t('type.folder') });

Expand All @@ -216,10 +212,7 @@ function buildAddNewCard() {
b.dataset.ctype = kind;
b.setAttribute('aria-pressed', String(kind === state.ctype));
b.setAttribute('aria-label', t('type.addNew') + ': ' + label);
setHtml(
b,
html`<span class="tile-ico"><svg width="26" height="26" viewBox="0 0 24 24" aria-hidden="true">${raw(TYPE_ICONS[kind])}</svg></span><span class="tile-cap">${label}</span>`,
);
setHtml(b, html`<span class="tile-ico">${raw(iconSvg(kind, 38))}</span><span class="tile-cap">${label}</span>`);
b.onclick = () => {
if (state.ctype === kind) return;
state.ctype = kind;
Expand Down
Loading
Loading