343 lines
12 KiB
CSS
343 lines
12 KiB
CSS
/* ============================================================
|
|
Family Home Lab — Components & Layout
|
|
Builds strictly from tokens.css variables per DESIGN.md.
|
|
============================================================ */
|
|
|
|
* { box-sizing: border-box; }
|
|
|
|
body {
|
|
margin: 0;
|
|
font-family: var(--font-family);
|
|
background: var(--canvas-soft);
|
|
color: var(--ink-secondary);
|
|
font: var(--type-body-md);
|
|
-webkit-font-smoothing: antialiased;
|
|
text-rendering: optimizeLegibility;
|
|
}
|
|
|
|
a { color: var(--primary); text-decoration: none; }
|
|
a:hover { text-decoration: underline; }
|
|
|
|
/* -------------------------------------------------- Login */
|
|
.login-screen {
|
|
min-height: 100vh;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background: var(--secondary);
|
|
color: var(--surface);
|
|
position: relative;
|
|
overflow: hidden;
|
|
padding: var(--space-lg);
|
|
}
|
|
/* Subtle starfield/sticker dots */
|
|
.login-screen::before {
|
|
content: "";
|
|
position: absolute; inset: 0;
|
|
background-image:
|
|
radial-gradient(rgba(255,255,255,.16) 1px, transparent 1.5px),
|
|
radial-gradient(rgba(255,255,255,.1) 1px, transparent 1.5px);
|
|
background-size: 44px 44px, 71px 71px;
|
|
background-position: 0 0, 17px 21px;
|
|
pointer-events: none;
|
|
}
|
|
.login-wrap { position: relative; z-index: 1; width: 100%; max-width: 400px; }
|
|
.login-greeting {
|
|
margin: 0 0 var(--space-xxl);
|
|
font: var(--type-display-1);
|
|
color: var(--surface);
|
|
letter-spacing: -1.5px;
|
|
}
|
|
.auth-card {
|
|
background: var(--surface);
|
|
border-radius: var(--rounded-lg);
|
|
box-shadow: var(--shadow-level-2);
|
|
padding: var(--space-xl) var(--space-xl);
|
|
color: var(--ink-secondary);
|
|
}
|
|
.auth-title { font: var(--type-title); margin: 0 0 var(--space-md); color: var(--ink); }
|
|
|
|
/* -------------------------------------------------- Form bits */
|
|
.form-field { margin-bottom: var(--space-md); }
|
|
.form-field label {
|
|
display: block;
|
|
font: var(--type-eyebrow);
|
|
letter-spacing: 0.125px;
|
|
color: var(--ink-muted);
|
|
margin-bottom: var(--space-xs);
|
|
}
|
|
.text-input {
|
|
width: 100%;
|
|
padding: 10px 12px;
|
|
font: var(--type-body-sm);
|
|
color: var(--ink);
|
|
border: 1px solid rgb(221, 221, 221);
|
|
border-radius: var(--rounded-xs);
|
|
background: var(--surface);
|
|
}
|
|
.text-input:focus {
|
|
outline: none;
|
|
border-color: var(--primary);
|
|
box-shadow: var(--shadow-level-1), 0 0 0 3px rgba(0, 117, 222, 0.18);
|
|
}
|
|
.form-error {
|
|
background: #fdecec;
|
|
color: #b3261e;
|
|
border: 1px solid #f5c6c4;
|
|
border-radius: var(--rounded-sm);
|
|
padding: var(--space-sm);
|
|
font: var(--type-body-sm);
|
|
margin-bottom: var(--space-md);
|
|
}
|
|
|
|
/* -------------------------------------------------- Buttons */
|
|
.button {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: var(--space-xs);
|
|
border: none;
|
|
cursor: pointer;
|
|
font: var(--type-button);
|
|
text-decoration: none;
|
|
transition: transform .08s ease, background .15s ease, box-shadow .15s ease;
|
|
}
|
|
.button:active { transform: scale(0.97); }
|
|
button.button, input[type="submit"].button { font-family: inherit; }
|
|
|
|
.button-primary {
|
|
background: var(--primary);
|
|
color: var(--on-primary);
|
|
border-radius: var(--rounded-full);
|
|
padding: 12px 28px;
|
|
}
|
|
.button-primary:hover { background: var(--primary-active); color: var(--on-primary); text-decoration: none; }
|
|
|
|
.button-secondary {
|
|
background: var(--surface);
|
|
color: var(--ink);
|
|
border-radius: var(--rounded-full);
|
|
padding: 11px 26px;
|
|
box-shadow: var(--shadow-level-1);
|
|
border: 1px solid var(--hairline);
|
|
}
|
|
.button-secondary:hover { box-shadow: var(--shadow-level-1); }
|
|
|
|
.button-utility {
|
|
background: var(--surface);
|
|
color: var(--ink);
|
|
border-radius: var(--rounded-md);
|
|
padding: 4px 14px;
|
|
border: 1px solid var(--hairline);
|
|
font: var(--type-body-sm);
|
|
}
|
|
.button-utility:hover { background: var(--canvas-soft); }
|
|
|
|
.width-full { width: 100%; }
|
|
|
|
/* -------------------------------------------------- Nav bar */
|
|
.nav-bar {
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 20;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: var(--space-lg);
|
|
background: var(--surface);
|
|
border-bottom: 1px solid var(--hairline);
|
|
padding: var(--space-sm) var(--space-xxl);
|
|
}
|
|
.nav-wordmark {
|
|
font: var(--type-heading-2);
|
|
color: var(--ink);
|
|
letter-spacing: -0.25px;
|
|
text-decoration: none;
|
|
}
|
|
.nav-wordmark:hover { text-decoration: none; }
|
|
.nav-right { display: flex; align-items: center; gap: var(--space-md); }
|
|
.nav-user { display: flex; align-items: center; gap: var(--space-xs); font: var(--type-body-sm); color: var(--ink-secondary); }
|
|
.nav-avatar {
|
|
width: 28px; height: 28px;
|
|
border-radius: var(--rounded-full);
|
|
background: var(--primary);
|
|
color: var(--on-primary);
|
|
display: flex; align-items: center; justify-content: center;
|
|
font: var(--type-button);
|
|
}
|
|
|
|
/* -------------------------------------------------- Layout */
|
|
.page { max-width: var(--container-max); margin: 0 auto; padding: var(--space-xxl) var(--space-lg); }
|
|
.greeting { font: var(--type-heading-1); color: var(--ink); margin: 0 0 var(--space-xxl); }
|
|
|
|
.section { margin-bottom: var(--space-xl); }
|
|
.section-head { display: flex; align-items: center; gap: var(--space-sm); margin-bottom: var(--space-md); }
|
|
.category-pill {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
font: var(--type-eyebrow);
|
|
letter-spacing: 0.125px;
|
|
background: var(--surface);
|
|
border-radius: var(--rounded-full);
|
|
padding: 4px 8px;
|
|
border: 1px solid var(--hairline);
|
|
}
|
|
.pill-dot { width: 8px; height: 8px; border-radius: var(--rounded-full); }
|
|
.section-title { font: var(--type-heading-2); color: var(--ink); margin: 0; }
|
|
|
|
/* -------------------------------------------------- Tool grid */
|
|
.tool-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(3, 1fr);
|
|
gap: var(--space-lg);
|
|
}
|
|
@media (max-width: 840px) { .tool-grid { grid-template-columns: repeat(2, 1fr); } }
|
|
@media (max-width: 600px) { .tool-grid { grid-template-columns: 1fr; } }
|
|
|
|
.tool-card {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-sm);
|
|
background: var(--surface);
|
|
border: 1px solid var(--hairline);
|
|
border-radius: var(--rounded-lg);
|
|
padding: var(--space-lg);
|
|
text-decoration: none;
|
|
color: var(--ink-secondary);
|
|
transition: box-shadow .18s ease, transform .18s ease;
|
|
}
|
|
.tool-card:hover {
|
|
box-shadow: var(--shadow-level-1);
|
|
transform: translateY(-1px);
|
|
text-decoration: none;
|
|
}
|
|
.tool-card-top { display: flex; align-items: flex-start; justify-content: space-between; }
|
|
.tool-icon {
|
|
width: 40px; height: 40px;
|
|
border-radius: var(--rounded-full);
|
|
display: flex; align-items: center; justify-content: center;
|
|
color: var(--surface);
|
|
font: var(--type-title);
|
|
flex: none;
|
|
}
|
|
.tool-card .tool-name { font: var(--type-title); color: var(--ink); margin: 0; }
|
|
.tool-card .tool-desc { font: var(--type-body-sm); color: var(--ink-muted); margin: 0; flex: 1; }
|
|
.tool-card-bottom { display: flex; align-items: center; justify-content: space-between; }
|
|
.launch-chip { font: var(--type-caption); color: var(--ink-faint); }
|
|
.tag-chip {
|
|
font: var(--type-caption);
|
|
color: var(--ink-muted);
|
|
border: 1px solid var(--hairline);
|
|
border-radius: var(--rounded-full);
|
|
padding: 1px 8px;
|
|
background: var(--surface-2);
|
|
}
|
|
.tag-chip-login { color: var(--sticker-orange); border-color: color-mix(in srgb, var(--sticker-orange) 40%, transparent); }
|
|
.tag-chip-admin { color: var(--ink-muted); border-style: dashed; }
|
|
|
|
/* catalogue search */
|
|
.dash-search {
|
|
max-width: 480px;
|
|
margin-bottom: var(--space-lg);
|
|
}
|
|
.tool-grid .tool-card.hidden { display: none; }
|
|
.section.hidden-section { display: none; }
|
|
|
|
/* status dot levels */
|
|
.status-dot {
|
|
width: 8px; height: 8px; border-radius: var(--rounded-full); display: inline-block;
|
|
}
|
|
.status-online { background: var(--sticker-green); }
|
|
.status-starting { background: var(--sticker-orange); }
|
|
.status-offline { background: var(--ink-faint); }
|
|
|
|
/* loading pulse for polling */
|
|
.tool-grid.htmx-request .tool-card { opacity: .6; transition: opacity .2s; }
|
|
|
|
/* -------------------------------------------------- Tool embed */
|
|
.tool-bar {
|
|
position: sticky; top: 52px; z-index: 15;
|
|
display: flex; align-items: center; justify-content: space-between;
|
|
gap: var(--space-md);
|
|
background: var(--surface);
|
|
border-bottom: 1px solid var(--hairline);
|
|
padding: var(--space-sm) var(--space-xxl);
|
|
}
|
|
.embed-well {
|
|
background: var(--surface);
|
|
border: 1px solid var(--hairline);
|
|
border-radius: var(--rounded-lg);
|
|
overflow: hidden;
|
|
height: calc(100vh - 170px);
|
|
box-shadow: var(--shadow-level-1);
|
|
}
|
|
.embed-well iframe { width: 100%; height: 100%; border: 0; display: block; }
|
|
|
|
/* -------------------------------------------------- Link-out fallback */
|
|
.linkout-card {
|
|
background: var(--surface);
|
|
border: 1px solid var(--hairline);
|
|
border-radius: var(--rounded-lg);
|
|
padding: var(--space-xl);
|
|
max-width: 520px;
|
|
box-shadow: var(--shadow-level-1);
|
|
}
|
|
|
|
/* -------------------------------------------------- Partial rows (status) */
|
|
.status-refresh {
|
|
display: contents; /* keeps the HTMX swap invisible-pressure-free */
|
|
}
|
|
|
|
/* -------------------------------------------------- Admin */
|
|
.user-table { width: 100%; border-collapse: collapse; background: var(--surface); border-radius: var(--rounded-lg); overflow: hidden; border: 1px solid var(--hairline); }
|
|
.user-table th, .user-table td { text-align: left; padding: var(--space-sm) var(--space-md); border-bottom: 1px solid var(--hairline); font: var(--type-body-sm); }
|
|
.user-table th { background: var(--canvas-soft); color: var(--ink-muted); font: var(--type-eyebrow); letter-spacing: .125px; }
|
|
.user-table tr:last-child td { border-bottom: none; }
|
|
.badge { display: inline-block; font: var(--type-eyebrow); border-radius: var(--rounded-full); padding: 2px 8px; background: var(--canvas-soft); color: var(--ink-muted); }
|
|
.badge-admin { background: var(--secondary); color: var(--surface); }
|
|
|
|
.admin-panel { display: grid; grid-template-columns: 2fr 1fr; gap: var(--space-xxl); align-items: start; }
|
|
@media (max-width: 840px) { .admin-panel { grid-template-columns: 1fr; } }
|
|
|
|
/* -------------------------------------------------- Workspace / file list */
|
|
.tool-detail { display: flex; flex-direction: column; gap: var(--space-lg); }
|
|
.workspace {
|
|
background: var(--surface);
|
|
border: 1px solid var(--hairline);
|
|
border-radius: var(--rounded-lg);
|
|
padding: var(--space-lg) var(--space-xl);
|
|
box-shadow: var(--shadow-level-1);
|
|
}
|
|
.workspace-head {
|
|
display: flex; align-items: baseline; justify-content: space-between;
|
|
gap: var(--space-md); margin-bottom: var(--space-sm);
|
|
}
|
|
.file-list { list-style: none; margin: 0; padding: 0; }
|
|
.file-list li {
|
|
display: flex; align-items: center; justify-content: space-between;
|
|
gap: var(--space-md); padding: 10px 2px;
|
|
border-bottom: 1px solid var(--hairline); font: var(--type-body-sm);
|
|
}
|
|
.file-list li:last-child { border-bottom: none; }
|
|
.file-name { color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
.file-meta { color: var(--ink-faint); font: var(--type-caption); white-space: nowrap; }
|
|
|
|
/* -------------------------------------------------- Minimal, generic */
|
|
.muted { color: var(--ink-muted); }
|
|
.faint { color: var(--ink-faint); }
|
|
.margin-top { margin-top: var(--space-lg); }
|
|
.stack > * + * { margin-top: var(--space-lg); }
|
|
/* ---------- Responsive (mobile) ---------- */
|
|
@media (max-width: 640px) {
|
|
.nav-bar {
|
|
flex-wrap: wrap;
|
|
gap: var(--space-xs);
|
|
padding: var(--space-sm) var(--space-md);
|
|
}
|
|
.nav-right { flex-wrap: wrap; gap: var(--space-xs); }
|
|
.nav-user span:last-child { display: none; } /* hide full name, keep avatar */
|
|
.page { padding: var(--space-lg) var(--space-md); }
|
|
.greeting { font: var(--type-heading-2); }
|
|
}
|