195 lines
4.0 KiB
Svelte
195 lines
4.0 KiB
Svelte
|
|
<script lang="ts">
|
||
|
|
import { page } from '$app/state';
|
||
|
|
import { operatorSession } from '$lib/session';
|
||
|
|
|
||
|
|
const links = [
|
||
|
|
{ href: '/', label: 'Home' },
|
||
|
|
{ href: '/raw-materials', label: 'Raw Materials' },
|
||
|
|
{ href: '/mixes', label: 'Mix Master' },
|
||
|
|
{ href: '/products', label: 'Products' },
|
||
|
|
{ href: '/scenarios', label: 'Scenarios' }
|
||
|
|
];
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<svelte:head>
|
||
|
|
<title>Data Entry App</title>
|
||
|
|
</svelte:head>
|
||
|
|
|
||
|
|
<div class="shell">
|
||
|
|
<header class="topbar">
|
||
|
|
<div class="brand-block">
|
||
|
|
<a class="brand" href="/">Data Entry App</a>
|
||
|
|
<p>Operator costing workflow</p>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<nav class="topnav" aria-label="Primary navigation">
|
||
|
|
{#each links as link}
|
||
|
|
<a class:active={page.url.pathname === link.href} href={link.href}>{link.label}</a>
|
||
|
|
{/each}
|
||
|
|
</nav>
|
||
|
|
|
||
|
|
<div class="session-panel">
|
||
|
|
{#if $operatorSession}
|
||
|
|
<div>
|
||
|
|
<span>Signed in</span>
|
||
|
|
<strong>{$operatorSession.name}</strong>
|
||
|
|
</div>
|
||
|
|
<button type="button" onclick={() => operatorSession.clear()}>Sign out</button>
|
||
|
|
{:else}
|
||
|
|
<a class="login-link" href="/">Operator login</a>
|
||
|
|
{/if}
|
||
|
|
</div>
|
||
|
|
</header>
|
||
|
|
|
||
|
|
<main class="content">
|
||
|
|
<slot />
|
||
|
|
</main>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<style>
|
||
|
|
:global(:root) {
|
||
|
|
--canvas: #f5efe4;
|
||
|
|
--canvas-strong: #fffaf1;
|
||
|
|
--ink: #20170f;
|
||
|
|
--muted: #695746;
|
||
|
|
--line: rgba(74, 53, 31, 0.14);
|
||
|
|
--brand: #8f4f1f;
|
||
|
|
--brand-deep: #5a2d18;
|
||
|
|
--accent: #d9a441;
|
||
|
|
--shadow: 0 18px 50px rgba(56, 38, 19, 0.12);
|
||
|
|
}
|
||
|
|
|
||
|
|
:global(body) {
|
||
|
|
margin: 0;
|
||
|
|
color: var(--ink);
|
||
|
|
font-family: "Segoe UI", "Helvetica Neue", sans-serif;
|
||
|
|
background:
|
||
|
|
radial-gradient(circle at top right, rgba(217, 164, 65, 0.22), transparent 24rem),
|
||
|
|
radial-gradient(circle at left center, rgba(143, 79, 31, 0.1), transparent 28rem),
|
||
|
|
linear-gradient(180deg, #f7f1e7 0%, #efe5d3 100%);
|
||
|
|
}
|
||
|
|
|
||
|
|
:global(*) {
|
||
|
|
box-sizing: border-box;
|
||
|
|
}
|
||
|
|
|
||
|
|
.shell {
|
||
|
|
min-height: 100vh;
|
||
|
|
}
|
||
|
|
|
||
|
|
.topbar {
|
||
|
|
position: sticky;
|
||
|
|
top: 0;
|
||
|
|
z-index: 10;
|
||
|
|
display: grid;
|
||
|
|
grid-template-columns: auto 1fr auto;
|
||
|
|
gap: 1rem;
|
||
|
|
align-items: center;
|
||
|
|
padding: 1rem 2rem;
|
||
|
|
backdrop-filter: blur(16px);
|
||
|
|
background: rgba(247, 241, 231, 0.88);
|
||
|
|
border-bottom: 1px solid var(--line);
|
||
|
|
}
|
||
|
|
|
||
|
|
.brand-block {
|
||
|
|
display: flex;
|
||
|
|
flex-direction: column;
|
||
|
|
gap: 0.15rem;
|
||
|
|
}
|
||
|
|
|
||
|
|
.brand {
|
||
|
|
color: var(--brand-deep);
|
||
|
|
text-decoration: none;
|
||
|
|
font-size: 1.25rem;
|
||
|
|
font-weight: 700;
|
||
|
|
letter-spacing: 0.02em;
|
||
|
|
}
|
||
|
|
|
||
|
|
.brand-block p,
|
||
|
|
.session-panel span {
|
||
|
|
margin: 0;
|
||
|
|
color: var(--muted);
|
||
|
|
font-size: 0.8rem;
|
||
|
|
text-transform: uppercase;
|
||
|
|
letter-spacing: 0.08em;
|
||
|
|
}
|
||
|
|
|
||
|
|
.topnav {
|
||
|
|
display: flex;
|
||
|
|
justify-content: center;
|
||
|
|
flex-wrap: wrap;
|
||
|
|
gap: 0.65rem;
|
||
|
|
}
|
||
|
|
|
||
|
|
.topnav a,
|
||
|
|
.login-link,
|
||
|
|
button {
|
||
|
|
border: 1px solid transparent;
|
||
|
|
border-radius: 999px;
|
||
|
|
padding: 0.75rem 1rem;
|
||
|
|
color: var(--brand-deep);
|
||
|
|
text-decoration: none;
|
||
|
|
background: transparent;
|
||
|
|
font: inherit;
|
||
|
|
cursor: pointer;
|
||
|
|
transition:
|
||
|
|
border-color 160ms ease,
|
||
|
|
background-color 160ms ease,
|
||
|
|
transform 160ms ease;
|
||
|
|
}
|
||
|
|
|
||
|
|
.topnav a:hover,
|
||
|
|
.topnav a.active,
|
||
|
|
.login-link:hover,
|
||
|
|
button:hover {
|
||
|
|
background: rgba(143, 79, 31, 0.08);
|
||
|
|
border-color: rgba(143, 79, 31, 0.18);
|
||
|
|
transform: translateY(-1px);
|
||
|
|
}
|
||
|
|
|
||
|
|
.topnav a.active {
|
||
|
|
background: linear-gradient(135deg, rgba(143, 79, 31, 0.14), rgba(217, 164, 65, 0.18));
|
||
|
|
font-weight: 600;
|
||
|
|
}
|
||
|
|
|
||
|
|
.session-panel {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
gap: 0.9rem;
|
||
|
|
}
|
||
|
|
|
||
|
|
.session-panel strong {
|
||
|
|
display: block;
|
||
|
|
}
|
||
|
|
|
||
|
|
button {
|
||
|
|
background: var(--brand-deep);
|
||
|
|
color: #fff7ef;
|
||
|
|
box-shadow: var(--shadow);
|
||
|
|
}
|
||
|
|
|
||
|
|
button:hover {
|
||
|
|
background: #472213;
|
||
|
|
}
|
||
|
|
|
||
|
|
.content {
|
||
|
|
padding: 2rem;
|
||
|
|
}
|
||
|
|
|
||
|
|
@media (max-width: 980px) {
|
||
|
|
.topbar {
|
||
|
|
grid-template-columns: 1fr;
|
||
|
|
justify-items: start;
|
||
|
|
padding: 1rem 1rem 0.9rem;
|
||
|
|
}
|
||
|
|
|
||
|
|
.topnav {
|
||
|
|
justify-content: flex-start;
|
||
|
|
}
|
||
|
|
|
||
|
|
.content {
|
||
|
|
padding: 1rem;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
</style>
|