wip: visual re-work

This commit is contained in:
2026-07-03 14:56:43 -03:00
parent 1580187689
commit 1dfbe74280
32 changed files with 636 additions and 188 deletions

View File

@@ -19,31 +19,31 @@ const CategoryEditModal: React.FC<CategoryEditModalProps> = ({ category, edit, o
};
return (
<div className="fixed inset-0 bg-black/90 backdrop-blur-sm flex items-center justify-center z-50" onClick={handleOverlayClick}>
<div className="bg-black/25 backdrop-blur-md border border-white/10 rounded-2xl p-8 w-full max-w-lg text-white">
<h2 className="text-3xl font-bold mb-6">{edit ? 'Edit Category' : 'Add Category'}</h2>
<div className="liquid-modal-backdrop fixed inset-0 flex items-center justify-center z-50 p-4" onClick={handleOverlayClick}>
<div className="liquid-panel liquid-modal-card rounded-3xl p-6 sm:p-8 w-full max-w-lg text-white">
<h2 className="liquid-title-text text-3xl font-extrabold mb-6">{edit ? 'Edit Category' : 'Add Category'}</h2>
<div className="flex flex-col gap-4">
<input
type="text"
placeholder="Category Name"
value={name}
onChange={(e) => setName(e.target.value)}
className="bg-white/10 p-3 rounded-lg focus:outline-none focus:ring-2 focus:ring-cyan-400"
className="liquid-input p-3"
/>
</div>
<div className="flex justify-between items-center mt-8">
<div>
{edit && (
<button onClick={onDelete} className="bg-red-500 hover:bg-red-400 text-white font-bold py-2 px-6 rounded-lg">
<button onClick={onDelete} className="liquid-button liquid-button-danger liquid-focus py-2.5 px-5">
Delete
</button>
)}
</div>
<div className="flex justify-end gap-4">
<button onClick={() => onSave(name)} className="bg-green-500 hover:bg-green-400 text-white font-bold py-2 px-6 rounded-lg">
<div className="flex justify-end gap-3">
<button onClick={() => onSave(name)} className="liquid-button liquid-button-success liquid-focus py-2.5 px-5">
Save
</button>
<button onClick={onClose} className="bg-gray-600 hover:bg-gray-500 text-white font-bold py-2 px-6 rounded-lg">
<button onClick={onClose} className="liquid-button liquid-button-secondary liquid-focus py-2.5 px-5">
Close
</button>
</div>

View File

@@ -56,9 +56,8 @@ const Clock: React.FC<ClockProps> = ({ config, getClockSizeClass }) => {
return (
<div
className={`text-white font-bold ${getClockSizeClass(config.clock.size)}`}
className={`liquid-clock-text whitespace-nowrap text-white font-bold ${getClockSizeClass(config.clock.size)}`}
style={{
textShadow: '0 2px 4px rgba(0,0,0,0.5)',
fontFamily: config.clock.font,
}}
>

View File

@@ -133,7 +133,7 @@ const ConfigurationModal: React.FC<ConfigurationModalProps> = ({
return (
<div className="fixed inset-0 z-50" role="dialog" aria-modal="true">
<div
className={`fixed inset-0 bg-black/60 backdrop-blur-sm transition-opacity duration-250 ease-ios ${
className={`liquid-modal-backdrop fixed inset-0 transition-opacity duration-200 ease-ios ${
isVisible ? 'opacity-100' : 'opacity-0'
}`}
onClick={handleClose}
@@ -141,21 +141,21 @@ const ConfigurationModal: React.FC<ConfigurationModalProps> = ({
<div
ref={menuRef}
className={`fixed top-0 right-0 h-full w-full max-w-lg bg-black/50 backdrop-blur-xl border-l border-white/10 text-white flex flex-col transition-transform duration-300 ease-spring transform ${
className={`liquid-drawer fixed top-0 right-0 h-full w-full max-w-xl text-white flex flex-col transition-transform duration-300 ease-spring transform ${
isVisible ? 'translate-x-0' : 'translate-x-full'
}`}
>
<div className="p-8 flex-grow overflow-y-auto">
<h2 className="text-3xl font-bold mb-6">Configuration</h2>
<div className="p-6 sm:p-8 flex-grow overflow-y-auto">
<h2 className="liquid-title-text text-3xl font-extrabold mb-6">Configuration</h2>
<div className="flex border-b border-white/10 mb-6">
<div className="liquid-surface grid grid-cols-2 sm:grid-cols-4 gap-1 rounded-2xl p-1 mb-7">
{tabs.map((tab) => (
<button
key={tab.id}
className={`px-4 py-2 text-lg font-semibold ${
className={`liquid-focus rounded-xl px-3 py-2 text-sm font-bold transition-all duration-200 ease-ios ${
activeTab === tab.id
? 'text-cyan-400 border-b-2 border-cyan-400'
: 'text-slate-400'
? 'bg-cyan-400/25 text-cyan-100 shadow-[inset_0_1px_0_rgba(255,255,255,0.28)]'
: 'text-slate-300 hover:bg-white/10 hover:text-white'
}`}
onClick={() => setActiveTab(tab.id)}
>
@@ -188,18 +188,18 @@ const ConfigurationModal: React.FC<ConfigurationModalProps> = ({
)}
</div>
<div className="p-8 border-t border-white/10">
<div className="flex items-center justify-between gap-4">
<div className="p-6 sm:p-8 border-t border-white/10">
<div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
<div className="flex gap-2">
<button
onClick={() => ConfigurationService.exportConfig()}
className="bg-slate-700 hover:bg-slate-600 active:scale-95 text-white text-sm font-semibold py-1.5 px-3 rounded-lg transition-all duration-150 ease-ios"
className="liquid-button liquid-button-secondary liquid-focus text-sm py-2 px-4"
>
Export
</button>
<button
onClick={() => importInputRef.current?.click()}
className="bg-slate-700 hover:bg-slate-600 active:scale-95 text-white text-sm font-semibold py-1.5 px-3 rounded-lg transition-all duration-150 ease-ios"
className="liquid-button liquid-button-secondary liquid-focus text-sm py-2 px-4"
>
Import
</button>
@@ -211,19 +211,19 @@ const ConfigurationModal: React.FC<ConfigurationModalProps> = ({
onChange={handleImportConfig}
/>
</div>
<div className="flex justify-end gap-4">
<div className="flex justify-end gap-3">
<button
onClick={() => {
isSaving.current = true;
onSave(config);
}}
className="bg-green-500 hover:bg-green-400 active:scale-95 text-white font-bold py-2 px-6 rounded-lg transition-all duration-150 ease-ios"
className="liquid-button liquid-button-success liquid-focus py-2.5 px-5"
>
Save & Close
</button>
<button
onClick={handleClose}
className="bg-gray-600 hover:bg-gray-500 active:scale-95 text-white font-bold py-2 px-6 rounded-lg transition-all duration-150 ease-ios"
className="liquid-button liquid-button-secondary liquid-focus py-2.5 px-5"
>
Cancel
</button>

View File

@@ -71,7 +71,7 @@ const Dropdown: React.FC<DropdownProps> = ({ options, value, onChange, name, mul
<div className="relative" ref={dropdownRef}>
<button
type="button"
className="bg-black/5 backdrop-blur-md border border-white/10 rounded-lg p-3 text-white text-sm focus:outline-none focus:ring-2 focus:ring-cyan-400 w-40 h-10 flex justify-between items-center transition-all duration-200 hover:bg-white/5"
className="liquid-surface liquid-focus rounded-xl px-3 text-white text-sm w-44 h-11 flex justify-between items-center transition-all duration-200 ease-ios hover:border-white/30"
onClick={() => setIsOpen(!isOpen)}
aria-haspopup="listbox"
aria-expanded={isOpen}
@@ -95,7 +95,7 @@ const Dropdown: React.FC<DropdownProps> = ({ options, value, onChange, name, mul
{isOpen && (
<ul
className="absolute z-10 mt-1 w-full bg-black/70 backdrop-blur-xl border border-white/20 rounded-lg shadow-2xl overflow-hidden animate-in slide-in-from-top-2 fade-in duration-150"
className="liquid-panel liquid-dropdown-list absolute z-10 mt-2 w-full rounded-xl overflow-hidden"
role="listbox"
>
{options.map((option) => (
@@ -105,8 +105,8 @@ const Dropdown: React.FC<DropdownProps> = ({ options, value, onChange, name, mul
className={`h-10 px-3 text-white cursor-pointer transition-all duration-150 ease-ios flex items-center
${
isSelected(option.value)
? 'bg-cyan-500/20 text-cyan-300'
: 'hover:bg-white/20 hover:text-white hover:shadow-lg'
? 'bg-cyan-400/20 text-cyan-200'
: 'hover:bg-white/20 hover:text-white'
}`}
role="option"
aria-selected={isSelected(option.value)}
@@ -117,7 +117,6 @@ const Dropdown: React.FC<DropdownProps> = ({ options, value, onChange, name, mul
</ul>
)}
{/* Hidden input to mimic native select behavior for forms */}
{name && !multiple && <input type="hidden" name={name} value={value as string} />}
</div>
);

View File

@@ -15,11 +15,11 @@ interface ServerWidgetProps {
const getStatusColor = (status: string) => {
switch (status) {
case 'online':
return 'bg-green-500';
return 'bg-green-400 text-green-400';
case 'offline':
return 'bg-red-500';
return 'bg-red-400 text-red-400';
default:
return 'bg-gray-500';
return 'bg-slate-400 text-slate-400';
}
};
@@ -71,13 +71,11 @@ const ServerWidget: React.FC<ServerWidgetProps> = ({ config }) => {
}
return (
<div className="fixed bottom-0 left-1/2 -translate-x-1/2 w-auto max-w-full">
<div className="flex items-center gap-4 bg-black/25 backdrop-blur-md border border-white/20 px-4 py-2 shadow-lg"
style={{ borderBottomLeftRadius: '0', borderBottomRightRadius: '0', borderTopLeftRadius: '16px', borderTopRightRadius: '15px', borderBottomWidth: '0' }}
>
<div className="fixed bottom-3 left-1/2 z-20 w-auto max-w-[calc(100%-1.5rem)] -translate-x-1/2">
<div className="liquid-surface flex items-center gap-4 rounded-full px-4 py-2">
{config.serverWidget.servers.map((server) => (
<div key={server.id} className="flex items-center gap-2">
<div className={`w-3 h-3 rounded-full ${getStatusColor(serverStatus[server.id])}`}></div>
<div className={`liquid-status-dot w-2.5 h-2.5 rounded-full ${getStatusColor(serverStatus[server.id])}`}></div>
<span className="text-slate-100 text-sm font-medium">
{server.name}
</span>
@@ -88,4 +86,4 @@ const ServerWidget: React.FC<ServerWidgetProps> = ({ config }) => {
);
};
export default ServerWidget;
export default ServerWidget;

View File

@@ -11,14 +11,20 @@ const ToggleSwitch: React.FC<ToggleSwitchProps> = ({ checked, onChange }) => {
};
return (
<div
className={`w-14 h-8 flex items-center rounded-full p-1 cursor-pointer transition-colors duration-200 ease-ios ${checked ? 'bg-cyan-500' : 'bg-gray-600'}`}
<button
type="button"
className={`liquid-focus relative w-14 h-8 flex items-center rounded-full p-1 cursor-pointer border transition-all duration-200 ease-ios ${
checked
? 'bg-cyan-400/70 border-cyan-200/60 shadow-[0_0_24px_rgba(34,211,238,0.22)]'
: 'bg-white/10 border-white/20'
}`}
onClick={handleToggle}
aria-pressed={checked}
>
<div
className={`bg-white w-6 h-6 rounded-full shadow-md transform transition-transform duration-200 ease-spring ${checked ? 'translate-x-6' : 'translate-x-0'}`}
className={`bg-white w-6 h-6 rounded-full shadow-lg transform transition-transform duration-200 ease-spring ${checked ? 'translate-x-6' : 'translate-x-0'}`}
/>
</div>
</button>
);
};

View File

@@ -128,17 +128,18 @@ const Wallpaper: React.FC<WallpaperProps> = ({ wallpaperNames, blur, brightness,
if (!imageUrl) return null;
return (
<div
className="fixed inset-0 -z-10 w-full h-full wallpaper-transition"
style={{
backgroundImage: `url(${imageUrl})`,
backgroundSize: 'cover',
backgroundPosition: 'center',
filter: `blur(${blur}px) brightness(${brightness / 100})`,
opacity: opacity / 100,
}}
aria-label="Wallpaper background"
/>
<>
<div
className="wallpaper-layer wallpaper-transition"
style={{
backgroundImage: `url(${imageUrl})`,
filter: `blur(${blur}px) brightness(${brightness / 100})`,
opacity: opacity / 100,
}}
aria-label="Wallpaper background"
/>
<div className="wallpaper-luminance" aria-hidden="true" />
</>
);
};

View File

@@ -103,15 +103,15 @@ const WebsiteEditModal: React.FC<WebsiteEditModalProps> = ({ website, edit, onCl
};
return (
<div className="fixed inset-0 bg-black/90 backdrop-blur-sm flex items-center justify-center z-50" onClick={handleOverlayClick}>
<div className="bg-black/25 backdrop-blur-md border border-white/10 rounded-2xl p-8 w-full max-w-lg text-white">
<h2 className="text-3xl font-bold mb-6">{edit ? 'Edit Website' : 'Add Website'}</h2>
<div className="liquid-modal-backdrop fixed inset-0 flex items-center justify-center z-50 p-4" onClick={handleOverlayClick}>
<div className="liquid-panel liquid-modal-card rounded-3xl p-6 sm:p-8 w-full max-w-lg text-white">
<h2 className="liquid-title-text text-3xl font-extrabold mb-6">{edit ? 'Edit Website' : 'Add Website'}</h2>
<div className="flex flex-col gap-4">
<div className="flex justify-center mb-4">
{icon ? (
<img src={icon} alt="Website Icon" className="h-24 w-24 object-contain" />
) : (
<div className="h-24 w-24 bg-white/10 rounded-lg flex items-center justify-center">
<div className="liquid-surface h-24 w-24 rounded-2xl flex items-center justify-center">
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1" strokeLinecap="round" strokeLinejoin="round" className="text-white/50">
<circle cx="12" cy="12" r="10"></circle>
<line x1="2" y1="12" x2="22" y2="12"></line>
@@ -125,16 +125,16 @@ const WebsiteEditModal: React.FC<WebsiteEditModalProps> = ({ website, edit, onCl
placeholder="Name"
value={name}
onChange={(e) => setName(e.target.value)}
className="bg-white/10 p-3 rounded-lg focus:outline-none focus:ring-2 focus:ring-cyan-400"
className="liquid-input p-3"
/>
<input
type="text"
placeholder="URL"
value={url}
onChange={(e) => setUrl(e.target.value)}
className="bg-white/10 p-3 rounded-lg focus:outline-none focus:ring-2 focus:ring-cyan-400"
className="liquid-input p-3"
/>
<div className="flex items-center gap-2">
<div className="flex flex-col gap-2 sm:flex-row sm:items-center">
<div className="relative w-full">
<input
type="text"
@@ -145,10 +145,10 @@ const WebsiteEditModal: React.FC<WebsiteEditModalProps> = ({ website, edit, onCl
setIconQuery(e.target.value);
}}
onFocus={ensureIconMetadata}
className="bg-white/10 p-3 rounded-lg focus:outline-none focus:ring-2 focus:ring-cyan-400 w-full"
className="liquid-input p-3"
/>
{filteredIcons.length > 0 && (
<div className="absolute z-10 w-full bg-gray-800 rounded-lg mt-1 max-h-60 overflow-y-auto">
<div className="liquid-panel liquid-dropdown-list absolute z-20 w-full rounded-xl mt-2 max-h-60 overflow-y-auto">
{filteredIcons.map(iconData => (
<div
key={iconData.name}
@@ -157,7 +157,7 @@ const WebsiteEditModal: React.FC<WebsiteEditModalProps> = ({ website, edit, onCl
setIcon(iconUrl);
setFilteredIcons([]);
}}
className="cursor-pointer flex items-center p-2 hover:bg-gray-700"
className="cursor-pointer flex items-center p-2 transition-colors duration-150 ease-ios hover:bg-white/20"
>
<img
src={`https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/${iconData.base}/${iconData.name}.${iconData.base}`}
@@ -170,7 +170,7 @@ const WebsiteEditModal: React.FC<WebsiteEditModalProps> = ({ website, edit, onCl
</div>
)}
</div>
<button onClick={fetchIcon} className="bg-gray-600 hover:bg-gray-500 text-white font-bold py-3 px-4 rounded-lg">
<button onClick={fetchIcon} className="liquid-button liquid-button-secondary liquid-focus py-3 px-4">
Fetch
</button>
</div>
@@ -178,16 +178,16 @@ const WebsiteEditModal: React.FC<WebsiteEditModalProps> = ({ website, edit, onCl
<div className="flex justify-between items-center mt-8">
<div>
{edit && (
<button onClick={onDelete} className="bg-red-500 hover:bg-red-400 text-white font-bold py-2 px-6 rounded-lg">
<button onClick={onDelete} className="liquid-button liquid-button-danger liquid-focus py-2.5 px-5">
Delete
</button>
)}
</div>
<div className="flex justify-end gap-4">
<button onClick={handleSave} className="bg-green-500 hover:bg-green-400 text-white font-bold py-2 px-6 rounded-lg">
<div className="flex justify-end gap-3">
<button onClick={handleSave} className="liquid-button liquid-button-success liquid-focus py-2.5 px-5">
Save
</button>
<button onClick={onClose} className="bg-gray-600 hover:bg-gray-500 text-white font-bold py-2 px-6 rounded-lg">
<button onClick={onClose} className="liquid-button liquid-button-secondary liquid-focus py-2.5 px-5">
Close
</button>
</div>
@@ -197,4 +197,4 @@ const WebsiteEditModal: React.FC<WebsiteEditModalProps> = ({ website, edit, onCl
);
};
export default WebsiteEditModal;
export default WebsiteEditModal;

View File

@@ -59,53 +59,48 @@ const WebsiteTile: React.FC<WebsiteTileProps> = ({ website, isEditing, onEdit, o
return;
}
setIsLoading(true);
// Simulate loading time (dev purpose)
// e.preventDefault();
// setTimeout(() => {
// setIsLoading(false);
// }, 3500); // Small delay to show spinner before navigation
};
const iconSizeClass = `w-[${getIconPixelSize(tileSize)}px] h-[${getIconPixelSize(tileSize)}px]`;
const iconSizeLoadingClass = `w-[${getIconLoadingPixelSize(tileSize)}px] h-[${getIconLoadingPixelSize(tileSize)}px]`;
return (
<div className={`relative ${getTileSizeClass(tileSize)} transition-all duration-200 ease-ios`}>
<div className={`relative ${getTileSizeClass(tileSize)} transition-all duration-200 ease-ios ${isEditing ? 'mb-4' : ''}`}>
<a
href={isEditing ? undefined : website.url}
target="_self"
rel="noopener noreferrer"
onClick={handleClick}
className="group flex flex-col items-center justify-center p-4 bg-black/25 backdrop-blur-md border border-white/10 rounded-2xl w-full h-full transform transition-all duration-200 ease-ios hover:scale-[1.04] active:scale-[0.96] hover:bg-white/25 shadow-lg focus:outline-none focus:ring-2 focus:ring-cyan-400 focus:ring-opacity-75"
className={`liquid-surface liquid-tile liquid-focus group flex flex-col items-center justify-center w-full h-full p-4 ${isEditing ? 'pb-6' : ''}`}
aria-label={isEditing ? `${website.name} edit controls` : `Open ${website.name}`}
>
{isLoading && (
<div className="absolute inset-0 flex items-center justify-center mb-6">
<div className="absolute inset-0 z-10 flex items-center justify-center mb-6">
<svg className="animate-spin h-10 w-10 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
</div>
)}
<div className={`flex items-center transition-all duration-200 ease-ios ${isLoading ? 'mt-18' : 'flex-col'} ${isLoading ? 'gap-2' : ''}`}>
<div className={`transition-all duration-200 ease-ios ${isLoading ? iconSizeLoadingClass : iconSizeClass}`}>
<img src={website.icon} alt={`${website.name} icon`} className={`object-contain w-full h-full`} />
<div className={`relative z-10 flex items-center transition-all duration-200 ease-ios ${isLoading ? 'translate-y-5 gap-2' : 'flex-col gap-3'}`}>
<div className={`transition-all duration-200 ease-ios drop-shadow-[0_10px_20px_rgba(0,0,0,0.28)] ${isLoading ? iconSizeLoadingClass : iconSizeClass}`}>
<img src={website.icon} alt={`${website.name} icon`} className="object-contain w-full h-full" />
</div>
<span className={`text-slate-100 font-medium text-base tracking-wide text-center transition-all duration-200 ease-ios ${isLoading ? 'text-sm' : ''}`}>
<span className={`max-w-full px-1 text-slate-50 font-semibold text-base text-center leading-tight transition-all duration-200 ease-ios [text-shadow:0_2px_12px_rgba(2,6,23,0.44)] ${isLoading ? 'text-sm' : ''}`}>
{website.name}
</span>
</div>
</a>
{isEditing && (
<div className="absolute bottom-2 left-0 right-0 flex justify-center gap-2">
<button onClick={() => onMove(website, 'left')} className="text-white/50 hover:text-white transition-colors"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" className="bi bi-arrow-left" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M15 8a.5.5 0 0 0-.5-.5H2.707l3.147-3.146a.5.5 0 1 0-.708-.708l-4 4a.5.5 0 0 0 0 .708l4 4a.5.5 0 0 0 .708-.708L2.707 8.5H14.5A.5.5 0 0 0 15 8z" />
<div className="liquid-surface liquid-edit-toolbar">
<button onClick={() => onMove(website, 'left')} className="liquid-edit-action liquid-focus" aria-label={`Move ${website.name} left`}><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" viewBox="0 0 16 16" aria-hidden="true">
<path fillRule="evenodd" d="M15 8a.5.5 0 0 0-.5-.5H2.707l3.147-3.146a.5.5 0 1 0-.708-.708l-4 4a.5.5 0 0 0 0 .708l4 4a.5.5 0 0 0 .708-.708L2.707 8.5H14.5A.5.5 0 0 0 15 8z" />
</svg></button>
<button onClick={() => onEdit(website)} className="text-white/50 hover:text-white transition-colors"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" className="bi bi-pencil" viewBox="0 0 16 16">
<button onClick={() => onEdit(website)} className="liquid-edit-action liquid-focus" aria-label={`Edit ${website.name}`}><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" viewBox="0 0 16 16" aria-hidden="true">
<path d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z" />
</svg></button>
<button onClick={() => onMove(website, 'right')} className="text-white/50 hover:text-white transition-colors"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" className="bi bi-arrow-right" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M1 8a.5.5 0 0 1 .5-.5h11.793l-3.147-3.146a.5.5 0 0 1 .708-.708l4 4a.5.5 0 0 1 0 .708l-4 4a.5.5 0 0 1-.708-.708L13.293 8.5H1.5A.5.5 0 0 1 1 8z" />
<button onClick={() => onMove(website, 'right')} className="liquid-edit-action liquid-focus" aria-label={`Move ${website.name} right`}><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" viewBox="0 0 16 16" aria-hidden="true">
<path fillRule="evenodd" d="M1 8a.5.5 0 0 1 .5-.5h11.793l-3.147-3.146a.5.5 0 0 1 .708-.708l4 4a.5.5 0 0 1 0 .708l-4 4a.5.5 0 0 1-.708-.708L13.293 8.5H1.5A.5.5 0 0 1 1 8z" />
</svg></button>
</div>
)}

View File

@@ -15,14 +15,14 @@ const ClockTab: React.FC<ClockTabProps> = ({ config, onChange }) => {
return (
<div className="flex flex-col gap-6">
<div className="flex items-center justify-between">
<div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
<label className="text-slate-300 text-sm font-semibold">Enable Clock</label>
<ToggleSwitch
checked={config.clock.enabled}
onChange={(checked) => updateClock({ enabled: checked })}
/>
</div>
<div className="flex items-center justify-between">
<div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
<label className="text-slate-300 text-sm font-semibold">Clock Size</label>
<Dropdown
name="clock.size"
@@ -36,7 +36,7 @@ const ClockTab: React.FC<ClockTabProps> = ({ config, onChange }) => {
]}
/>
</div>
<div className="flex items-center justify-between">
<div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
<label className="text-slate-300 text-sm font-semibold">Clock Font</label>
<Dropdown
name="clock.font"
@@ -50,7 +50,7 @@ const ClockTab: React.FC<ClockTabProps> = ({ config, onChange }) => {
]}
/>
</div>
<div className="flex items-center justify-between">
<div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
<label className="text-slate-300 text-sm font-semibold">Time Format</label>
<Dropdown
name="clock.format"

View File

@@ -16,10 +16,10 @@ const GeneralTab: React.FC<GeneralTabProps> = ({ config, onChange }) => {
type="text"
value={config.title}
onChange={(e) => onChange({ title: e.target.value })}
className="bg-white/10 p-3 rounded-lg w-full focus:outline-none focus:ring-2 focus:ring-cyan-400"
className="liquid-input p-3"
/>
</div>
<div className="flex items-center justify-between">
<div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
<label className="text-slate-300 text-sm font-semibold">Title Size</label>
<Dropdown
name="titleSize"
@@ -33,7 +33,7 @@ const GeneralTab: React.FC<GeneralTabProps> = ({ config, onChange }) => {
]}
/>
</div>
<div className="flex items-center justify-between">
<div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
<label className="text-slate-300 text-sm font-semibold">Vertical Alignment</label>
<Dropdown
name="alignment"
@@ -46,7 +46,7 @@ const GeneralTab: React.FC<GeneralTabProps> = ({ config, onChange }) => {
]}
/>
</div>
<div className="flex items-center justify-between">
<div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
<label className="text-slate-300 text-sm font-semibold">Tile Size</label>
<Dropdown
name="tileSize"
@@ -59,7 +59,7 @@ const GeneralTab: React.FC<GeneralTabProps> = ({ config, onChange }) => {
]}
/>
</div>
<div className="flex items-center justify-between">
<div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
<label className="text-slate-300 text-sm font-semibold">Horizontal Alignment</label>
<Dropdown
name="horizontalAlignment"

View File

@@ -44,7 +44,7 @@ const ServerWidgetTab: React.FC<ServerWidgetTabProps> = ({ config, onChange }) =
return (
<div className="flex flex-col gap-6">
<div className="flex items-center justify-between">
<div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
<label className="text-slate-300 text-sm font-semibold">Enable Server Widget</label>
<ToggleSwitch
checked={config.serverWidget.enabled}
@@ -53,7 +53,7 @@ const ServerWidgetTab: React.FC<ServerWidgetTabProps> = ({ config, onChange }) =
</div>
{config.serverWidget.enabled && (
<>
<div className="flex items-center justify-between">
<div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
<label className="text-slate-300 text-sm font-semibold">Ping Frequency</label>
<div className="flex items-center gap-4">
<input
@@ -62,9 +62,9 @@ const ServerWidgetTab: React.FC<ServerWidgetTabProps> = ({ config, onChange }) =
max="60"
value={config.serverWidget.pingFrequency}
onChange={(e) => updateServerWidget({ pingFrequency: Number(e.target.value) })}
className="w-48"
className="liquid-range"
/>
<span>{config.serverWidget.pingFrequency}s</span>
<span className="w-12 text-right text-sm text-slate-200">{config.serverWidget.pingFrequency}s</span>
</div>
</div>
<div>
@@ -84,7 +84,7 @@ const ServerWidgetTab: React.FC<ServerWidgetTabProps> = ({ config, onChange }) =
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
className="flex items-center justify-between bg-white/10 p-2 rounded-lg"
className="liquid-surface flex items-center justify-between rounded-xl p-3"
>
<div>
<p className="font-semibold">{server.name}</p>
@@ -92,7 +92,8 @@ const ServerWidgetTab: React.FC<ServerWidgetTabProps> = ({ config, onChange }) =
</div>
<button
onClick={() => handleRemoveServer(server.id)}
className="text-red-500 hover:text-red-400"
className="liquid-edit-action liquid-focus text-red-300 hover:text-red-100"
aria-label={`Remove ${server.name}`}
>
<svg
xmlns="http://www.w3.org/2000/svg"
@@ -118,24 +119,24 @@ const ServerWidgetTab: React.FC<ServerWidgetTabProps> = ({ config, onChange }) =
)}
</Droppable>
</DragDropContext>
<div className="flex gap-2 mt-2">
<div className="flex flex-col gap-2 mt-3 sm:flex-row">
<input
type="text"
placeholder="Server Name"
value={newServerName}
onChange={(e) => setNewServerName(e.target.value)}
className="bg-white/10 p-2 rounded-lg w-full focus:outline-none focus:ring-2 focus:ring-cyan-400"
className="liquid-input p-2.5"
/>
<input
type="text"
placeholder="HTTP Address"
value={newServerAddress}
onChange={(e) => setNewServerAddress(e.target.value)}
className="bg-white/10 p-2 rounded-lg w-full focus:outline-none focus:ring-2 focus:ring-cyan-400"
className="liquid-input p-2.5"
/>
<button
onClick={handleAddServer}
className="bg-cyan-500 hover:bg-cyan-400 text-white font-bold py-2 px-4 rounded-lg"
className="liquid-button liquid-button-primary liquid-focus py-2.5 px-4"
>
Add
</button>

View File

@@ -55,7 +55,7 @@ const ThemeTab: React.FC<ThemeTabProps> = ({
return (
<div className="flex flex-col gap-6">
<div className="flex items-center justify-between">
<div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
<label className="text-slate-300 text-sm font-semibold">Background</label>
<Dropdown
name="currentWallpapers"
@@ -66,7 +66,7 @@ const ThemeTab: React.FC<ThemeTabProps> = ({
/>
</div>
{Array.isArray(config.currentWallpapers) && config.currentWallpapers.length > 1 && (
<div className="flex items-center justify-between">
<div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
<label className="text-slate-300 text-sm font-semibold">Change Frequency</label>
<Dropdown
name="wallpaperFrequency"
@@ -83,7 +83,7 @@ const ThemeTab: React.FC<ThemeTabProps> = ({
/>
</div>
)}
<div className="flex items-center justify-between">
<div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
<label className="text-slate-300 text-sm font-semibold">Wallpaper Blur</label>
<div className="flex items-center gap-4">
<input
@@ -92,12 +92,12 @@ const ThemeTab: React.FC<ThemeTabProps> = ({
max="50"
value={config.wallpaperBlur}
onChange={(e) => onChange({ wallpaperBlur: Number(e.target.value) })}
className="w-48"
className="liquid-range"
/>
<span>{config.wallpaperBlur}px</span>
<span className="w-12 text-right text-sm text-slate-200">{config.wallpaperBlur}px</span>
</div>
</div>
<div className="flex items-center justify-between">
<div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
<label className="text-slate-300 text-sm font-semibold">Wallpaper Brightness</label>
<div className="flex items-center gap-4">
<input
@@ -106,12 +106,12 @@ const ThemeTab: React.FC<ThemeTabProps> = ({
max="200"
value={config.wallpaperBrightness}
onChange={(e) => onChange({ wallpaperBrightness: Number(e.target.value) })}
className="w-48"
className="liquid-range"
/>
<span>{config.wallpaperBrightness}%</span>
<span className="w-12 text-right text-sm text-slate-200">{config.wallpaperBrightness}%</span>
</div>
</div>
<div className="flex items-center justify-between">
<div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
<label className="text-slate-300 text-sm font-semibold">Wallpaper Opacity</label>
<div className="flex items-center gap-4">
<input
@@ -120,9 +120,9 @@ const ThemeTab: React.FC<ThemeTabProps> = ({
max="100"
value={config.wallpaperOpacity}
onChange={(e) => onChange({ wallpaperOpacity: Number(e.target.value) })}
className="w-48"
className="liquid-range"
/>
<span>{config.wallpaperOpacity}%</span>
<span className="w-12 text-right text-sm text-slate-200">{config.wallpaperOpacity}%</span>
</div>
</div>
{chromeStorageAvailable && (
@@ -133,12 +133,13 @@ const ThemeTab: React.FC<ThemeTabProps> = ({
{userWallpapers.map((wallpaper) => (
<div
key={wallpaper.name}
className="flex items-center justify-between bg-white/10 p-2 rounded-lg"
className="liquid-surface flex items-center justify-between rounded-xl p-2.5"
>
<span className="truncate">{wallpaper.name}</span>
<button
onClick={() => onDeleteWallpaper(wallpaper)}
className="text-red-500 hover:text-red-400"
className="liquid-edit-action liquid-focus text-red-300 hover:text-red-100"
aria-label={`Delete ${wallpaper.name}`}
>
<svg
xmlns="http://www.w3.org/2000/svg"
@@ -167,19 +168,19 @@ const ThemeTab: React.FC<ThemeTabProps> = ({
placeholder="Wallpaper Name (optional for URLs)"
value={newWallpaperName}
onChange={(e) => setNewWallpaperName(e.target.value)}
className="bg-white/10 p-2 rounded-lg w-full focus:outline-none focus:ring-2 focus:ring-cyan-400"
className="liquid-input p-2.5"
/>
<div className="flex gap-2">
<div className="flex flex-col gap-2 sm:flex-row">
<input
type="text"
placeholder="Image URL"
value={newWallpaperUrl}
onChange={(e) => setNewWallpaperUrl(e.target.value)}
className="bg-white/10 p-2 rounded-lg w-full focus:outline-none focus:ring-2 focus:ring-cyan-400"
className="liquid-input p-2.5"
/>
<button
onClick={handleAddWallpaper}
className="bg-cyan-500 hover:bg-cyan-400 active:scale-95 text-white font-bold py-2 px-4 rounded-lg transition-all duration-150 ease-ios"
className="liquid-button liquid-button-primary liquid-focus py-2.5 px-4"
>
Add
</button>
@@ -187,7 +188,7 @@ const ThemeTab: React.FC<ThemeTabProps> = ({
<div className="flex items-center justify-center w-full">
<label
htmlFor="file-upload"
className="flex flex-col items-center justify-center w-full h-32 border-2 border-dashed rounded-lg cursor-pointer bg-white/5 border-white/20 hover:bg-white/10"
className="liquid-surface liquid-ghost-tile flex flex-col items-center justify-center w-full h-32 cursor-pointer transition-all duration-200 ease-ios"
>
<div className="flex flex-col items-center justify-center pt-5 pb-6">
<svg
@@ -227,7 +228,7 @@ const ThemeTab: React.FC<ThemeTabProps> = ({
<button
onClick={onNextWallpaper}
disabled={config.currentWallpapers.length === 0}
className="flex items-center gap-2 bg-black/25 backdrop-blur-md border border-white/10 hover:bg-white/25 active:scale-95 disabled:opacity-40 disabled:cursor-not-allowed text-white text-sm font-semibold py-2 px-4 rounded-xl transition-all duration-150 ease-ios"
className="liquid-surface liquid-control liquid-focus disabled:opacity-40 disabled:cursor-not-allowed text-white text-sm font-semibold py-2 px-4 rounded-2xl"
>
<svg
xmlns="http://www.w3.org/2000/svg"

View File

@@ -15,6 +15,19 @@ interface CategoryGroupProps {
tileSize?: string;
}
const getAddTileSizeClass = (size: string | undefined) => {
switch (size) {
case 'small':
return 'w-28 h-28';
case 'medium':
return 'w-32 h-32';
case 'large':
return 'w-36 h-36';
default:
return 'w-32 h-32';
}
};
const CategoryGroup: React.FC<CategoryGroupProps> = ({
category,
isEditing,
@@ -29,23 +42,24 @@ const CategoryGroup: React.FC<CategoryGroupProps> = ({
}) => {
return (
<div key={category.id} className="w-full">
<div className={`flex ${getHorizontalAlignmentClass(horizontalAlignment)} items-center mb-4 w-full ${horizontalAlignment !== 'middle' ? 'px-8' : ''}`}>
<h2 className={`text-2xl font-bold text-white ${horizontalAlignment === 'left' ? 'text-left' : horizontalAlignment === 'right' ? 'text-right' : 'text-center'} ${horizontalAlignment !== 'middle' ? 'w-full' : ''}`}>{category.name}</h2>
<div className={`flex ${getHorizontalAlignmentClass(horizontalAlignment)} items-center mb-3 w-full ${horizontalAlignment !== 'middle' ? 'px-3 sm:px-8' : ''}`}>
<h2 className={`liquid-category-title text-2xl font-extrabold text-white ${horizontalAlignment === 'left' ? 'text-left' : horizontalAlignment === 'right' ? 'text-right' : 'text-center'} ${horizontalAlignment !== 'middle' ? 'w-full' : ''}`}>{category.name}</h2>
{isEditing && (
<button
onClick={() => {
setEditingCategory(category);
setIsCategoryModalOpen(true);
}}
className={`ml-2 text-white/50 hover:text-white transition-all duration-300 ease-in-out transform ${isEditing ? 'scale-100 opacity-100' : 'scale-0 opacity-0'}`}
className={`liquid-surface liquid-edit-action liquid-focus ml-2 shrink-0 transition-all duration-300 ease-spring transform ${isEditing ? 'scale-100 opacity-100' : 'scale-0 opacity-0'}`}
aria-label={`Edit ${category.name} category`}
>
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" className="bi bi-pencil" viewBox="0 0 16 16">
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" viewBox="0 0 16 16" aria-hidden="true">
<path d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z" />
</svg>
</button>
)}
</div>
<div className={`flex flex-wrap ${getHorizontalAlignmentClass(horizontalAlignment)} gap-6`}>
<div className={`flex flex-wrap ${getHorizontalAlignmentClass(horizontalAlignment)} gap-5 sm:gap-6 px-1 sm:px-0`}>
{category.websites.map((website) => (
<WebsiteTile
key={website.id}
@@ -59,12 +73,14 @@ const CategoryGroup: React.FC<CategoryGroupProps> = ({
{isEditing && (
<button
onClick={() => setAddingWebsite(category)}
className={`text-white/50 hover:text-white transition-all duration-300 ease-in-out transform ${isEditing ? 'scale-100 opacity-100' : 'scale-0 opacity-0'}`}
className={`liquid-surface liquid-control liquid-ghost-tile liquid-focus flex-col ${getAddTileSizeClass(tileSize)} transition-all duration-300 ease-spring transform ${isEditing ? 'scale-100 opacity-100' : 'scale-0 opacity-0'}`}
aria-label={`Add website to ${category.name}`}
>
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="currentColor" className="bi bi-plus-circle" viewBox="0 0 16 16">
<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" fill="currentColor" viewBox="0 0 16 16" aria-hidden="true">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z" />
<path d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4z" />
</svg>
<span className="text-sm font-bold">Add</span>
</button>
)}
</div>

View File

@@ -6,12 +6,13 @@ interface ConfigurationButtonProps {
const ConfigurationButton: React.FC<ConfigurationButtonProps> = ({ onClick }) => {
return (
<div className="absolute top-4 right-4">
<div className="absolute top-4 right-4 z-20">
<button
onClick={onClick}
className="bg-black/25 backdrop-blur-md border border-white/10 rounded-xl p-3 text-white flex items-center gap-2 hover:bg-white/25 active:scale-90 transition-all duration-200 ease-ios"
className="liquid-surface liquid-control liquid-focus rounded-2xl p-3"
aria-label="Open configuration"
>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<svg xmlns="http://www.w3.org/2000/svg" width="17" height="17" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
<circle cx="12" cy="12" r="3" stroke="currentColor" strokeWidth="2" fill="none"/>
<path stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 1 1-4 0v-.09a1.65 1.65 0 0 0-1-1.51 1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 1 1 0-4h.09c.7 0 1.31-.4 1.51-1a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06c.51.51 1.31.61 1.82.33.51-.28 1-.81 1-1.51V3a2 2 0 1 1 4 0v.09c0 .7.49 1.23 1 1.51.51.28 1.31.18 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82c.2.6.81 1 1.51 1H21a2 2 0 1 1 0 4h-.09c-.7 0-1.31.4-1.51 1z"/>
</svg>

View File

@@ -7,13 +7,13 @@ interface EditButtonProps {
const EditButton: React.FC<EditButtonProps> = ({ isEditing, onClick }) => {
return (
<div className="absolute top-4 left-4">
<div className="absolute top-4 left-4 z-20">
<button
onClick={onClick}
className="bg-black/25 backdrop-blur-md border border-white/10 rounded-xl p-3 text-white flex items-center gap-2 hover:bg-white/25 active:scale-90 transition-all duration-200 ease-ios"
style={{ fontSize: '12px' }}
className={`liquid-surface liquid-control liquid-focus rounded-2xl px-3.5 py-3 text-xs font-bold ${isEditing ? 'pr-4' : ''}`}
aria-label={isEditing ? 'Finish editing' : 'Edit page'}
>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" className="bi bi-pencil" viewBox="0 0 16 16">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16" aria-hidden="true">
<path d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z"/>
</svg>
{isEditing ? 'Done' : ''}

View File

@@ -56,16 +56,15 @@ const Header: React.FC<HeaderProps> = ({ config }) => {
return (
<>
{config.clock.enabled && (
<div className="absolute top-5 left-1/2 -translate-x-1/2 z-10 flex justify-center w-auto p-2">
<div className="absolute top-5 left-1/2 -translate-x-1/2 z-10 flex justify-center w-auto px-3 py-2">
<Clock config={config} getClockSizeClass={getClockSizeClass} />
</div>
)}
<div className={`flex flex-col ${config.alignment === 'bottom' ? 'mt-auto' : ''} items-center`}>
<div className={`relative z-10 flex flex-col ${config.alignment === 'bottom' ? 'mt-auto' : ''} items-center`}>
{config.title && (
<div className="text-center">
<h1
className={`${getTitleSizeClass(config.titleSize)} font-extrabold text-white tracking-tighter mb-3 mt-4`}
style={{ textShadow: '0 2px 4px rgba(0,0,0,0.5)' }}
className={`liquid-title-text ${getTitleSizeClass(config.titleSize)} font-extrabold text-white mb-2 mt-3`}
>
{config.title}
</h1>

View File

@@ -9,11 +9,11 @@ type RequiredLocalStorageKey = typeof REQUIRED_LOCAL_STORAGE_KEYS[number];
export const DEFAULT_CONFIG: Config = {
title: 'Vision Start',
currentWallpapers: ['Abstract'],
currentWallpapers: ['Beach'],
wallpaperFrequency: '1d',
wallpaperBlur: 0,
wallpaperBrightness: 100,
wallpaperOpacity: 100,
wallpaperBrightness: 108,
wallpaperOpacity: 96,
titleSize: 'medium',
alignment: 'middle',
horizontalAlignment: 'middle',