UNPKG

brainmap.js

Version:

A beautiful, interactive, and themeable mindmap library for creating hierarchical visualizations with editing capabilities

445 lines (382 loc) 10.1 kB
/** * Brainmap.js - CSS Styles * A beautiful, interactive mindmap library */ :root { /* Theme Variables */ --mindmap-bg-primary: #9696c2; --mindmap-bg-secondary: #ffffff; --mindmap-color-root: linear-gradient(135deg, #f97316 0%, #dc2626 100%); --mindmap-color-root-stroke: #dc2626; --mindmap-color-root-text: #ffffff; --mindmap-color-branch: linear-gradient(135deg, #34d399 0%, #059669 100%); --mindmap-color-branch-stroke: #059669; --mindmap-color-branch-text: #065f46; --mindmap-color-leaf: linear-gradient(135deg, #60a5fa 0%, #1d4ed8 100%); --mindmap-color-leaf-stroke: #2563eb; --mindmap-color-leaf-text: #1e40af; --mindmap-color-link: rgba(255, 255, 255, 0.6); --mindmap-color-text: #333333; --mindmap-color-hover-shadow: rgba(0, 0, 0, 0.3); --mindmap-radius-root: 12px; --mindmap-radius-branch: 7px; --mindmap-radius-leaf: 8px; --mindmap-stroke-width: 2; --mindmap-font-size-root: 14px; --mindmap-font-size-branch: 12px; --mindmap-font-size-leaf: 11px; --mindmap-font-weight-normal: 600; --mindmap-font-weight-bold: 700; --mindmap-transition: all 0.2s ease; --mindmap-shadow-hover: 0 6px 12px rgba(37, 99, 235, 0.4); --mindmap-shadow-default: 0 2px 4px rgba(0, 0, 0, 0.2); } .mindmap-container { font-family: system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", Arial, sans-serif; position: relative; width: 100%; height: 100%; background: var(--mindmap-bg-primary); overflow: hidden; /* Touch improvements */ -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; touch-action: none; } .mindmap-svg { width: 100%; height: 100%; cursor: grab; } .mindmap-svg.editing { cursor: default; } .mindmap-node circle { stroke-width: var(--mindmap-stroke-width); transition: var(--mindmap-transition); filter: drop-shadow(var(--mindmap-shadow-default)); } .mindmap-node.root circle { fill: url(#mindmapRootGradient); stroke: var(--mindmap-color-root-stroke); stroke-width: 3; } .mindmap-node.branch circle { fill: url(#mindmapBranchGradient); stroke: var(--mindmap-color-branch-stroke); } .mindmap-node.leaf circle { fill: url(#mindmapLeafGradient); stroke: var(--mindmap-color-leaf-stroke); } .mindmap-node:hover circle { transform: scale(1.2); filter: drop-shadow(var(--mindmap-shadow-hover)); } .mindmap-node.editing circle { stroke-width: 3; stroke-dasharray: 5, 5; animation: mindmap-dash 1s linear infinite; } .mindmap-node.long-pressing circle { stroke-width: 4; filter: drop-shadow(0 0 8px rgba(59, 130, 246, 0.8)); animation: mindmap-pulse 0.5s ease-in-out; } @keyframes mindmap-dash { to { stroke-dashoffset: -10; } } @keyframes mindmap-pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.1); } } .mindmap-node text { text-anchor: middle; dominant-baseline: middle; pointer-events: none; fill: var(--mindmap-color-text); font-weight: var(--mindmap-font-weight-normal); transition: var(--mindmap-transition); } .mindmap-node.root text { font-size: var(--mindmap-font-size-root); fill: var(--mindmap-color-root-text); text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); font-weight: var(--mindmap-font-weight-bold); } .mindmap-node.branch text { font-size: var(--mindmap-font-size-branch); fill: var(--mindmap-color-branch-text); } .mindmap-node.leaf text { font-size: var(--mindmap-font-size-leaf); fill: var(--mindmap-color-leaf-text); font-weight: var(--mindmap-font-weight-bold); } /* Touch enhancements */ @media (hover: none) and (pointer: coarse) { /* Larger touch targets on mobile */ .mindmap-node circle { r: 15; /* Larger radius for easier touching */ } .mindmap-node.root circle { r: 18; } .mindmap-node.branch circle { r: 12; } .mindmap-node.leaf circle { r: 14; } /* Remove hover effects on touch devices */ .mindmap-node:hover circle { transform: none; filter: drop-shadow(var(--mindmap-shadow-default)); } /* Larger control buttons for touch */ .mindmap-control-btn { padding: 12px 16px; font-size: 14px; min-height: 44px; /* iOS recommended touch target size */ min-width: 44px; } } /* Disable selection on all mindmap elements */ .mindmap-container * { -webkit-tap-highlight-color: transparent; } .mindmap-link { stroke: var(--mindmap-color-link); stroke-width: 2; fill: none; filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.1)); } /* Editing Input */ .mindmap-edit-input { position: absolute; padding: 4px 8px; border: 2px solid var(--mindmap-color-leaf-stroke); border-radius: 4px; background: var(--mindmap-bg-secondary); font-family: inherit; font-size: 12px; font-weight: var(--mindmap-font-weight-normal); text-align: center; z-index: 1000; box-shadow: var(--mindmap-shadow-hover); } /* Context Menu */ .mindmap-context-menu { position: absolute; background: var(--mindmap-bg-secondary); border-radius: 8px; box-shadow: var(--mindmap-shadow-hover); z-index: 1001; min-width: 180px; border: 1px solid #e5e7eb; } .mindmap-context-menu-item { padding: 12px 16px; cursor: pointer; transition: var(--mindmap-transition); font-size: 14px; border-bottom: 1px solid #f3f4f6; } .mindmap-context-menu-item:last-child { border-bottom: none; } .mindmap-context-menu-item:hover { background: #f9fafb; color: var(--mindmap-color-leaf-stroke); } .mindmap-context-menu-item.dangerous { color: #dc2626; } .mindmap-context-menu-item.dangerous:hover { background: #fee2e2; color: #991b1b; } /* Custom Modal */ .mindmap-modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); display: flex; align-items: center; justify-content: center; z-index: 10000; backdrop-filter: blur(2px); animation: mindmap-modal-fade-in 0.2s ease-out; } .mindmap-modal { background: var(--mindmap-bg-secondary); border-radius: 12px; padding: 24px; min-width: 320px; max-width: 90vw; box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); animation: mindmap-modal-slide-in 0.3s ease-out; } .mindmap-modal-title { font-size: 18px; font-weight: var(--mindmap-font-weight-bold); color: var(--mindmap-color-text); margin: 0 0 16px 0; text-align: center; } .mindmap-modal-input { width: 100%; padding: 12px 16px; border: 2px solid #e5e7eb; border-radius: 8px; font-size: 14px; font-family: inherit; margin-bottom: 20px; transition: var(--mindmap-transition); box-sizing: border-box; } .mindmap-modal-input:focus { outline: none; border-color: var(--mindmap-color-leaf-stroke); box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1); } .mindmap-modal-buttons { display: flex; gap: 12px; justify-content: flex-end; } .mindmap-modal-btn { padding: 10px 20px; border: none; border-radius: 6px; font-size: 14px; font-weight: var(--mindmap-font-weight-normal); cursor: pointer; transition: var(--mindmap-transition); min-height: 40px; min-width: 80px; } .mindmap-modal-btn.primary { background: var(--mindmap-color-leaf-stroke); color: white; } .mindmap-modal-btn.primary:hover { background: var(--mindmap-color-leaf-text); transform: translateY(-1px); } .mindmap-modal-btn.secondary { background: #f3f4f6; color: var(--mindmap-color-text); border: 1px solid #d1d5db; } .mindmap-modal-btn.secondary:hover { background: #e5e7eb; transform: translateY(-1px); } @keyframes mindmap-modal-fade-in { from { opacity: 0; } to { opacity: 1; } } @keyframes mindmap-modal-slide-in { from { opacity: 0; transform: translateY(-20px) scale(0.95); } to { opacity: 1; transform: translateY(0) scale(1); } } /* Mobile optimizations for modal */ @media (max-width: 480px) { .mindmap-modal { margin: 20px; min-width: calc(100vw - 40px); max-width: calc(100vw - 40px); padding: 20px; } .mindmap-modal-title { font-size: 16px; } .mindmap-modal-input { font-size: 16px; /* Prevents zoom on iOS */ padding: 14px 16px; } .mindmap-modal-buttons { flex-direction: column-reverse; gap: 8px; } .mindmap-modal-btn { width: 100%; padding: 12px 20px; min-height: 44px; } } /* Controls */ .mindmap-controls { position: absolute; top: 20px; right: 20px; display: flex; gap: 10px; z-index: 999; } .mindmap-control-btn { padding: 8px 12px; background: var(--mindmap-bg-secondary); border: 1px solid #e5e7eb; border-radius: 6px; cursor: pointer; font-size: 12px; transition: var(--mindmap-transition); box-shadow: var(--mindmap-shadow-default); } .mindmap-control-btn:hover { background: #f3f4f6; transform: translateY(-1px); } .mindmap-status { position: absolute; bottom: 20px; left: 20px; background: rgba(255, 255, 255, 0.9); padding: 8px 12px; border-radius: 6px; font-size: 12px; color: var(--mindmap-color-text); box-shadow: var(--mindmap-shadow-default); } /* Dark theme variant */ .mindmap-container.dark { --mindmap-bg-primary: linear-gradient(135deg, #1f2937 0%, #111827 100%); --mindmap-bg-secondary: #374151; --mindmap-color-text: #f9fafb; --mindmap-color-link: rgba(156, 163, 175, 0.6); } /* Compact theme variant */ .mindmap-container.compact { --mindmap-radius-root: 8px; --mindmap-radius-branch: 5px; --mindmap-radius-leaf: 6px; --mindmap-font-size-root: 12px; --mindmap-font-size-branch: 10px; --mindmap-font-size-leaf: 9px; }