initial commit

This commit is contained in:
sHa
2025-03-19 15:42:10 +02:00
commit 8fa4d61b4e
7 changed files with 924 additions and 0 deletions

115
README.md Normal file
View File

@@ -0,0 +1,115 @@
# Theme Switcher Demo
A lightweight, elegant theme switcher for web applications that allows users to toggle between light, dark, and system themes, along with custom accent colors.
## Features
- **Multiple theme options**:
- Light mode
- Dark mode
- System preference detection
- **Custom accent color** selection
- **Persistent settings** using localStorage
- **Responsive design** that works on all screen sizes
- **No flash of unstyled content** when loading in dark mode
- **Modern UI** with accessible controls
- **Smooth transitions** between themes
## Demo
The project includes a demo page with various UI elements to showcase the theme switching capabilities:
- Text elements (headings, paragraphs)
- Cards with different backgrounds
- Buttons
- Form elements
- Footer
## How It Works
### Theme Switching
The theme switcher allows users to select between three theme options:
- **Light**: Forces light theme regardless of system settings
- **Dark**: Forces dark theme regardless of system settings
- **System**: Automatically follows the user's system preference
### Accent Color
Users can customize the accent color used throughout the interface:
1. Click on the color preview in the theme menu
2. Select a color using the color picker
3. The accent color is applied across buttons, headings, and UI accents
### Persistence
User preferences are stored in the browser's localStorage, so theme settings persist between visits.
## Usage
1. Include the CSS and JavaScript files in your project
2. Add the theme toggle HTML markup
3. Initialize the theme switcher with JavaScript
```html
<link rel="stylesheet" href="styles.css">
<script src="script.js"></script>
```
## Implementation Details
### Preventing Flash
To prevent flash of unstyled content when loading in dark mode, the project includes an inline script in the head that sets the theme before the page renders:
```html
<script>
// Immediately set theme before page renders
const savedTheme = localStorage.getItem('preferred-theme') || 'system';
if (savedTheme === 'dark') {
document.documentElement.setAttribute('data-theme', 'dark');
} else if (savedTheme === 'system') {
const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)').matches;
document.documentElement.setAttribute('data-theme', prefersDarkScheme ? 'dark' : 'light');
}
</script>
```
### CSS Variables
The theme switcher uses CSS custom properties (variables) to define theme colors:
```css
:root {
--background-color: #ffffff;
--text-color: #333333;
--accent-color: #4a90e2;
/* more variables... */
}
[data-theme="dark"] {
--background-color: #1a1a1a;
--text-color: #f5f5f5;
/* more variables... */
}
```
## Browser Support
This theme switcher works in all modern browsers that support:
- CSS Custom Properties (variables)
- localStorage API
- matchMedia API
## License
This project is available for use under the MIT License.
## Author
Created by sHa.
## Getting Started
1. Clone the repository
2. Open index.html in your browser
3. Try switching between themes and selecting custom accent colors

95
index.html Normal file
View File

@@ -0,0 +1,95 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Theme Switcher Demo</title>
<script>
// Immediately set theme before page renders
const savedTheme = localStorage.getItem('preferred-theme') || 'system';
if (savedTheme === 'dark') {
document.documentElement.setAttribute('data-theme', 'dark');
} else if (savedTheme === 'system') {
const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)').matches;
document.documentElement.setAttribute('data-theme', prefersDarkScheme ? 'dark' : 'light');
}
</script>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header>
<h1>Theme Switcher Demo</h1>
<div class="theme-controls">
<button id="theme-menu-toggle" class="theme-menu-toggle" aria-label="Theme settings">
<img id="toggle-icon" src="system.svg" alt="Theme settings" />
</button>
<div id="theme-menu" class="theme-menu">
<div class="menu-section">
<h4>Theme</h4>
<div class="theme-button-group">
<button class="theme-button" data-theme="light" aria-label="Light theme">
<img src="sun.svg" alt="Light theme" class="theme-icon" />
<span>Light</span>
</button>
<button class="theme-button" data-theme="dark" aria-label="Dark theme">
<img src="moon.svg" alt="Dark theme" class="theme-icon" />
<span>Dark</span>
</button>
<button class="theme-button" data-theme="system" aria-label="System theme">
<img src="system.svg" alt="System theme" class="theme-icon" />
<span>System</span>
</button>
</div>
</div>
<div class="menu-section">
<h4>Accent Color</h4>
<div class="accent-color-control">
<input type="color" id="accent-color" value="#4a90e2">
<span class="accent-color-preview" id="accent-color-preview"></span>
<label for="accent-color">Select accent color</label>
</div>
</div>
</div>
</div>
</header>
<main>
<section class="content">
<h2>Welcome to the Theme Switcher</h2>
<p>This is a demonstration of a theme switcher that allows you to choose between light, dark, or system theme preferences.</p>
<p>Your theme preference will be stored in local storage and remembered when you return.</p>
</section>
<section class="demo-elements">
<h3>Demo Elements</h3>
<div class="card">
<h4>Sample Card</h4>
<p>This is a sample card element to demonstrate theming capabilities.</p>
<button class="btn">Sample Button</button>
</div>
<form class="demo-form">
<h4>Sample Form</h4>
<div class="form-group">
<label for="name">Name:</label>
<input type="text" id="name" placeholder="Enter your name">
</div>
<div class="form-group">
<label for="email">Email:</label>
<input type="email" id="email" placeholder="Enter your email">
</div>
<button type="submit" class="btn">Submit</button>
</form>
</section>
</main>
<footer>
<p>Developed by sHa. Theme Switcher Demo</p>
</footer>
<script src="script.js"></script>
</body>
</html>

5
moon.svg Normal file
View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="currentColor">
<path fill="none" d="M0 0h24v24H0z" />
<path
d="M10 7a7 7 0 0 0 12 4.9v.1c0 5.523-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2h.1A6.979 6.979 0 0 0 10 7zm-6 5a8 8 0 0 0 15.062 3.762A9 9 0 0 1 8.238 4.938 7.999 7.999 0 0 0 4 12z" />
</svg>

After

Width:  |  Height:  |  Size: 356 B

138
script.js Normal file
View File

@@ -0,0 +1,138 @@
document.addEventListener('DOMContentLoaded', () => {
const themeMenuToggle = document.getElementById('theme-menu-toggle');
const toggleIcon = document.getElementById('toggle-icon');
const themeMenu = document.getElementById('theme-menu');
const themeButtons = document.querySelectorAll('.theme-button');
const accentColorInput = document.getElementById('accent-color');
const accentColorPreview = document.getElementById('accent-color-preview');
console.log('Theme switcher initialized');
// Function to update toggle icon based on theme
const updateToggleIcon = (theme) => {
const iconPath = theme === 'light' ? 'sun.svg' :
theme === 'dark' ? 'moon.svg' : 'system.svg';
toggleIcon.src = iconPath;
console.log(`Updated toggle icon to: ${iconPath}`);
};
// Function to set theme
const setTheme = (theme) => {
console.log(`Setting theme preference to: ${theme}`);
let appliedTheme;
if (theme === 'system') {
// Check system preference
const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)').matches;
appliedTheme = prefersDarkScheme ? 'dark' : 'light';
console.log(`System preference detected: ${appliedTheme}`);
} else {
// Set specific theme
appliedTheme = theme;
}
// Apply the determined theme
document.documentElement.setAttribute('data-theme', appliedTheme);
// Update toggle icon to reflect current theme
updateToggleIcon(theme);
// Update active state in button group
themeButtons.forEach(button => {
if (button.getAttribute('data-theme') === theme) {
button.classList.add('active');
// Apply accent color dynamically to active button
button.style.backgroundColor = getComputedStyle(document.documentElement).getPropertyValue('--accent-color');
} else {
button.classList.remove('active');
button.style.backgroundColor = '';
}
});
console.log(`Applied theme: ${appliedTheme}`);
// Save to localStorage
localStorage.setItem('preferred-theme', theme);
};
// Function to set accent color
const setAccentColor = (color) => {
console.log(`Setting accent color to: ${color}`);
document.documentElement.style.setProperty('--accent-color', color);
// Convert hex to RGB for the accent-color-rgb variable
const r = parseInt(color.slice(1, 3), 16);
const g = parseInt(color.slice(3, 5), 16);
const b = parseInt(color.slice(5, 7), 16);
document.documentElement.style.setProperty('--accent-color-rgb', `${r}, ${g}, ${b}`);
// Update active button with new accent color
const activeButton = document.querySelector('.theme-button.active');
if (activeButton) {
activeButton.style.backgroundColor = color;
}
accentColorInput.value = color;
accentColorPreview.style.backgroundColor = color;
localStorage.setItem('accent-color', color);
};
// Toggle theme menu
themeMenuToggle.addEventListener('click', (e) => {
themeMenu.classList.toggle('active');
e.stopPropagation();
});
// Close menu when clicking outside
document.addEventListener('click', (e) => {
if (!themeMenu.contains(e.target) && e.target !== themeMenuToggle) {
themeMenu.classList.remove('active');
}
});
// Theme button selection
themeButtons.forEach(button => {
button.addEventListener('click', () => {
const theme = button.getAttribute('data-theme');
console.log(`Theme changed by user to: ${theme}`);
setTheme(theme);
});
});
// Accent color preview click opens color picker
accentColorPreview.addEventListener('click', () => {
accentColorInput.click();
});
// Event listener for accent color change
accentColorInput.addEventListener('change', (e) => {
console.log(`Accent color changed by user to: ${e.target.value}`);
setAccentColor(e.target.value);
});
// Load saved theme or use system default
const savedTheme = localStorage.getItem('preferred-theme') || 'system';
console.log(`Loading saved theme from localStorage: ${savedTheme}`);
setTheme(savedTheme);
// Load saved accent color or use default
const savedAccentColor = localStorage.getItem('accent-color') || '#4a90e2';
console.log(`Loading saved accent color from localStorage: ${savedAccentColor}`);
setAccentColor(savedAccentColor);
// Listen for system theme changes when in "system" mode
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
console.log(`System theme preference changed. Dark mode: ${e.matches}`);
const currentTheme = localStorage.getItem('preferred-theme');
if (currentTheme === 'system') {
setTheme('system');
}
});
// Enable transitions after initial load (prevents flash of white)
setTimeout(() => {
document.documentElement.classList.add('transitions-enabled');
console.log('Theme transitions enabled');
}, 100);
});

555
styles.css Normal file
View File

@@ -0,0 +1,555 @@
html {
transition: none;
}
:root {
/* Light theme variables (default) */
--background-color: #ffffff;
--text-color: #333333;
--text-invert-color: #f5f5f5;
--header-bg: #f5f5f5;
--footer-bg: #f5f5f5;
--card-bg: #ffffff;
--border-color: #dddddd;
--accent-color: #4a90e2; /* Default accent color */
--accent-color-rgb: 74, 144, 226; /* RGB values of accent color */
--button-bg: var(--accent-color);
--button-text: #ffffff;
--input-bg: #ffffff;
--input-border: #cccccc;
--form-bg: #f9f9f9;
}
/* Dark theme variables */
[data-theme="dark"] {
--background-color: #1a1a1a;
--text-color: #f5f5f5;
--text-invert-color: #33333;
--header-bg: #2c2c2c;
--footer-bg: #2c2c2c;
--card-bg: #2c2c2c;
--border-color: #444444;
--accent-color: #4a90e2; /* Default accent color */
--accent-color-rgb: 74, 144, 226; /* RGB values of accent color */
--button-bg: var(--accent-color);
--button-text: #ffffff;
--input-bg: #333333;
--input-border: #555555;
--form-bg: #252525;
}
/* Add a class to re-enable transitions after page load */
html.transitions-enabled {
transition: background-color 0.3s ease, color 0.3s ease;
}
/* Global styles */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* Global layout structure - using grid */
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: var(--background-color);
color: var(--text-color);
line-height: 1.6;
transition: background-color 0.3s ease, color 0.3s ease;
display: grid;
grid-template-areas:
"header"
"main"
"footer";
grid-template-rows: auto 1fr auto;
min-height: 100vh;
margin: 0;
}
header {
grid-area: header;
background-color: var(--header-bg);
padding: 1rem 2rem;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid var(--border-color);
flex-wrap: wrap;
gap: 1rem;
}
.theme-controls {
position: relative;
display: flex;
align-items: center;
}
.theme-menu-toggle {
background-color: var(--card-bg);
border: 1px solid var(--border-color);
border-radius: 50%;
width: 40px;
height: 40px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
padding: 8px;
transition: background-color 0.3s, box-shadow 0.3s;
}
.theme-menu-toggle:hover {
background-color: var(--background-color);
box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
}
.theme-menu-toggle svg {
fill: var(--accent-color);
}
.theme-menu-toggle img,
.theme-button img {
width: 24px;
height: 24px;
fill: var(--accent-color);
transition: all 0.2s;
}
.theme-menu-toggle img,
.theme-button img {
filter: invert(50%) sepia(50%) saturate(1000%) hue-rotate(190deg) brightness(90%) contrast(95%);
}
.theme-button.active img {
filter: invert(100%);
}
.theme-menu {
position: absolute;
top: calc(100% + 8px);
right: 0;
background-color: var(--card-bg);
border: 1px solid var(--border-color);
border-radius: 12px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
width: 320px;
padding: 20px;
opacity: 0;
visibility: hidden;
transform: translateY(-10px);
transition: opacity 0.3s, transform 0.3s, visibility 0s linear 0.3s;
z-index: 100;
}
.theme-menu.active {
opacity: 1;
visibility: visible;
transform: translateY(0);
transition: opacity 0.3s, transform 0.3s, visibility 0s;
}
.menu-section {
margin-bottom: 20px;
width: 100%;
}
.menu-section:last-child {
margin-bottom: 0;
}
.menu-section h4 {
margin-bottom: 15px;
font-size: 14px;
opacity: 0.8;
}
.theme-button-group {
display: flex;
background-color: var(--background-color);
border-radius: 8px;
padding: 4px;
border: 1px solid var(--border-color);
width: 100%;
box-sizing: border-box;
margin-bottom: 8px;
}
.theme-button {
flex: 1;
padding: 10px 12px; /* Slightly more vertical padding */
border: none;
background: none;
border-radius: 6px;
cursor: pointer;
display: flex;
flex-direction: column;
align-items: center;
gap: 6px;
color: var(--text-color);
transition: all 0.2s;
}
.theme-button svg {
width: 18px;
height: 18px;
fill: var(--text-color);
transition: fill 0.2s;
}
/* Active button uses accent color */
.theme-button.active {
background-color: var(--accent-color);
color: white;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
/* Override active button styling */
.theme-button.active {
background-color: var(--accent-color);
color: white;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
.theme-button.active svg {
fill: white; /* White icon when button is active */
}
/* Theme-specific icon styling for better visual cues */
.theme-button[data-theme="light"] svg {
color: #f9a825; /* Sunny yellow for light theme */
}
.theme-button[data-theme="dark"] svg {
color: #9fa8da; /* Soft blue for dark theme */
}
.theme-button[data-theme="system"] svg {
color: #78909c; /* Neutral blue-grey for system */
}
/* Override fill when active */
.theme-button.active[data-theme="light"] svg,
.theme-button.active[data-theme="dark"] svg,
.theme-button.active[data-theme="system"] svg {
fill: white;
}
/* Accent Color Styles */
.accent-color-control {
display: flex;
align-items: center;
gap: 15px;
width: 100%; /* Ensure full width */
}
#accent-color {
width: 0;
height: 0;
opacity: 0;
position: absolute;
}
.accent-color-preview {
width: 30px;
height: 30px;
border-radius: 50%;
background-color: var(--accent-color);
border: 2px solid var(--border-color);
cursor: pointer;
transition: transform 0.2s;
}
.accent-color-preview:hover {
transform: scale(1.1);
}
.accent-color-control label {
font-size: 14px;
cursor: pointer;
}
/* Main content styles - using grid */
main {
grid-area: main;
max-width: 1200px;
margin: 2rem auto;
padding: 0 2rem;
width: 100%;
display: grid;
grid-template-columns: 1fr;
gap: 2rem;
}
/* For wider screens, use two columns for content sections */
@media (min-width: 768px) {
main {
grid-template-columns: repeat(2, 1fr);
}
/* Make some sections span full width */
.content {
grid-column: 1 / -1;
}
}
/* Section styles - using flexbox */
section {
margin-bottom: 2rem;
display: flex;
flex-direction: column;
gap: 1rem;
}
h1, h2, h3, h4 {
margin-bottom: 1rem;
color: var(--accent-color);
}
p {
margin-bottom: 1rem;
}
a {
color: var(--accent-color);
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
/* Card styles - using flexbox */
.card {
background-color: var(--card-bg);
border: 1px solid var(--border-color);
border-radius: 8px;
padding: 1.5rem;
margin-bottom: 1.5rem;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
display: flex;
flex-direction: column;
gap: 1rem;
}
/* Button styles */
.btn {
background-color: var(--button-bg);
color: var(--button-text);
border: none;
padding: 0.75rem 1.5rem;
border-radius: 4px;
cursor: pointer;
font-size: 1rem;
transition: background-color 0.3s;
}
.btn:hover {
background-color: var(--button-bg);
opacity: 0.9;
}
/* Demo form - using grid */
.demo-form {
background-color: var(--form-bg);
padding: 1.5rem;
border-radius: 8px;
border: 1px solid var(--border-color);
display: grid;
grid-template-columns: 1fr;
gap: 1rem;
}
@media (min-width: 576px) {
.demo-form {
grid-template-columns: repeat(2, 1fr);
}
.form-group {
grid-column: span 1;
}
.demo-form h4 {
grid-column: 1 / -1;
}
.demo-form button {
grid-column: 1 / -1;
justify-self: start;
}
}
/* Form group styles - using flexbox */
.form-group {
margin-bottom: 1rem;
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.form-group label {
display: block;
margin-bottom: 0.5rem;
}
.form-group input {
width: 100%;
padding: 0.75rem;
border: 1px solid var(--input-border);
border-radius: 4px;
background-color: var(--input-bg);
color: var(--text-color);
}
/* Footer styles - using flexbox */
footer {
grid-area: footer;
background-color: var(--footer-bg);
text-align: center;
padding: 0.5rem 1.5rem;
border-top: 1px solid var(--border-color);
display: flex;
justify-content: center;
align-items: center;
}
footer p {
margin: 0;
color: var(--text-color);
}
/* Theme Dropdown Styles */
.theme-dropdown {
position: relative;
display: inline-block;
}
.theme-toggle {
background-color: var(--card-bg);
border: 1px solid var(--border-color);
border-radius: 50%;
width: 40px;
height: 40px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
padding: 8px;
transition: background-color 0.3s, box-shadow 0.3s;
}
.theme-toggle:hover {
background-color: var(--background-color);
box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
}
.theme-icon {
display: flex;
align-items: center;
justify-content: center;
}
.theme-icon svg {
fill: var(--text-color);
transition: fill 0.3s;
}
/* Hide all icons by default */
.theme-toggle .theme-icon {
display: none;
}
/* Show only the current theme icon */
[data-theme="light"] .theme-toggle .light-icon,
.theme-toggle .light-icon {
display: flex;
}
[data-theme="dark"] .theme-toggle .light-icon {
display: none;
}
[data-theme="dark"] .theme-toggle .dark-icon {
display: flex;
}
[data-theme="system"] .theme-toggle .light-icon,
[data-theme="system"] .theme-toggle .dark-icon {
display: none;
}
[data-theme="system"] .theme-toggle .system-icon {
display: flex;
}
.theme-button[data-theme="dark"]{
color: var(--text-invert-color) !important;
}
[data-theme="light"] .theme-button[data-theme="dark"]>svg {
fill: var(--text-invert-color);
}
.theme-menu {
position: absolute;
top: calc(100% + 8px);
right: 0;
background-color: var(--card-bg);
border: 1px solid var(--border-color);
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
opacity: 0;
visibility: hidden;
transform: translateY(-10px);
transition: opacity 0.3s, transform 0.3s, visibility 0s linear 0.3s;
z-index: 100;
color: var(--text-color) !important;
}
.theme-dropdown.active .theme-menu {
opacity: 1;
visibility: visible;
transform: translateY(0);
transition: opacity 0.3s, transform 0.3s, visibility 0s;
}
/* Clean slate for theme option styling */
.theme-option {
display: flex;
align-items: center;
padding: 10px 15px;
border: none;
background: none;
width: 100%;
text-align: left;
cursor: pointer;
transition: background-color 0.2s;
/* Force the text color to match the parent document theme */
color: var(--text-color);
}
/* Make icons match text color */
.theme-option .theme-icon svg {
fill: var(--text-color);
}
/* Hover states */
.theme-option:hover {
background-color: rgba(0, 0, 0, 0.05);
}
[data-theme="dark"] .theme-option:hover {
background-color: rgba(255, 255, 255, 0.05);
}
/* Active state styling */
.theme-option.active {
background-color: var(--accent-color);
}
.theme-option.active,
.theme-option.active .theme-icon svg {
/* Force white for active option regardless of theme */
color: white;
fill: white;
}

5
sun.svg Normal file
View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="currentColor">
<path fill="none" d="M0 0h24v24H0z" />
<path
d="M12 18a6 6 0 1 1 0-12 6 6 0 0 1 0 12zM11 1h2v3h-2V1zm0 19h2v3h-2v-3zM3.515 4.929l1.414-1.414L7.05 5.636 5.636 7.05 3.515 4.93zM16.95 18.364l1.414-1.414 2.121 2.121-1.414 1.414-2.121-2.121zm2.121-14.85l1.414 1.415-2.121 2.121-1.414-1.414 2.121-2.121zM5.636 16.95l1.414 1.414-2.121 2.121-1.414-1.414 2.121-2.121zM23 11v2h-3v-2h3zM4 11v2H1v-2h3z" />
</svg>

After

Width:  |  Height:  |  Size: 522 B

11
system.svg Normal file
View File

@@ -0,0 +1,11 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="currentColor">
<rect x="0" y="-3.059" width="26.969" height="26.969" style="fill:none;" />
<rect x="12.361" y="19.415" width="2.247" height="3.371" />
<path d="M3.95,2.48l1.589,-1.589l2.383,2.383l-1.589,1.589l-2.383,-2.383Z" />
<path d="M19.047,17.577l1.589,-1.589l2.384,2.384l-1.589,1.588l-2.384,-2.383Z" />
<path d="M6.333,15.988l1.589,1.589l-2.383,2.383l-1.589,-1.588l2.383,-2.384Z" />
<rect x="1.124" y="9.302" width="3.371" height="2.247" />
<path
d="M12.158,7.063c0,-0 0,0 0,0c0,2.586 2.128,4.714 4.713,4.714c1.267,-0 2.481,-0.511 3.367,-1.415l-0,0.067c-0,3.719 -3.015,6.734 -6.733,6.734c-3.719,-0 -6.734,-3.015 -6.734,-6.734c0,-3.718 3.015,-6.733 6.734,-6.733l0.067,0c-0.906,0.885 -1.416,2.1 -1.414,3.367Zm-4.04,3.366c0,0.001 0,0.002 0,0.003c0,2.955 2.432,5.386 5.387,5.386c1.988,0 3.821,-1.101 4.755,-2.856c-0.456,0.108 -0.922,0.162 -1.39,0.162c-3.324,-0 -6.06,-2.736 -6.06,-6.06c0,-0.468 0.054,-0.934 0.162,-1.39c-1.755,0.935 -2.854,2.768 -2.854,4.755Z"
style="fill-rule:nonzero;" />
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB