feat: version 2.8.1 -- catalogo de logos de marca en Contraseñas (simple-icons, CC0)
Amplia el selector de icono de una credencial con ~70 logos reales de marcas conocidas (Google, GitHub, Cloudflare, cPanel, MikroTik, WordPress, etc.), empaquetados localmente desde el paquete simple-icons (dominio publico) y tree-shakeados por Vite. Se mantiene el criterio de privacidad ya establecido: ninguna consulta externa de favicon por entrada. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,12 @@
|
|||||||
# Changelog - project.linkedcorp.net
|
# Changelog - project.linkedcorp.net
|
||||||
|
|
||||||
|
## [2.8.1] - 2026-10-01
|
||||||
|
### Added
|
||||||
|
- Catálogo de íconos de "Contraseñas" ampliado con ~70 logos de marcas conocidas (Google, GitHub,
|
||||||
|
Cloudflare, cPanel, MikroTik, WordPress, etc.), empaquetados localmente desde `simple-icons`
|
||||||
|
(licencia CC0, dominio público) — sin ninguna consulta externa por entrada, mismo criterio de
|
||||||
|
privacidad que el catálogo genérico anterior.
|
||||||
|
|
||||||
## [2.8.0] - 2026-10-01
|
## [2.8.0] - 2026-10-01
|
||||||
### Added
|
### Added
|
||||||
- Buscador en "Contraseñas": filtra las tarjetas mientras escribís, por nombre, usuario, enlace
|
- Buscador en "Contraseñas": filtra las tarjetas mientras escribís, por nombre, usuario, enlace
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "project-linkedcorp-backend",
|
"name": "project-linkedcorp-backend",
|
||||||
"version": "2.8.0",
|
"version": "2.8.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "src/server.js",
|
"main": "src/server.js",
|
||||||
|
|||||||
@@ -11,11 +11,27 @@ import { sendMail } from '../../utils/mailer.js';
|
|||||||
const PIN_RE = /^\d{4}$/;
|
const PIN_RE = /^\d{4}$/;
|
||||||
const VAULT_TOKEN_EXPIRES = '30m';
|
const VAULT_TOKEN_EXPIRES = '30m';
|
||||||
|
|
||||||
// Catalogo fijo (debe coincidir con el del frontend, ContrasenasPage.jsx#ICONS) -- nunca se
|
// Catalogo fijo (debe coincidir con el del frontend: ContrasenasPage.jsx#ICONS y
|
||||||
// acepta un valor arbitrario, para no guardar basura ni abrir una via de inyeccion rara.
|
// frontend/src/data/brandIcons.js#BRAND_ICONS) -- nunca se acepta un valor arbitrario, para no
|
||||||
|
// guardar basura ni abrir una via de inyeccion rara.
|
||||||
const ICON_KEYS = new Set([
|
const ICON_KEYS = new Set([
|
||||||
'mail', 'globe', 'server', 'database', 'cloud', 'shield', 'lock', 'wifi',
|
'mail', 'globe', 'server', 'database', 'cloud', 'shield', 'lock', 'wifi',
|
||||||
'card', 'building', 'printer', 'phone', 'key', 'disk', 'router', 'user',
|
'card', 'building', 'printer', 'phone', 'key', 'disk', 'router', 'user',
|
||||||
|
'b_google', 'b_gmail', 'b_googledrive', 'b_googlecloud', 'b_protonmail', 'b_zoho',
|
||||||
|
'b_github', 'b_gitlab', 'b_digitalocean', 'b_cloudflare', 'b_namecheap', 'b_godaddy',
|
||||||
|
'b_ovh', 'b_vultr', 'b_netlify', 'b_vercel', 'b_cpanel', 'b_plesk', 'b_webmin',
|
||||||
|
'b_nginx', 'b_apache', 'b_mysql', 'b_mariadb', 'b_postgresql', 'b_docker',
|
||||||
|
'b_cisco', 'b_fortinet', 'b_mikrotik', 'b_ubiquiti', 'b_tplink', 'b_openvpn', 'b_wireguard',
|
||||||
|
'b_pfsense', 'b_opnsense', 'b_qnap', 'b_synology', 'b_nordvpn', 'b_bitdefender',
|
||||||
|
'b_trendmicro', 'b_avast', 'b_kaspersky',
|
||||||
|
'b_whatsapp', 'b_telegram', 'b_zoom', 'b_discord', 'b_jitsi',
|
||||||
|
'b_facebook', 'b_instagram', 'b_x',
|
||||||
|
'b_paypal', 'b_stripe',
|
||||||
|
'b_teamviewer', 'b_anydesk',
|
||||||
|
'b_dropbox', 'b_backblaze', 'b_mega', 'b_veeam', 'b_nextcloud',
|
||||||
|
'b_bitwarden', 'b_lastpass',
|
||||||
|
'b_linux', 'b_ubuntu', 'b_apple', 'b_raspberrypi',
|
||||||
|
'b_wordpress', 'b_mailchimp', 'b_firebase',
|
||||||
]);
|
]);
|
||||||
function sanitizeIconKey(key) {
|
function sanitizeIconKey(key) {
|
||||||
return ICON_KEYS.has(key) ? key : null;
|
return ICON_KEYS.has(key) ? key : null;
|
||||||
|
|||||||
Generated
+32
-12
@@ -1,18 +1,19 @@
|
|||||||
{
|
{
|
||||||
"name": "project-linkedcorp-frontend",
|
"name": "project-linkedcorp-frontend",
|
||||||
"version": "1.21.1",
|
"version": "2.8.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "project-linkedcorp-frontend",
|
"name": "project-linkedcorp-frontend",
|
||||||
"version": "1.21.1",
|
"version": "2.8.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lucide-react": "^0.462.0",
|
"lucide-react": "^0.462.0",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-router-dom": "^7.18.3",
|
"react-router-dom": "^7.18.3",
|
||||||
"serve": "^14.2.6"
|
"serve": "^14.2.6",
|
||||||
|
"simple-icons": "^16.33.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vitejs/plugin-react": "^4.3.4",
|
"@vitejs/plugin-react": "^4.3.4",
|
||||||
@@ -3064,9 +3065,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/brace-expansion": {
|
"node_modules/brace-expansion": {
|
||||||
"version": "1.1.18",
|
"version": "1.1.21",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.21.tgz",
|
||||||
"integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==",
|
"integrity": "sha512-9zeA+KLZNNzglF2TPKRQEDyx6Yby7daAkuy8MiPzpXPsYDWi/DRM8jmwUDxokQjYqBpv5DgPiwD4h4ZZSy1Ujw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"balanced-match": "^1.0.0",
|
"balanced-match": "^1.0.0",
|
||||||
@@ -3903,9 +3904,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/fast-uri": {
|
"node_modules/fast-uri": {
|
||||||
"version": "3.1.7",
|
"version": "3.1.8",
|
||||||
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.8.tgz",
|
||||||
"integrity": "sha512-dOvZVzjdZdz7phd9v6jCbwxrBW3fK6n8Rc0CtdmM4bumzMnxywBYhuph6J819RRw/ku+rLbelwfMunktuzVVHg==",
|
"integrity": "sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "github",
|
"type": "github",
|
||||||
@@ -5802,9 +5803,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/serialize-javascript": {
|
"node_modules/serialize-javascript": {
|
||||||
"version": "7.1.1",
|
"version": "7.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.1.2.tgz",
|
||||||
"integrity": "sha512-k3CMsaIvvdSwm8oLB4MXSl0wH2/cwlH7xGcnRd2DaeRmBkbzYmyT8j0tsX60DwD1eRwHTpNpH8ljKu9oUT1MeQ==",
|
"integrity": "sha512-GL2BWwVa6JydKO6l/ljVgjAZF4QJ3S7dWDWi53s5GZT8PJzD2fNxi67HANQGKAqPrwEpL5ba7gUBGi0Ls/sEoQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "BSD-3-Clause",
|
"license": "BSD-3-Clause",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -6018,6 +6019,25 @@
|
|||||||
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
|
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/simple-icons": {
|
||||||
|
"version": "16.33.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/simple-icons/-/simple-icons-16.33.0.tgz",
|
||||||
|
"integrity": "sha512-z14u6A8ngAg9mgERRsNO8YkjIMefehIpBk7A8Dz3Gd91945qFP19MLPSHgV4z8P5u/MRYd5e07OTzaDoB4d6qA==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/simple-icons"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/simple-icons"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "CC0-1.0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.12.18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/smob": {
|
"node_modules/smob": {
|
||||||
"version": "1.6.2",
|
"version": "1.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/smob/-/smob-1.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/smob/-/smob-1.6.2.tgz",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "project-linkedcorp-frontend",
|
"name": "project-linkedcorp-frontend",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "2.8.0",
|
"version": "2.8.1",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
@@ -13,7 +13,8 @@
|
|||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-router-dom": "^7.18.3",
|
"react-router-dom": "^7.18.3",
|
||||||
"serve": "^14.2.6"
|
"serve": "^14.2.6",
|
||||||
|
"simple-icons": "^16.33.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vitejs/plugin-react": "^4.3.4",
|
"@vitejs/plugin-react": "^4.3.4",
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
// Catalogo estatico de logos de marca para el icono de una entrada de Contraseñas.
|
||||||
|
// Fuente: paquete npm "simple-icons" (CC0-1.0 / dominio publico) -- se empaqueta localmente,
|
||||||
|
// NUNCA se consulta un servicio externo de favicon por entrada (eso filtraria a terceros que
|
||||||
|
// urls internas guarda cada usuario). simple-icons ya excluye marcas con politicas de marca mas
|
||||||
|
// estrictas (ej. Microsoft, LinkedIn, AWS, Windows no estan incluidas en el paquete).
|
||||||
|
// Debe coincidir con backend/src/modules/vault/service.js#BRAND_ICON_KEYS.
|
||||||
|
import {
|
||||||
|
siGoogle, siGmail, siGoogledrive, siGooglecloud, siProtonmail, siZoho,
|
||||||
|
siGithub, siGitlab, siDigitalocean, siCloudflare, siNamecheap, siGodaddy,
|
||||||
|
siOvh, siVultr, siNetlify, siVercel, siCpanel, siPlesk, siWebmin,
|
||||||
|
siNginx, siApache, siMysql, siMariadb, siPostgresql, siDocker,
|
||||||
|
siCisco, siFortinet, siMikrotik, siUbiquiti, siTplink, siOpenvpn, siWireguard,
|
||||||
|
siPfsense, siOpnsense, siQnap, siSynology, siNordvpn, siBitdefender,
|
||||||
|
siTrendmicro, siAvast, siKaspersky,
|
||||||
|
siWhatsapp, siTelegram, siZoom, siDiscord, siJitsi,
|
||||||
|
siFacebook, siInstagram, siX,
|
||||||
|
siPaypal, siStripe,
|
||||||
|
siTeamviewer, siAnydesk,
|
||||||
|
siDropbox, siBackblaze, siMega, siVeeam, siNextcloud,
|
||||||
|
siBitwarden, siLastpass,
|
||||||
|
siLinux, siUbuntu, siApple, siRaspberrypi,
|
||||||
|
siWordpress, siMailchimp, siFirebase,
|
||||||
|
} from 'simple-icons';
|
||||||
|
|
||||||
|
export const BRAND_ICONS = {
|
||||||
|
b_google: siGoogle, b_gmail: siGmail, b_googledrive: siGoogledrive, b_googlecloud: siGooglecloud,
|
||||||
|
b_protonmail: siProtonmail, b_zoho: siZoho,
|
||||||
|
b_github: siGithub, b_gitlab: siGitlab, b_digitalocean: siDigitalocean, b_cloudflare: siCloudflare,
|
||||||
|
b_namecheap: siNamecheap, b_godaddy: siGodaddy, b_ovh: siOvh, b_vultr: siVultr,
|
||||||
|
b_netlify: siNetlify, b_vercel: siVercel, b_cpanel: siCpanel, b_plesk: siPlesk, b_webmin: siWebmin,
|
||||||
|
b_nginx: siNginx, b_apache: siApache, b_mysql: siMysql, b_mariadb: siMariadb,
|
||||||
|
b_postgresql: siPostgresql, b_docker: siDocker,
|
||||||
|
b_cisco: siCisco, b_fortinet: siFortinet, b_mikrotik: siMikrotik, b_ubiquiti: siUbiquiti,
|
||||||
|
b_tplink: siTplink, b_openvpn: siOpenvpn, b_wireguard: siWireguard, b_pfsense: siPfsense,
|
||||||
|
b_opnsense: siOpnsense, b_qnap: siQnap, b_synology: siSynology,
|
||||||
|
b_nordvpn: siNordvpn, b_bitdefender: siBitdefender, b_trendmicro: siTrendmicro,
|
||||||
|
b_avast: siAvast, b_kaspersky: siKaspersky,
|
||||||
|
b_whatsapp: siWhatsapp, b_telegram: siTelegram, b_zoom: siZoom, b_discord: siDiscord, b_jitsi: siJitsi,
|
||||||
|
b_facebook: siFacebook, b_instagram: siInstagram, b_x: siX,
|
||||||
|
b_paypal: siPaypal, b_stripe: siStripe,
|
||||||
|
b_teamviewer: siTeamviewer, b_anydesk: siAnydesk,
|
||||||
|
b_dropbox: siDropbox, b_backblaze: siBackblaze, b_mega: siMega, b_veeam: siVeeam, b_nextcloud: siNextcloud,
|
||||||
|
b_bitwarden: siBitwarden, b_lastpass: siLastpass,
|
||||||
|
b_linux: siLinux, b_ubuntu: siUbuntu, b_apple: siApple, b_raspberrypi: siRaspberrypi,
|
||||||
|
b_wordpress: siWordpress, b_mailchimp: siMailchimp, b_firebase: siFirebase,
|
||||||
|
};
|
||||||
@@ -18,25 +18,36 @@ import { PasswordInput } from '../../components/PasswordInput.jsx';
|
|||||||
import { DetailPopup } from '../../components/DetailPopup.jsx';
|
import { DetailPopup } from '../../components/DetailPopup.jsx';
|
||||||
import { Flyout, FlyoutItem } from '../../components/Flyout.jsx';
|
import { Flyout, FlyoutItem } from '../../components/Flyout.jsx';
|
||||||
import { SearchInput } from '../../components/SearchInput.jsx';
|
import { SearchInput } from '../../components/SearchInput.jsx';
|
||||||
|
import { BRAND_ICONS } from '../../data/brandIcons.js';
|
||||||
|
|
||||||
const EMPTY_FORM = { title: '', url: '', username: '', password: '', notes: '', iconKey: '' };
|
const EMPTY_FORM = { title: '', url: '', username: '', password: '', notes: '', iconKey: '' };
|
||||||
const AUTO_LOCK_MS = 3 * 60 * 1000; // 3 minutos: salir solo del menu si queda abierto sin atencion
|
const AUTO_LOCK_MS = 3 * 60 * 1000; // 3 minutos: salir solo del menu si queda abierto sin atencion
|
||||||
|
|
||||||
// Catalogo fijo de iconos (debe coincidir con backend/src/modules/vault/service.js#ICON_KEYS) --
|
// Catalogo fijo de iconos genericos (debe coincidir con backend/src/modules/vault/service.js#ICON_KEYS) --
|
||||||
// a proposito NO se usa ningun servicio externo de favicon (ej. google/s2/favicons): revelaria a
|
// a proposito NO se usa ningun servicio externo de favicon (ej. google/s2/favicons): revelaria a
|
||||||
// terceros que urls internas tiene guardadas cada usuario, inaceptable para un repositorio de
|
// terceros que urls internas tiene guardadas cada usuario, inaceptable para un repositorio de
|
||||||
// credenciales. El usuario elige uno de esta lista, o se deja "Auto" (inicial del nombre).
|
// credenciales. El usuario elige uno de esta lista, o uno de marca (BRAND_ICONS), o se deja
|
||||||
|
// "Auto" (inicial del nombre).
|
||||||
const ICONS = {
|
const ICONS = {
|
||||||
mail: Mail, globe: Globe, server: Server, database: Database, cloud: Cloud, shield: Shield,
|
mail: Mail, globe: Globe, server: Server, database: Database, cloud: Cloud, shield: Shield,
|
||||||
lock: Lock, wifi: Wifi, card: CreditCard, building: Building2, printer: Printer,
|
lock: Lock, wifi: Wifi, card: CreditCard, building: Building2, printer: Printer,
|
||||||
phone: Smartphone, key: KeyRound, disk: HardDrive, router: Router, user: UserCog,
|
phone: Smartphone, key: KeyRound, disk: HardDrive, router: Router, user: UserCog,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function BrandSvg({ icon, size = 22 }) {
|
||||||
|
return (
|
||||||
|
<svg viewBox="0 0 24 24" width={size} height={size} fill={`#${icon.hex}`}>
|
||||||
|
<path d={icon.path} />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function EntryIcon({ iconKey, title, size = 22 }) {
|
function EntryIcon({ iconKey, title, size = 22 }) {
|
||||||
const Icon = ICONS[iconKey];
|
const Icon = ICONS[iconKey];
|
||||||
|
const brand = BRAND_ICONS[iconKey];
|
||||||
return (
|
return (
|
||||||
<div className="vault-card-icon">
|
<div className={`vault-card-icon ${brand ? 'brand' : ''}`}>
|
||||||
{Icon ? <Icon size={size} /> : <span>{(title || '?').trim().charAt(0).toUpperCase()}</span>}
|
{Icon ? <Icon size={size} /> : brand ? <BrandSvg icon={brand} size={size} /> : <span>{(title || '?').trim().charAt(0).toUpperCase()}</span>}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -344,6 +355,19 @@ export default function ContrasenasPage() {
|
|||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
<div className="vault-icon-picker vault-icon-picker-brands">
|
||||||
|
{Object.entries(BRAND_ICONS).map(([key, icon]) => (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
key={key}
|
||||||
|
className={`vault-icon-option brand ${form.iconKey === key ? 'selected' : ''}`}
|
||||||
|
title={icon.title}
|
||||||
|
onClick={() => setForm((f) => ({ ...f, iconKey: key }))}
|
||||||
|
>
|
||||||
|
<BrandSvg icon={icon} size={16} />
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
</Field>
|
</Field>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
@@ -379,6 +379,7 @@ table.list-table { width: 100%; border-collapse: collapse; font-size: .8rem; }
|
|||||||
text-overflow: ellipsis; white-space: nowrap;
|
text-overflow: ellipsis; white-space: nowrap;
|
||||||
}
|
}
|
||||||
.vault-icon-picker { display: flex; flex-wrap: wrap; gap: 8px; }
|
.vault-icon-picker { display: flex; flex-wrap: wrap; gap: 8px; }
|
||||||
|
.vault-icon-picker-brands { max-height: 150px; overflow-y: auto; padding-top: 8px; margin-top: 4px; border-top: 1px dashed rgb(var(--line)); }
|
||||||
.vault-icon-option {
|
.vault-icon-option {
|
||||||
width: 36px; height: 36px; border-radius: 999px; border: 1px solid rgb(var(--line));
|
width: 36px; height: 36px; border-radius: 999px; border: 1px solid rgb(var(--line));
|
||||||
background: rgb(var(--field)); color: rgb(var(--body)); cursor: pointer;
|
background: rgb(var(--field)); color: rgb(var(--body)); cursor: pointer;
|
||||||
@@ -386,6 +387,8 @@ table.list-table { width: 100%; border-collapse: collapse; font-size: .8rem; }
|
|||||||
}
|
}
|
||||||
.vault-icon-option:hover { border-color: rgb(var(--accent) / .6); }
|
.vault-icon-option:hover { border-color: rgb(var(--accent) / .6); }
|
||||||
.vault-icon-option.selected { border-color: rgb(var(--accent)); background: rgb(var(--accent) / .15); color: rgb(var(--accent)); }
|
.vault-icon-option.selected { border-color: rgb(var(--accent)); background: rgb(var(--accent) / .15); color: rgb(var(--accent)); }
|
||||||
|
.vault-icon-option.brand, .vault-card-icon.brand { background: #fff; }
|
||||||
|
.vault-icon-option.brand.selected { border-color: rgb(var(--accent)); }
|
||||||
|
|
||||||
/* --- DetailPopup (ver DetailPopup.jsx) ---
|
/* --- DetailPopup (ver DetailPopup.jsx) ---
|
||||||
Al elegir un item de un listado, la lista queda inactiva detras del overlay y el popup
|
Al elegir un item de un listado, la lista queda inactiva detras del overlay y el popup
|
||||||
|
|||||||
Reference in New Issue
Block a user