/* Reset and base styles */ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } :root { /* Color palette - soft, muted tones */ --bg: #fafaf9; --text: #1c1917; --text-muted: #78716c; --border: #e7e5e4; --accent: #0c4a6e; --accent-light: #e0f2fe; --error: #dc2626; /* Language family colors - earthy, distinct */ --lang-modern: #0284c7; /* Modern languages (en, fr, de, etc.) */ --lang-latin: #7c3aed; /* Latin and Romance */ --lang-greek: #059669; /* Greek */ --lang-germanic: #ea580c; /* Proto-Germanic */ --lang-pie: #dc2626; /* Proto-Indo-European */ --lang-semitic: #d97706; /* Semitic languages */ --lang-other: #64748b; /* Other/unknown */ /* Spacing */ --space-xs: 0.25rem; --space-sm: 0.5rem; --space-md: 1rem; --space-lg: 2rem; --space-xl: 4rem; /* Typography */ --font-sans: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; --font-serif: 'EB Garamond', Garamond, 'Times New Roman', serif; --font-mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace; } html { font-size: 16px; } body { font-family: var(--font-sans); background: var(--bg); color: var(--text); line-height: 1.6; min-height: 100vh; display: flex; flex-direction: column; } main { flex: 1; display: flex; flex-direction: column; padding: var(--space-sm) var(--space-lg) var(--space-lg); max-width: 1200px; margin: 0 auto; width: 100%; } /* Header */ header { text-align: center; margin-bottom: var(--space-lg); position: relative; } h1 { font-size: 2rem; font-weight: 600; letter-spacing: -0.02em; color: var(--text); margin-top: 0; } .subtitle { color: var(--text-muted); font-size: 1rem; margin-top: var(--space-xs); } /* Search */ .search-container { display: flex; gap: var(--space-sm); max-width: 480px; margin: 0 auto var(--space-xs); width: 100%; } .search-hint { text-align: center; font-size: 0.8rem; color: var(--text-muted); margin-bottom: var(--space-xs); } /* Graph options */ .graph-options { display: flex; justify-content: center; gap: var(--space-md); margin-bottom: var(--space-sm); max-width: 480px; margin-left: auto; margin-right: auto; } .depth-control { display: flex; align-items: center; gap: var(--space-xs); font-size: 0.8rem; color: var(--text-muted); } .depth-label { font-weight: 500; margin-right: var(--space-xs); } .depth-btn { width: 28px; height: 28px; padding: 0; font-size: 1rem; font-weight: 500; line-height: 1; border-radius: 6px; display: flex; align-items: center; justify-content: center; } .depth-btn:disabled { opacity: 0.4; cursor: not-allowed; } .depth-value { min-width: 1.5em; text-align: center; font-weight: 600; font-size: 0.9rem; color: var(--text); } /* Settings popover */ .settings-wrapper { position: relative; } .settings-popover { position: absolute; top: calc(100% + 6px); right: 0; background: white; border: 1px solid var(--border); border-radius: 8px; padding: var(--space-sm); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); z-index: 20; min-width: 200px; display: flex; flex-direction: column; gap: var(--space-xs); } .settings-option { display: flex; align-items: center; gap: var(--space-xs); font-size: 0.8rem; color: var(--text-muted); cursor: pointer; padding: 4px 0; white-space: nowrap; } .settings-option input[type="checkbox"] { width: 14px; height: 14px; cursor: pointer; accent-color: var(--accent); } .settings-option:hover { color: var(--text); } .search-wrapper { flex: 1; position: relative; } #word-input { width: 100%; padding: var(--space-sm) var(--space-md); font-size: 1rem; border: 1px solid var(--border); border-radius: 8px; background: white; color: var(--text); outline: none; transition: border-color 0.2s, box-shadow 0.2s; } /* Autocomplete suggestions */ .suggestions { position: absolute; top: 100%; left: 0; right: 0; background: white; border: 1px solid var(--border); border-top: none; border-radius: 0 0 8px 8px; max-height: 300px; overflow-y: auto; z-index: 100; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); } .suggestion-item { padding: var(--space-sm) var(--space-md); cursor: pointer; border-bottom: 1px solid var(--border); } .suggestion-item:last-child { border-bottom: none; } .suggestion-item:hover, .suggestion-item.selected { background: var(--accent-light); } .suggestion-word { font-weight: 500; color: var(--text); } .suggestion-sense { font-size: 0.875rem; color: var(--text-muted); margin-top: 2px; } #word-input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-light); } #word-input::placeholder { color: var(--text-muted); } button { padding: var(--space-sm) var(--space-md); border: 1px solid var(--border); border-radius: 8px; background: white; color: var(--text); cursor: pointer; display: flex; align-items: center; justify-content: center; transition: background 0.2s, border-color 0.2s; } button:hover { background: var(--bg); border-color: var(--text-muted); } button:active { transform: translateY(1px); } #search-btn { background: var(--accent); border-color: var(--accent); color: white; } #search-btn:hover { background: #0369a1; border-color: #0369a1; } /* Graph container */ #graph-container { flex: 1; min-height: 400px; background: white; border: 1px solid var(--border); border-radius: 12px; position: relative; overflow: hidden; } /* Expanded graph state */ #graph-container.expanded { position: fixed; top: var(--space-md); left: var(--space-md); right: var(--space-md); bottom: var(--space-md); z-index: 50; min-height: auto; box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2); transition: all 0.3s ease; } /* Expand/minimize button */ .expand-btn { position: absolute; top: var(--space-sm); right: var(--space-sm); z-index: 15; padding: var(--space-xs); background: white; border: 1px solid var(--border); border-radius: 6px; cursor: pointer; color: var(--text-muted); display: flex; align-items: center; justify-content: center; transition: all 0.2s; } .expand-btn:hover { background: var(--bg); color: var(--text); border-color: var(--text-muted); } .expand-btn .minimize-icon { display: none; } #graph-container.expanded .expand-btn .expand-icon { display: none; } #graph-container.expanded .expand-btn .minimize-icon { display: block; } /* Backdrop when expanded */ .graph-backdrop { position: fixed; inset: 0; background: rgba(250, 250, 249, 0.9); z-index: 40; opacity: 0; pointer-events: none; transition: opacity 0.3s ease; } .graph-backdrop.visible { opacity: 1; pointer-events: auto; } #cy { width: 100%; height: 100%; position: absolute; top: 0; left: 0; } /* Cytoscape HTML node labels */ .cy-node-html-label { pointer-events: none; } .cy-node-label { text-align: center; padding: 8px 12px; display: flex; flex-direction: column; align-items: center; justify-content: center; } .node-lang { font-family: system-ui, -apple-system, sans-serif; font-size: 10px; font-weight: 600; color: #78716c; text-transform: lowercase; margin-bottom: 4px; } .node-word { font-family: 'EB Garamond', Garamond, serif; font-size: 18px; font-weight: 600; color: #1c1917; line-height: 1.2; } .node-sense { font-family: 'EB Garamond', Garamond, serif; font-size: 11px; font-style: italic; color: #78716c; margin-top: 4px; line-height: 1.3; max-width: 140px; } /* States */ #empty-state, #error-state, #loading { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center; color: var(--text-muted); } #empty-state p, #error-state p { font-size: 1rem; } #error-state { color: #dc2626; } /* Error action buttons */ .error-actions { display: flex; flex-wrap: wrap; gap: var(--space-sm); justify-content: center; margin-top: var(--space-md); } .error-action-btn { display: inline-flex; align-items: center; gap: var(--space-xs); padding: var(--space-xs) var(--space-md); font-size: 0.8rem; border: 1px solid var(--border); border-radius: 6px; background: white; color: var(--accent); text-decoration: none; cursor: pointer; transition: background 0.2s, border-color 0.2s; } .error-action-btn:hover { background: var(--accent-light); border-color: var(--accent); } .error-action-report { color: var(--text-muted); } .error-action-report:hover { color: var(--text); } .hidden { display: none !important; } /* Loading spinner */ #loading { display: flex; flex-direction: column; align-items: center; gap: var(--space-sm); } .spinner { width: 32px; height: 32px; border: 3px solid var(--border); border-top-color: var(--accent); border-radius: 50%; animation: spin 0.8s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } /* Word info bar */ #word-info { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-sm) var(--space-md); margin-top: var(--space-md); padding: var(--space-sm) var(--space-md); background: white; border: 1px solid var(--border); border-radius: 8px; } #current-word { font-family: var(--font-serif); font-size: 1.25rem; font-weight: 600; color: var(--text); } .info-divider { width: 1px; height: 1.25rem; background: var(--border); } #lang-breakdown { display: flex; flex-wrap: wrap; gap: var(--space-xs) var(--space-sm); font-size: 0.8rem; color: var(--text-muted); } .lang-chip { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px; background: var(--bg); border-radius: 12px; } .lang-chip-name { color: var(--text); } .lang-chip-count { color: var(--text-muted); font-size: 0.75rem; } /* Stats toggle button */ .stats-toggle { display: flex; align-items: center; gap: var(--space-xs); margin-left: auto; padding: var(--space-xs) var(--space-sm); font-size: 0.75rem; background: transparent; border: 1px solid var(--border); border-radius: 6px; color: var(--text-muted); cursor: pointer; } .stats-toggle:hover { background: var(--bg); color: var(--text); } .stats-toggle.active { background: var(--accent-light); border-color: var(--accent); color: var(--accent); } /* Stats panel (below word-info) */ .stats-panel { margin-top: var(--space-sm); padding: var(--space-sm) var(--space-md); background: white; border: 1px solid var(--border); border-radius: 8px; } .stats-grid { display: flex; justify-content: center; gap: var(--space-lg); } .stat-item { display: flex; flex-direction: column; align-items: center; gap: 2px; } .stat-value { font-size: 1.25rem; font-weight: 600; color: var(--text); font-family: var(--font-mono); } .stat-label { font-size: 0.7rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.05em; } /* Node detail panel */ #node-detail { position: absolute; top: var(--space-md); right: var(--space-md); background: white; border: 1px solid var(--border); border-radius: 8px; padding: var(--space-md); min-width: 220px; max-width: 300px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); z-index: 10; font-family: var(--font-serif); } #detail-close { position: absolute; top: var(--space-xs); right: var(--space-xs); padding: var(--space-xs); border: none; background: transparent; cursor: pointer; color: var(--text-muted); border-radius: 4px; } #detail-close:hover { background: var(--bg); color: var(--text); } .detail-header { margin-bottom: var(--space-sm); padding-right: var(--space-lg); } .detail-lang { display: block; font-size: 0.8rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: var(--space-xs); } .detail-word { display: block; font-size: 1.5rem; font-weight: 600; color: var(--text); line-height: 1.2; } .detail-row { display: flex; flex-direction: column; gap: 2px; padding: var(--space-sm) 0; border-top: 1px solid var(--border); } .detail-row .detail-label { display: flex; align-items: center; gap: var(--space-xs); font-family: var(--font-sans); font-size: 0.7rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.05em; } .detail-value { font-size: 1rem; color: var(--text); } .detail-row:last-child .detail-value { font-style: italic; } /* Info tooltip button */ .info-btn { display: inline-flex; align-items: center; justify-content: center; width: 14px; height: 14px; border-radius: 50%; background: var(--border); color: var(--text-muted); font-size: 0.6rem; font-weight: 600; font-family: var(--font-sans); cursor: help; border: none; padding: 0; position: relative; } .info-btn:hover { background: var(--text-muted); color: white; } .info-btn .tooltip { display: none; position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%); background: var(--text); color: white; font-size: 0.75rem; font-weight: 400; text-transform: none; letter-spacing: normal; padding: var(--space-xs) var(--space-sm); border-radius: 4px; white-space: nowrap; margin-bottom: 4px; z-index: 20; } .info-btn:hover .tooltip { display: block; } /* Graph legend */ .graph-legend { position: absolute; bottom: var(--space-md); left: var(--space-md); display: flex; align-items: center; gap: var(--space-sm); padding: var(--space-xs) var(--space-sm); background: rgba(255, 255, 255, 0.9); border: 1px solid var(--border); border-radius: 6px; font-size: 0.7rem; color: var(--text-muted); z-index: 5; backdrop-filter: blur(4px); } /* Direction indicator within legend */ #direction-indicator { display: inline-flex; align-items: center; gap: var(--space-xs); } #direction-indicator.vertical { flex-direction: column; } .direction-label { font-family: var(--font-sans); letter-spacing: 0.02em; color: var(--text-muted); } .direction-arrow { color: var(--text-muted); font-size: 1rem; line-height: 1; } /* Legend divider */ .legend-divider { color: var(--border); font-weight: 300; } /* Edge type legend */ .edge-legend { display: flex; align-items: center; gap: var(--space-sm); } .legend-item { display: flex; align-items: center; gap: 4px; } .legend-line { display: inline-block; width: 20px; height: 2px; vertical-align: middle; } .legend-line.regular { background: #d6d3d1; } .legend-line.compound { background: var(--accent); } .legend-line.link-inh { background: #059669; } .legend-line.link-bor { background: #d97706; } .legend-line.link-der { background: #7c3aed; } .legend-line.link-cog { background: #0284c7; } .legend-line.link-cmpd { background: #0c4a6e; } /* Header buttons */ .header-buttons { position: absolute; top: 0.15em; right: 0; display: grid; grid-template-columns: auto auto; gap: var(--space-xs); justify-items: end; } .header-buttons .settings-wrapper { grid-column: 2; } .header-btn { display: flex; align-items: center; justify-content: center; gap: var(--space-xs); padding: var(--space-xs) var(--space-sm); font-size: 0.875rem; background: transparent; border: 1px solid var(--border); border-radius: 6px; color: var(--text-muted); cursor: pointer; text-decoration: none; } .header-btn:hover { background: var(--bg); color: var(--text); } /* Mobile menu (hidden on desktop by default) */ .mobile-only { display: none; } .mobile-menu-wrapper { position: relative; } #mobile-menu-btn { min-width: 44px; min-height: 44px; } .mobile-menu { position: absolute; top: calc(100% + 6px); right: 0; background: white; border: 1px solid var(--border); border-radius: 8px; padding: var(--space-xs) 0; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); z-index: 20; min-width: 200px; } .mobile-menu-item { display: flex; align-items: center; gap: var(--space-sm); width: 100%; padding: var(--space-sm) var(--space-md); font-size: 0.875rem; color: var(--text); background: none; border: none; border-radius: 0; cursor: pointer; text-decoration: none; text-align: left; } .mobile-menu-item:hover { background: var(--bg); } .mobile-about-link { color: var(--accent); font-weight: 500; justify-content: flex-start; } .mobile-external-link { justify-content: space-between; } .mobile-external-link .external-icon { color: var(--text-muted); font-size: 0.75rem; } .mobile-menu-divider { height: 1px; background: var(--border); margin: var(--space-xs) 0; } /* Modal */ .modal { position: fixed; inset: 0; z-index: 100; display: flex; align-items: center; justify-content: center; padding: var(--space-md); } .modal-backdrop { position: absolute; inset: 0; background: rgba(0, 0, 0, 0.5); } .modal-content { position: relative; background: white; border-radius: 12px; max-width: 600px; max-height: 80vh; overflow-y: auto; padding: var(--space-lg); box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2); } .modal-close { position: absolute; top: var(--space-sm); right: var(--space-sm); padding: var(--space-xs); background: transparent; border: none; color: var(--text-muted); cursor: pointer; border-radius: 4px; } .modal-close:hover { background: var(--bg); color: var(--text); } .modal-tabs { display: flex; gap: var(--space-xs); margin-bottom: var(--space-md); border-bottom: 1px solid var(--border); padding-bottom: var(--space-sm); } .modal-tab { padding: var(--space-xs) var(--space-sm); background: transparent; border: none; color: var(--text-muted); cursor: pointer; font-size: 0.875rem; border-radius: 4px; } .modal-tab:hover { background: var(--bg); } .modal-tab.active { background: var(--accent-light); color: var(--accent); font-weight: 500; } .tab-content { display: none; } .tab-content.active { display: block; } .tab-content h2 { font-family: var(--font-serif); font-size: 1.5rem; margin-bottom: var(--space-md); } .tab-content h3 { font-size: 1rem; margin-top: var(--space-md); margin-bottom: var(--space-sm); color: var(--text); } .tab-content p { margin-bottom: var(--space-sm); line-height: 1.7; color: var(--text); } .tab-content .philosophy { font-family: var(--font-serif); font-size: 1.25rem; font-style: italic; margin-bottom: var(--space-md); } .tab-content .citation { font-size: 0.875rem; color: var(--text-muted); font-style: italic; } .tab-content .example { font-size: 0.875rem; color: var(--text-muted); background: var(--bg); padding: var(--space-sm) var(--space-md); border-radius: 6px; border-left: 3px solid var(--accent); } .tab-content code { font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace; background: var(--border); padding: 1px 5px; border-radius: 3px; font-size: 0.85em; } .tab-content ol, .tab-content ul { margin-bottom: var(--space-sm); padding-left: var(--space-lg); line-height: 1.8; } .tab-content li { margin-bottom: var(--space-xs); } .tab-content a { color: var(--accent); } /* View toggle buttons */ .view-toggle { display: flex; align-items: center; gap: 0; } .view-btn { padding: 2px var(--space-xs); font-size: 0.75rem; background: transparent; border: none; color: var(--text-muted); cursor: pointer; transition: color 0.15s ease; } .view-btn:hover { color: var(--text); } .view-btn.active { color: var(--text); font-weight: 600; } .view-btn svg { display: none; } .view-toggle .view-btn + .view-btn { border-left: 1px solid var(--border); } /* Tree view container */ .tree-view { width: 100%; height: 100%; position: absolute; top: 0; left: 0; overflow: auto; padding: var(--space-md); background: white; } .tree-view.hidden { display: none; } .tree-content { font-family: var(--font-mono); font-size: 0.875rem; line-height: 1.6; white-space: pre; } .tree-line { display: block; } .tree-node { cursor: pointer; padding: 2px 4px; border-radius: 4px; transition: background 0.15s ease; } .tree-node:hover { background: var(--accent-light); } .tree-word { font-family: var(--font-serif); font-weight: 600; color: var(--text); } .tree-lang { color: var(--text-muted); font-family: var(--font-sans); font-size: 0.8em; } .tree-empty { text-align: center; color: var(--text-muted); padding: var(--space-xl); } /* Footer */ footer { text-align: center; padding: var(--space-md); color: var(--text-muted); font-size: 0.875rem; } footer a { color: var(--accent); text-decoration: none; } footer a:hover { text-decoration: underline; } /* Version details in footer */ .version-details { margin-top: var(--space-sm); font-size: 0.75rem; color: var(--text-muted); } .version-details summary { cursor: pointer; user-select: none; display: inline; } .version-details summary:hover { color: var(--text); } .version-content { display: flex; justify-content: center; gap: var(--space-md); margin-top: var(--space-xs); font-size: 0.75rem; color: var(--text-muted); } /* Responsive */ @media (max-width: 640px) { main { padding: var(--space-sm); } header { margin-bottom: var(--space-md); } h1 { font-size: 1.5rem; padding-right: 0; } .subtitle { font-size: 0.875rem; } .desktop-only { display: none !important; } .mobile-only { display: block; } .header-buttons { grid-template-columns: auto; } /* Keep search on one row with compact buttons */ .search-container { gap: var(--space-xs); margin-bottom: var(--space-xs); flex-wrap: nowrap; } .search-hint { font-size: 0.7rem; margin-bottom: var(--space-xs); } .graph-options { margin-bottom: var(--space-xs); flex-wrap: wrap; } .view-toggle { order: -1; justify-content: center; margin-bottom: var(--space-xs); } .depth-control { font-size: 0.75rem; } .tree-content { font-size: 0.75rem; } .depth-btn { width: 32px; height: 32px; } #word-input { padding: var(--space-xs) var(--space-sm); font-size: 16px; /* Prevent iOS auto-zoom on focus */ } #search-btn, #random-btn { padding: var(--space-xs) var(--space-sm); min-width: 44px; } #search-btn svg, #random-btn svg { width: 18px; height: 18px; } /* Graph takes more space */ #graph-container { min-height: 50vh; flex: 1; } /* Legend vertical on mobile - top-left to avoid overlapping leaf nodes */ .graph-legend { font-size: 0.6rem; padding: 4px 6px; top: var(--space-sm); bottom: auto; left: var(--space-sm); gap: 2px; flex-direction: column; align-items: flex-start; } .edge-legend { gap: 2px; flex-direction: column; } .legend-divider { display: none; } .legend-line { width: 14px; } /* Direction indicator vertical on mobile */ #direction-indicator { flex-direction: column; align-items: flex-start; } /* Detail panel full width at bottom on mobile */ #node-detail { position: fixed; top: auto; bottom: 0; left: 0; right: 0; max-width: none; min-width: auto; border-radius: 12px 12px 0 0; padding: var(--space-sm) var(--space-md); box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.15); z-index: 55; } .detail-word { font-size: 1.25rem; } .detail-row { padding: var(--space-xs) 0; } /* Info bar more compact */ #word-info { padding: var(--space-xs) var(--space-sm); gap: var(--space-xs) var(--space-sm); margin-top: var(--space-sm); } #current-word { font-size: 1rem; } #lang-breakdown { font-size: 0.7rem; } .lang-chip { padding: 1px 6px; } /* Stats panel on mobile */ .stats-grid { gap: var(--space-md); } .stat-value { font-size: 1rem; } .stat-label { font-size: 0.6rem; } .stats-toggle { font-size: 0.7rem; padding: 2px 6px; } /* Modal adjustments */ .modal-content { padding: var(--space-md); max-height: 90vh; } .tab-content h2 { font-size: 1.25rem; } footer { padding: var(--space-sm); font-size: 0.75rem; } .mobile-menu-wrapper.mobile-only { display: block; } }