Implemented InlineSvg component to fetch and color SVG logos dynamically.

This commit is contained in:
sHa
2025-04-29 12:16:41 +03:00
parent 69f6f30cb3
commit 3d90d9b0da
9 changed files with 380 additions and 34 deletions

View File

@@ -20,8 +20,8 @@
]
},
{
"name": "Apple (black)",
"path": "logos/apple_black.svg",
"name": "Apple",
"path": "logos/apple.svg",
"format": "SVG",
"disable": false,
"tags": [
@@ -29,19 +29,16 @@
"text": "tech",
"color": "silver"
}
]
},
{
"name": "Apple (silver)",
"path": "logos/apple_silver.svg",
"format": "SVG",
"disable": false,
"tags": [
{
"text": "tech",
"color": "silver"
}
]
],
"colors": [
{ "label": "Silver", "value": "#999" },
{ "label": "White", "value": "#fff" },
{ "label": "Black", "value": "#000" }
],
"colorConfig": {
"target": "path",
"attribute": "fill"
}
},
{
"name": "ATB",
@@ -315,6 +312,26 @@
"furniture"
]
},
{
"name": "Sendpulse Small",
"path": "logos/sendpulse-small.svg",
"format": "SVG",
"disable": false,
"tags": [
"marketing",
"email"
]
},
{
"name": "Sendpulse",
"path": "logos/sendpulse.svg",
"format": "SVG",
"disable": false,
"tags": [
"marketing",
"email"
]
},
{
"name": "Shkafnik",
"path": "logos/shkafnik.svg",

View File

Before

Width:  |  Height:  |  Size: 675 B

After

Width:  |  Height:  |  Size: 675 B

View File

@@ -1 +0,0 @@
<svg width="100%" height="100%" viewBox="0 0 1100 1100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"><g><path d="M695.579,184.597c18.506,-22.393 33.973,-49.186 43.976,-78.123c10.015,-28.955 14.535,-60.049 11.135,-91.073c-26.66,1.075 -56.128,9.969 -83.708,24.178c-27.568,14.218 -53.264,33.758 -72.385,56.136c-17.138,19.821 -33.225,45.599 -44.007,74.022c-10.781,28.414 -16.259,59.488 -12.21,89.89c29.729,2.308 59.775,-5.251 87.016,-18.978c27.243,-13.733 51.673,-33.644 70.183,-56.052Z"/><path d="M900.01,745.451c35.18,33.47 70.36,46.979 71.14,47.319c-0.59,1.891 -6.15,20.9 -17.96,48.77c-11.8,27.88 -29.83,64.62 -55.38,101.95c-22.08,32.27 -44.58,64.5 -70.58,88.8c-26.02,24.32 -55.52,40.73 -91.634,41.4c-35.476,0.65 -58.913,-9.86 -83.622,-20.55c-24.716,-10.68 -50.703,-21.52 -91.26,-21.52c-40.548,-0 -67.156,10.18 -92.028,20.7c-24.874,10.51 -47.998,21.35 -81.589,22.68c-34.841,1.32 -65.535,-16.14 -93.082,-41.96c-27.559,-25.82 -51.961,-60.01 -74.218,-92.16c-45.502,-65.79 -85.641,-158.719 -102.729,-255.487c-17.086,-96.758 -11.131,-197.342 35.566,-278.41c23.192,-40.264 55.508,-73.131 93.276,-96.107c37.77,-22.975 80.994,-36.059 125.981,-36.71c34.228,-0.649 67.49,10.865 97.422,22.537c29.938,11.677 56.546,23.519 77.467,23.519c20.906,-0 50.986,-14.242 86.163,-27.436c35.167,-13.188 75.419,-25.336 116.687,-21.15c17.28,0.716 50.16,4.211 86.51,18.909c36.34,14.706 76.16,40.624 107.3,86.2c-2.51,1.555 -31.44,18.448 -59.59,51.704c-78.5,92.761 -72.3,232.832 16.16,317.002Z"/></g></svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="29.5 29.5 300 300"
enable-background="new 29.5 29.5 300 300" xml:space="preserve">
<rect x="29.5" y="29.5" fill="#009FC1" width="300" height="300" />
<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M147.3,280h-25.9l-18.3-75.1H68.5v-24.2h57.1l9.5,39.8L172.6,79
h26.7l13,106.6h29.1c4.4-8,13-13.4,23-13.4c14.4,0,26,11.3,26,25.4c0,14-11.7,25.4-26,25.4c-10,0-18.4-5.4-23-13.4h-52.8l-7.8-53.8
L147.3,280z" />
</svg>

After

Width:  |  Height:  |  Size: 496 B

View File

@@ -0,0 +1,36 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
viewBox="0 0 334 75" enable-background="new 0 0 334 75" xml:space="preserve">
<path fill="#199FC0" d="M235.3,44.8v2.3c0,3.1-1.1,5.4-3.5,6.7c-2.2,1.2-5.1,1.8-8.9,1.8c-3,0-6-0.2-9-0.6l-0.9-0.1v-0.9v-3.7v-1.2
l1.2,0.2c4.2,0.7,7.1,1,8.8,1c2.1,0,3.5-0.2,4.4-0.5c0.4-0.2,0.5-0.2,0.6-0.5c0.2-0.3,0.3-0.5,0.2-1v-2.7c0-0.9-0.3-1.2-0.6-1.4
c-0.5-0.3-1.4-0.5-3-0.5h-2.9c-2.8,0-5.1-0.6-6.8-1.9c-1.7-1.3-2.5-3.2-2.5-5.5v-2.4c0-2.5,1.2-4.3,3.5-5.5c2.2-1.1,5.2-1.7,9.1-1.7
c0.9,0,3.5,0.2,7.9,0.4l1,0.1v1v3.5v1.3l-1.2-0.2c-2.6-0.5-5.2-0.7-7.8-0.8c-2.5,0-4,0.3-4.6,0.6c-0.5,0.3-0.8,0.7-0.8,1.6v2.2
c0,0.5,0.2,0.8,0.6,1c0.5,0.3,1.5,0.5,3,0.5h1.9h1.1c2.8,0,5.1,0.5,6.8,1.8C234.5,40.6,235.3,42.5,235.3,44.8z M201.1,17.4H200V19
v34.9V55h1.1h4.8h1.1v-1.1V19v-1.6h-1.1H201.1z M264.5,36.3V42v1.2h-1.1h-16.2v2.7c0,1.6,0.5,2.5,1.4,3c1,0.6,2.7,1,5.1,1
c2.4,0,5.1-0.4,8.4-1.2l1.4-0.3v1.4v3.6v0.9l-0.9,0.2c-3.1,0.7-6.4,1.1-9.6,1.1c-4.1,0-7.2-0.6-9.5-2.1c-2.3-1.6-3.4-3.9-3.4-6.9
V36.3c0-3.4,1-6,3.1-7.7c2.1-1.6,5.3-2.3,9.3-2.3c3.8,0,6.8,0.6,8.8,2.2C263.6,30.1,264.5,32.8,264.5,36.3z M257.5,34.8
c0-1.3-0.4-2-0.9-2.3c-0.7-0.4-2-0.7-4.2-0.7c-2.1,0-3.4,0.3-4.2,0.7c-0.5,0.3-1,1-1,2.4v3.1h10.3V34.8z M188.3,26.9h-1.1v1.1v19.6
c0,1-0.3,1.5-0.9,1.8c-0.8,0.4-2.4,0.6-5.1,0.6c-0.9,0-1.8-0.1-2.7-0.3c-0.5-0.1-0.8-0.3-1.1-0.6c-0.2-0.3-0.4-0.5-0.5-0.9
c-0.1-0.5-0.2-0.9-0.1-1.3V27.9v-1.1h-1.1h-4.8h-1.1v1.1V47c0,2.7,0.7,4.9,2.3,6.4c1.6,1.6,4.3,2.1,7.8,2.1c2.6,0,4.8-0.3,6.4-1
c0.3-0.2,0.6-0.3,1-0.5v1h1.1h4.8h1.1v-1.1v-26v-1.1h-1.1H188.3z M313.2,35.9c-2.2,0-4.1,1.2-5,3h-6.3l-2.8-23.6h-5.8l-8.2,31.4
l-2.1-8.8h-12.4v5.4h7.6l3.9,16.6h5.6l7.3-27.5l1.6,11.1l0.2,0.9h11.5c1,1.8,2.8,3,5,3c3.1,0,5.7-2.5,5.7-5.6
C318.9,38.5,316.3,35.9,313.2,35.9z M163.5,22.4c0.5,1.1,0.9,3.6,0.9,3.6v7.2c0,3.3-1.3,5.8-4,7.2c-2.5,1.3-5.9,2-10.2,2h-4.2v11.5
V55h-1.1h-5.2h-1.1v-1.1V19.1V18h1.1H151c1.5,0,2.7,0.1,3.7,0.1c1.1,0.1,2.3,0.3,3.4,0.5c1.1,0.2,2.2,0.7,3.1,1.3
C162.2,20.6,162.9,21.4,163.5,22.4z M157.1,26.5c0.1-0.6-0.1-1.2-0.5-1.7c-0.4-0.5-0.9-0.8-1.5-0.9c-0.7-0.2-1.4-0.3-2.1-0.4
c-0.6-0.1-1.3-0.1-2.2-0.1h-4.7v13.6h4.8c1.9,0,3.4-0.3,4.8-1c1-0.5,1.6-1.5,1.6-3.1L157.1,26.5z M31.2,32.9H27
c-2.2,0-3.4-0.3-3.9-0.6c-0.5-0.3-0.8-0.8-0.8-1.8v-4c0-1.3,0.4-2,1.1-2.4c0.4-0.2,1-0.4,2.1-0.6c1-0.2,2.3-0.2,3.9-0.2
c2.2,0,5.2,0.3,9.1,0.9l1.2,0.2v-1.2v-4v-1l-1-0.1c-3-0.4-6-0.6-9-0.6c-5.2,0-9,0.6-11.3,2.2c-2.2,1.6-3.3,3.9-3.3,7v2.8
c0,2.9,0.7,5.3,2.3,7c1.7,1.7,4.5,2.5,8.1,2.5h4.1c2.2,0,3.3,0.3,3.8,0.7c0.5,0.3,0.8,1,0.8,2.3v4.5c0,0.7-0.1,1.1-0.3,1.6
c-0.2,0.4-0.4,0.6-1,0.8c-1.1,0.5-2.8,0.8-5.2,0.8c-3,0-6.5-0.4-10.6-1.3l-1.3-0.3v1.3v4.3v0.9l1,0.2c3.5,0.5,7.1,0.8,10.7,0.9
c4.5,0,8.1-0.7,10.4-2.3c2.5-1.7,3.6-4.7,3.6-8.6v-2.5c0-3-0.6-5.4-2.2-6.9C37.6,33.5,34.8,32.9,31.2,32.9z M131,17.4h1.1V19v34.9
V55H131h-4.7h-1.1v-1.1c-0.3,0.2-0.5,0.3-0.8,0.4c-1.7,0.8-4.1,1.2-6.8,1.2c-3.8,0-6.7-0.6-8.5-2c-1.9-1.5-2.7-4.1-2.7-7.4V34.8
c0-2.8,0.9-5.1,2.9-6.5c1.9-1.3,4.9-1.9,8.6-1.9c2,0,4.1,0.3,5.9,0.9c0.4,0.2,0.9,0.3,1.3,0.5c0-1.4-0.1-2.7-0.1-3.5V19v-1.6h1.1
h3.7H131z M125.2,34.3c0-0.7-0.3-1.2-1.2-1.7c-1-0.5-2.5-0.8-4.8-0.8c-1.4,0-2.5,0.1-3.4,0.2c-0.9,0.1-1.4,0.3-1.7,0.4
c-0.3,0.2-0.7,0.6-0.7,1.9v12.8c0,1.2,0.4,1.8,1,2.2c0.7,0.4,2.1,0.8,4.4,0.8c2.6,0,4.3-0.3,5.2-0.8c0.8-0.4,1.2-1,1.2-2.1V34.3
L125.2,34.3z M71,36.3V42v1.2H70H53.7v2.7c0,1.6,0.5,2.5,1.4,3c1,0.6,2.7,1,5.1,1c2.4,0,5.1-0.4,8.4-1.2l1.4-0.3v1.4v3.6v0.9
l-0.9,0.2c-3.1,0.7-6.4,1.1-9.6,1.1c-4,0-7.2-0.6-9.5-2.1c-2.3-1.6-3.4-3.9-3.4-6.9V36.3c0-3.4,1-6,3.1-7.7c2.1-1.6,5.3-2.3,9.3-2.3
c3.8,0,6.8,0.6,8.8,2.2C70.2,30.1,71,32.8,71,36.3z M64.1,37.8l-0.1-3.1c0-1.3-0.4-2-0.9-2.3c-0.7-0.4-2-0.7-4.2-0.7
c-2.1,0-3.4,0.3-4.2,0.7c-0.5,0.3-1,1-1,2.4l0.1,3.1L64.1,37.8L64.1,37.8z M91.1,26.3c-2.6,0-4.8,0.3-6.4,1c-0.3,0.2-0.6,0.3-1,0.5
v-1h-1.1h-4.8h-1.1v1.1v26V55h1.1h4.8h1.1v-1.1V35.1c0-1.4,0.4-2.1,0.9-2.5c0.6-0.4,2.2-0.8,5.1-0.8c0.9,0,1.8,0.1,2.7,0.3
c0.5,0.1,0.8,0.3,1.1,0.6c0.2,0.3,0.4,0.5,0.4,0.9c0.1,0.5,0.2,0.9,0.1,1.3v18.8V55h1.1h4.8h1.1v-1.1V34.9c0-2.7-0.7-4.9-2.2-6.4
C97.2,26.9,94.5,26.3,91.1,26.3z" />
</svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@@ -0,0 +1,25 @@
<script>
import { onMount } from 'svelte';
export let path;
export let color;
export let colorConfig = { target: 'path', attribute: 'fill' };
let svgHtml = '';
async function fetchAndColorSvg() {
const res = await fetch(path);
let text = await res.text();
// Parse and update color
const parser = new DOMParser();
const doc = parser.parseFromString(text, 'image/svg+xml');
const targets = doc.querySelectorAll(colorConfig.selector || colorConfig.target);
targets.forEach(el => {
el.setAttribute(colorConfig.attribute, color);
});
svgHtml = doc.documentElement.outerHTML;
}
$: path, color, colorConfig, fetchAndColorSvg();
</script>
{@html svgHtml}

View File

@@ -1,6 +1,8 @@
<script>
import LogoModal from './LogoModal.svelte';
import LogoActions from './LogoActions.svelte';
import InlineSvg from './InlineSvg.svelte';
import { onMount } from 'svelte';
export let logos = [];
export let onCopy;
@@ -17,6 +19,21 @@
function closeModal() {
showModal = false;
}
function isSvgLogo(logo) {
return logo.format && logo.format.toLowerCase() === 'svg';
}
// Inline SVG logic for color switching
let svgCache = {};
async function fetchInlineSvg(path) {
if (svgCache[path]) return svgCache[path];
const res = await fetch(path);
const text = await res.text();
svgCache[path] = text;
return text;
}
</script>
<LogoModal show={showModal} logo={selectedLogo} on:close={closeModal} />
@@ -32,11 +49,38 @@
on:keydown={(e) => (e.key === 'Enter' || e.key === ' ') && openPreview(logo)}
style="cursor:pointer;"
>
<img src={logo.path} alt={logo.name} />
{#if isSvgLogo(logo) && logo.colors}
<InlineSvg path={logo.path} color={logo._activeColor || logo.colors[0].value} colorConfig={logo.colorConfig} alt={logo.name} />
{:else}
<img src={logo.path} alt={logo.name} />
{/if}
</div>
<div class="logo-info">
<h3>{logo.name}</h3>
<p>Format: {logo.format}</p>
<div class="format-row">
<span><strong>Format:</strong> {logo.format}</span>
{#if isSvgLogo(logo) && logo.colors}
<span class="color-switcher-inline">
{#each logo.colors as colorObj}
<span
class="color-circle"
title={colorObj.label}
style="background:{colorObj.value}"
tabindex="0"
role="button"
aria-label={"Switch color to " + colorObj.label}
on:click|stopPropagation={() => logo._activeColor = colorObj.value}
on:keydown|stopPropagation={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
logo._activeColor = colorObj.value;
e.preventDefault();
}
}}
></span>
{/each}
</span>
{/if}
</div>
<div class="logo-actions">
<LogoActions {logo} {onCopy} {onDownload} />
</div>
@@ -77,13 +121,27 @@
cursor: pointer;
transition: background 0.2s, color 0.2s;
}
.logo-image img {
.logo-image img,
.logo-image :global(svg) {
width: 100%;
height: 100%;
max-width: 100%;
max-height: 100%;
object-fit: contain;
object-position: center;
display: block;
margin: 0 auto;
}
/* Make inline SVGs scale and fit like <img> */
.logo-image svg {
max-width: 80%;
max-height: 80%;
width: auto !important;
height: auto !important;
object-fit: contain;
object-position: center;
display: block;
margin: 0 auto;
}
.logo-info {
padding: 1rem;
@@ -96,21 +154,71 @@
margin-bottom: 0.5rem;
color: var(--color-accent, #4f8cff);
}
.logo-info p {
font-size: 0.9rem;
color: var(--color-text);
margin-bottom: 1rem;
}
/* .logo-info p { font-size: 0.9rem; color: var(--color-text); margin-bottom: 1rem; } */
.logo-actions {
display: flex;
align-items: center;
gap: 0.5em;
flex-wrap: nowrap;
}
.format-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1em;
margin-bottom: 0.5em;
}
.color-switcher-inline {
display: flex;
gap: 0.4em;
align-items: center;
margin-left: auto;
}
.color-switcher {
display: flex;
gap: 0.4em;
margin: 0.5em 0 0.5em 0;
align-items: center;
}
.color-circle {
width: 20px;
height: 20px;
border-radius: 50%;
border: 2px solid #eee;
box-shadow: 0 1px 2px rgba(0,0,0,0.08);
cursor: pointer;
display: inline-block;
transition: border 0.2s, box-shadow 0.2s;
}
.color-circle:hover {
border: 2px solid #888;
box-shadow: 0 2px 8px rgba(0,0,0,0.12);
}
.no-results {
grid-column: 1 / -1;
text-align: center;
padding: 2rem;
color: #666;
}
.color-switcher {
display: flex;
gap: 0.4em;
margin: 0.5em 0 0.5em 0;
align-items: center;
}
.color-circle {
width: 20px;
height: 20px;
border-radius: 50%;
border: 2px solid #eee;
box-shadow: 0 1px 2px rgba(0,0,0,0.08);
cursor: pointer;
display: inline-block;
transition: border 0.2s, box-shadow 0.2s;
}
.color-circle:hover {
border: 2px solid #888;
box-shadow: 0 2px 8px rgba(0,0,0,0.12);
}
</style>

View File

@@ -1,6 +1,7 @@
<script>
import LogoModal from './LogoModal.svelte';
import LogoActions from './LogoActions.svelte';
import InlineSvg from './InlineSvg.svelte';
export let logos = [];
export let onCopy;
@@ -18,6 +19,10 @@
showModal = false;
}
function isSvgLogo(logo) {
return logo.format && logo.format.toLowerCase() === 'svg';
}
</script>
<LogoModal show={showModal} logo={selectedLogo} on:close={closeModal} />
@@ -33,11 +38,39 @@
on:keydown={(e) => (e.key === 'Enter' || e.key === ' ') && openPreview(logo)}
style="cursor:pointer;"
>
<img src={logo.path} alt={logo.name} />
>
{#if isSvgLogo(logo) && logo.colors}
<InlineSvg path={logo.path} color={logo._activeColor || logo.colors[0].value} colorConfig={logo.colorConfig} alt={logo.name} />
{:else}
<img src={logo.path} alt={logo.name} />
{/if}
</div>
<div class="logo-info">
<h3>{logo.name}</h3>
<p>Format: {logo.format}</p>
<div class="format-row">
<span><strong>Format:</strong> {logo.format}</span>
</div>
{#if isSvgLogo(logo) && logo.colors}
<div class="color-switcher-under">
{#each logo.colors as colorObj}
<span
class="color-circle"
title={colorObj.label}
style="background:{colorObj.value}"
tabindex="0"
role="button"
aria-label={"Set color " + colorObj.label}
on:click|stopPropagation={() => logo._activeColor = colorObj.value}
on:keydown|stopPropagation={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
logo._activeColor = colorObj.value;
e.preventDefault();
}
}}
></span>
{/each}
</div>
{/if}
</div>
<div class="logo-actions">
<LogoActions {logo} {onCopy} {onDownload} />
@@ -82,6 +115,26 @@
object-fit: contain;
object-position: center;
}
.color-switcher {
display: flex;
gap: 0.4em;
margin: 0.5em 0 0.5em 0;
align-items: center;
}
.color-circle {
width: 20px;
height: 20px;
border-radius: 50%;
border: 2px solid #eee;
box-shadow: 0 1px 2px rgba(0,0,0,0.08);
cursor: pointer;
display: inline-block;
transition: border 0.2s, box-shadow 0.2s;
}
.color-circle:hover {
border: 2px solid #888;
box-shadow: 0 2px 8px rgba(0,0,0,0.12);
}
.logo-info {
background: var(--color-card);
color: var(--color-text);
@@ -93,11 +146,7 @@
margin-bottom: 0.5rem;
color: var(--color-accent, #4f8cff);
}
.logo-info p {
font-size: 0.9rem;
color: var(--color-text);
margin-bottom: 1rem;
}
/* .logo-info p { font-size: 0.9rem; color: var(--color-text); margin-bottom: 1rem; } */
.logo-actions {
display: flex;
align-items: center;
@@ -114,4 +163,17 @@
padding: 2rem;
color: #666;
}
.format-row {
display: flex;
align-items: center;
gap: 1em;
}
/* .color-switcher-inline { display: flex; gap: 0.4em; align-items: center; margin-left: auto; } */
.color-switcher-under {
display: flex;
gap: 0.4em;
align-items: center;
margin: 0.5em 0 0 0;
}
</style>

View File

@@ -1,5 +1,6 @@
<script>
import { onMount, onDestroy, createEventDispatcher } from 'svelte';
import InlineSvg from './InlineSvg.svelte';
export let show = false;
export let logo = null;
@@ -16,6 +17,10 @@
}
}
function isSvgLogo(logo) {
return logo && logo.format && logo.format.toLowerCase() === 'svg';
}
onMount(() => {
document.addEventListener('keydown', handleKeydown);
});
@@ -44,10 +49,29 @@
on:keydown={(e) => (e.key === 'Enter' || e.key === ' ') && close()}
style="cursor:pointer;"
>
<img src={logo.path} alt={logo.name} />
{#if isSvgLogo(logo) && logo.colors}
<InlineSvg path={logo.path} color={logo._activeColor || logo.colors[0].value} colorConfig={logo.colorConfig} alt={logo.name} />
{:else}
<img src={logo.path} alt={logo.name} />
{/if}
</div>
<div class="logo-details">
<p><strong>Format:</strong> {logo.format}</p>
{#if isSvgLogo(logo) && logo.colors}
<div class="color-switcher-preview">
{#each logo.colors as colorObj}
<span
class="color-circle"
title={colorObj.label}
style="background:{colorObj.value}"
tabindex="0"
role="button"
on:click|stopPropagation={() => logo._activeColor = colorObj.value}
on:keydown|stopPropagation={(e) => (e.key === 'Enter' || e.key === ' ') && (logo._activeColor = colorObj.value)}
></span>
{/each}
</div>
{/if}
<p><strong>Format:</strong> <span>{logo.format}</span></p>
<p><strong>Path:</strong> {logo.path}</p>
{#if logo.tags && logo.tags.length}
<div class="logo-tags">
@@ -119,8 +143,11 @@
background-color: var(--color-card);
border-radius: 4px;
padding: 2rem;
min-height: 300px;
min-height: 200px;
max-height: 60vh;
max-width: 100%;
transition: background 0.2s, color 0.2s;
overflow: auto;
}
.preview-container img {
@@ -129,6 +156,33 @@
object-fit: contain;
}
/* .color-switcher { display: flex; gap: 0.4em; margin: 0.5em 0 0.5em 0; align-items: center; } */
.color-switcher-inline {
display: flex;
gap: 0.4em;
align-items: center;
margin-left: auto;
}
.color-circle {
width: 20px;
height: 20px;
border-radius: 50%;
border: 2px solid #eee;
box-shadow: 0 1px 2px rgba(0,0,0,0.08);
cursor: pointer;
display: inline-block;
transition: border 0.2s, box-shadow 0.2s;
}
.color-circle:hover {
border: 2px solid #888;
box-shadow: 0 2px 8px rgba(0,0,0,0.12);
}
/* .format-row { display: flex; align-items: center; justify-content: space-between; gap: 1em; margin-bottom: 0.5em; } */
.logo-details {
padding: 1rem;
background-color: var(--color-card);
@@ -159,4 +213,42 @@
letter-spacing: 0.02em;
transition: background 0.2s;
}
/* .color-switcher-under { display: flex; gap: 0.4em; align-items: center; margin: 0.5em 0 0 0; } */
.color-switcher-inline {
display: flex;
gap: 0.4em;
align-items: center;
margin-left: auto;
}
.color-circle {
width: 20px;
height: 20px;
border-radius: 50%;
border: 2px solid #eee;
box-shadow: 0 1px 2px rgba(0,0,0,0.08);
cursor: pointer;
display: inline-block;
transition: border 0.2s, box-shadow 0.2s;
}
.color-circle:hover {
border: 2px solid #888;
box-shadow: 0 2px 8px rgba(0,0,0,0.12);
}
.format-value {
font-weight: 400;
margin-left: 0.3em;
}
.color-switcher-preview {
display: flex;
justify-content: center;
gap: 0.4em;
align-items: center;
margin: 1em 0 0.5em 0;
}
</style>