Fixing time between flyouts

This commit is contained in:
Ian Roddis committed 2026-07-02 13:50:10 -03:00
1 parent 7fcf5b3f75
commit ae50ec7049
2 files changed
+212 -29

No files matched your search

+57 -7
View File
@@ -68,23 +68,65 @@ a:hover {
gap: 0.75rem;
}
/* Nav icons */
.nav-icon {
width: 14px;
height: 14px;
stroke: currentColor;
fill: none;
stroke-width: 2;
stroke-linecap: round;
stroke-linejoin: round;
flex-shrink: 0;
vertical-align: -2px;
}
/* Nav dropdowns */
.nav-group {
position: relative;
line-height: 1;
}
/* Invisible bridge so the hover isn't broken by the gap between trigger and panel */
.nav-group::after {
content: '';
position: absolute;
top: 100%;
left: 0;
right: 0;
height: 8px;
}
/* Fly-out submenus open to the right — bridge the margin-left gap */
.nav-dropdown .nav-group::after {
top: 0;
bottom: 0;
left: 100%;
right: auto;
height: auto;
width: 4px;
}
.nav-label {
cursor: default;
color: #a5b4fc;
white-space: nowrap;
user-select: none;
display: flex;
align-items: center;
gap: 0.35rem;
}
.nav-label:hover {
text-decoration: underline;
}
.topbar nav>a {
display: flex;
align-items: center;
gap: 0.35rem;
}
.nav-dropdown {
display: none;
position: absolute;
@@ -94,17 +136,19 @@ a:hover {
border: 1px solid var(--border);
border-radius: 8px;
padding: 0.3rem 0;
min-width: 180px;
min-width: 190px;
z-index: 200;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
}
.nav-group:hover > .nav-dropdown {
.nav-group:hover>.nav-dropdown {
display: block;
}
.nav-dropdown a {
display: block;
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.38rem 0.9rem;
white-space: nowrap;
color: #a5b4fc;
@@ -122,22 +166,28 @@ a:hover {
}
/* Second-level group inside a dropdown */
.nav-dropdown .nav-group > .nav-label {
display: block;
.nav-dropdown .nav-group>.nav-label {
padding: 0.38rem 0.9rem;
}
.nav-dropdown .nav-group:hover > .nav-label {
.nav-dropdown .nav-group:hover>.nav-label {
background: var(--surface-2);
text-decoration: none;
}
.nav-dropdown .nav-group > .nav-dropdown {
.nav-dropdown .nav-group>.nav-dropdown {
top: -0.3rem;
left: 100%;
margin-left: 2px;
}
.nav-chevron {
margin-left: auto;
opacity: 0.6;
font-style: normal;
font-size: 0.7em;
}
/* Cards */
.card {
background: var(--surface);
+155 -22
View File
@@ -5,59 +5,192 @@
{% set can_labels = su or "manufacturers:read" in p or "part_colours:read" in p or "part_types:read" in p or "scope_models:read" in p or "sub_part_types:read" in p %}
{% set can_database = su or "imported_parts:read" in p or "augmented_parts:read" in p %}
{% set can_parts = can_connections or can_labels or can_database %}
{# ── SVG icon sprite ───────────────────────────────────────────────────────── #}
<svg xmlns="http://www.w3.org/2000/svg" style="display:none">
<symbol id="icon-home" viewBox="0 0 24 24">
<path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/>
<polyline points="9 22 9 12 15 12 15 22"/>
</symbol>
<symbol id="icon-shield" viewBox="0 0 24 24">
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/>
</symbol>
<symbol id="icon-user" viewBox="0 0 24 24">
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/>
<circle cx="12" cy="7" r="4"/>
</symbol>
<symbol id="icon-lock" viewBox="0 0 24 24">
<rect width="18" height="11" x="3" y="11" rx="2" ry="2"/>
<path d="M7 11V7a5 5 0 0 1 10 0v4"/>
</symbol>
<symbol id="icon-list-checks" viewBox="0 0 24 24">
<path d="m3 17 2 2 4-4"/><path d="m3 7 2 2 4-4"/>
<path d="M13 6h8"/><path d="M13 12h8"/><path d="M13 18h8"/>
</symbol>
<symbol id="icon-package" viewBox="0 0 24 24">
<path d="M16.5 9.4 7.55 4.24"/>
<path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/>
<polyline points="3.27 6.96 12 12.01 20.73 6.96"/>
<line x1="12" x2="12" y1="22.08" y2="12"/>
</symbol>
<symbol id="icon-link-2" viewBox="0 0 24 24">
<path d="M9 17H7A5 5 0 0 1 7 7h2"/>
<path d="M15 7h2a5 5 0 1 1 0 10h-2"/>
<line x1="8" x2="16" y1="12" y2="12"/>
</symbol>
<symbol id="icon-maximize-2" viewBox="0 0 24 24">
<polyline points="15 3 21 3 21 9"/>
<polyline points="9 21 3 21 3 15"/>
<line x1="21" x2="14" y1="3" y2="10"/>
<line x1="3" x2="10" y1="21" y2="14"/>
</symbol>
<symbol id="icon-settings-2" viewBox="0 0 24 24">
<path d="M20 7h-9"/><path d="M14 17H5"/>
<circle cx="17" cy="17" r="3"/><circle cx="7" cy="7" r="3"/>
</symbol>
<symbol id="icon-minus-circle" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="10"/>
<line x1="8" x2="16" y1="12" y2="12"/>
</symbol>
<symbol id="icon-wrench" viewBox="0 0 24 24">
<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/>
</symbol>
<symbol id="icon-tag" viewBox="0 0 24 24">
<path d="M12 2H2v10l9.29 9.29c.94.94 2.48.94 3.42 0l6.58-6.58c.94-.94.94-2.48 0-3.42L12 2Z"/>
<path d="M7 7h.01"/>
</symbol>
<symbol id="icon-building-2" viewBox="0 0 24 24">
<path d="M6 22V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v18Z"/>
<path d="M6 12H4a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h2"/>
<path d="M18 9h2a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2h-2"/>
<path d="M10 6h4"/><path d="M10 10h4"/><path d="M10 14h4"/><path d="M10 18h4"/>
</symbol>
<symbol id="icon-droplet" viewBox="0 0 24 24">
<path d="M12 22a7 7 0 0 0 7-7c0-2-1-3.9-3-5.5s-3.5-4-4-6.5c-.5 2.5-2 4.9-4 6.5C6 11.1 5 13 5 15a7 7 0 0 0 7 7z"/>
</symbol>
<symbol id="icon-crosshair" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="10"/>
<line x1="22" x2="18" y1="12" y2="12"/>
<line x1="6" x2="2" y1="12" y2="12"/>
<line x1="12" x2="12" y1="6" y2="2"/>
<line x1="12" x2="12" y1="22" y2="18"/>
</symbol>
<symbol id="icon-corner-down-right" viewBox="0 0 24 24">
<polyline points="15 10 20 15 15 20"/>
<path d="M4 4v7a4 4 0 0 0 4 4h12"/>
</symbol>
<symbol id="icon-database" viewBox="0 0 24 24">
<ellipse cx="12" cy="5" rx="9" ry="3"/>
<path d="M3 5v14a9 3 0 0 0 18 0V5"/>
<path d="M3 12a9 3 0 0 0 18 0"/>
</symbol>
<symbol id="icon-download" viewBox="0 0 24 24">
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
<polyline points="7 10 12 15 17 10"/>
<line x1="12" x2="12" y1="15" y2="3"/>
</symbol>
<symbol id="icon-layers" viewBox="0 0 24 24">
<polygon points="12 2 2 7 12 12 22 7 12 2"/>
<polyline points="2 17 12 22 22 17"/>
<polyline points="2 12 12 17 22 12"/>
</symbol>
<symbol id="icon-alert-circle" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="10"/>
<line x1="12" x2="12" y1="8" y2="12"/>
<line x1="12" x2="12.01" y1="16" y2="16"/>
</symbol>
<symbol id="icon-book-open" viewBox="0 0 24 24">
<path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/>
<path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 0 3-3h7z"/>
</symbol>
</svg>
{# ── Nav macro for DRY icon use ────────────────────────────────────────────── #}
{% macro icon(id) %}<svg class="nav-icon"><use href="#icon-{{ id }}"/></svg>{% endmacro %}
<header class="topbar">
<div class="brand"><a href="/">{{ app_name }}</a></div>
<nav>
<a href="/">Dashboard</a>
<a href="/">{{ icon("home") }} Dashboard</a>
{% if can_admin %}
<div class="nav-group">
<span class="nav-label">Admin ▾</span>
<span class="nav-label">{{ icon("shield") }} Admin ▾</span>
<div class="nav-dropdown">
{% if su or "users:read" in p %}<a href="/admin/users">Users</a>{% endif %}
{% if su or "roles:read" in p %}<a href="/admin/roles">Roles</a>{% endif %}
{% if su or "audit_log:read" in p %}<a href="/admin/audit-log">Audit Log</a>{% endif %}
{% if su or "users:read" in p %}
<a href="/admin/users">{{ icon("user") }} Users</a>
{% endif %}
{% if su or "roles:read" in p %}
<a href="/admin/roles">{{ icon("lock") }} Roles</a>
{% endif %}
{% if su or "audit_log:read" in p %}
<a href="/admin/audit-log">{{ icon("list-checks") }} Audit Log</a>
{% endif %}
</div>
</div>
{% endif %}
{% if can_parts %}
<div class="nav-group">
<span class="nav-label">Parts ▾</span>
<span class="nav-label">{{ icon("package") }} Parts ▾</span>
<div class="nav-dropdown">
{% if can_connections %}
<div class="nav-group">
<span class="nav-label">Connections ▶</span>
<span class="nav-label">{{ icon("link-2") }} Connections <i class="nav-chevron">▶</i></span>
<div class="nav-dropdown">
{% if su or "clamp_connections:read" in p %}<a href="/admin/clamp-connections">Clamp Connections</a>{% endif %}
{% if su or "iso_threads:read" in p %}<a href="/admin/iso-threads">ISO Threads</a>{% endif %}
{% if su or "static_connections:read" in p %}<a href="/admin/static-connections">Static Connections</a>{% endif %}
{% if su or "unc_threads:read" in p %}<a href="/admin/unc-threads">UNC Threads</a>{% endif %}
{% if su or "clamp_connections:read" in p %}
<a href="/admin/clamp-connections">{{ icon("maximize-2") }} Clamp Connections</a>
{% endif %}
{% if su or "iso_threads:read" in p %}
<a href="/admin/iso-threads">{{ icon("settings-2") }} ISO Threads</a>
{% endif %}
{% if su or "static_connections:read" in p %}
<a href="/admin/static-connections">{{ icon("minus-circle") }} Static Connections</a>
{% endif %}
{% if su or "unc_threads:read" in p %}
<a href="/admin/unc-threads">{{ icon("wrench") }} UNC Threads</a>
{% endif %}
</div>
</div>
{% endif %}
{% if can_labels %}
<div class="nav-group">
<span class="nav-label">Labels ▶</span>
<span class="nav-label">{{ icon("tag") }} Labels <i class="nav-chevron">▶</i></span>
<div class="nav-dropdown">
{% if su or "manufacturers:read" in p %}<a href="/admin/manufacturers">Manufacturers</a>{% endif %}
{% if su or "part_colours:read" in p %}<a href="/admin/part-colours">Part Colours</a>{% endif %}
{% if su or "part_types:read" in p %}<a href="/admin/part-types">Part Types</a>{% endif %}
{% if su or "scope_models:read" in p %}<a href="/admin/scope-models">Scope Models</a>{% endif %}
{% if su or "sub_part_types:read" in p %}<a href="/admin/sub-part-types">Sub Part Types</a>{% endif %}
{% if su or "manufacturers:read" in p %}
<a href="/admin/manufacturers">{{ icon("building-2") }} Manufacturers</a>
{% endif %}
{% if su or "part_colours:read" in p %}
<a href="/admin/part-colours">{{ icon("droplet") }} Part Colours</a>
{% endif %}
{% if su or "part_types:read" in p %}
<a href="/admin/part-types">{{ icon("tag") }} Part Types</a>
{% endif %}
{% if su or "scope_models:read" in p %}
<a href="/admin/scope-models">{{ icon("crosshair") }} Scope Models</a>
{% endif %}
{% if su or "sub_part_types:read" in p %}
<a href="/admin/sub-part-types">{{ icon("corner-down-right") }} Sub Part Types</a>
{% endif %}
</div>
</div>
{% endif %}
{% if can_database %}
<div class="nav-group">
<span class="nav-label">Database ▶</span>
<span class="nav-label">{{ icon("database") }} Database <i class="nav-chevron">▶</i></span>
<div class="nav-dropdown">
{% if su or "imported_parts:read" in p %}<a href="/admin/imported-parts">Imported Parts</a>{% endif %}
{% if su or "augmented_parts:read" in p %}<a href="/admin/augmented-parts">Augmented Parts</a>{% endif %}
{% if su or "augmented_parts:write" in p %}<a href="/admin/augmented-parts/skipped">Skipped Parts</a>{% endif %}
{% if su or "imported_parts:read" in p %}
<a href="/admin/imported-parts">{{ icon("download") }} Imported Parts</a>
{% endif %}
{% if su or "augmented_parts:read" in p %}
<a href="/admin/augmented-parts">{{ icon("layers") }} Augmented Parts</a>
{% endif %}
{% if su or "augmented_parts:write" in p %}
<a href="/admin/augmented-parts/skipped">{{ icon("alert-circle") }} Skipped Parts</a>
{% endif %}
</div>
</div>
{% endif %}
@@ -66,7 +199,7 @@
</div>
{% endif %}
<a href="/docs" target="_blank">API docs</a>
<a href="/docs" target="_blank">{{ icon("book-open") }} API docs</a>
</nav>
<form method="post" action="/logout" class="logout">
<span class="muted">{{ user.email }}</span>