<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ctext y='.9em' font-size='88'%3E%E2%9A%99%EF%B8%8F%3C/text%3E%3C/svg%3E">
<title>{% block title %}devendra{% endblock %}</title>
<!-- Theme: set data-theme before first paint to avoid a flash. Mirrors the
../dms setup — the same daisyUI palettes, system default, and toggle. -->
<script>
(() => {
const DARK = "afterdark", LIGHT = "her";
const mq = window.matchMedia("(prefers-color-scheme: dark)");
const sys = () => (mq.matches ? DARK : LIGHT);
window.devendraSetTheme = (t) => {
if (t === "system") {
localStorage.removeItem("devendra:theme");
document.documentElement.dataset.theme = sys();
} else {
localStorage.setItem("devendra:theme", t);
document.documentElement.dataset.theme = t;
}
// Drop focus so the (focus-driven) dropdown closes after a pick.
if (document.activeElement && document.activeElement.blur) document.activeElement.blur();
};
document.documentElement.dataset.theme = localStorage.getItem("devendra:theme") || sys();
mq.addEventListener("change", () => {
if (!localStorage.getItem("devendra:theme")) document.documentElement.dataset.theme = sys();
});
})();
</script>
<style>
@font-face { font-family: "B612 Mono"; font-style: normal; font-weight: 400;
font-display: swap; src: url("/assets/fonts/b612-mono-400.woff2") format("woff2"); }
@font-face { font-family: "B612 Mono"; font-style: normal; font-weight: 700;
font-display: swap; src: url("/assets/fonts/b612-mono-700.woff2") format("woff2"); }
@font-face { font-family: "Font Awesome 6 Free"; font-style: normal; font-weight: 900;
font-display: block; src: url("/assets/fonts/fa-solid-900.woff2") format("woff2"); }
/* FontAwesome solid — same icon component as ../dms. */
.fas, .fa-solid { font-family: "Font Awesome 6 Free"; font-weight: 900;
font-style: normal; display: inline-block; line-height: 1; }
.fa-fw { width: 1.25em; text-align: center; }
.fa-server:before { content: "\f233"; }
.fa-puzzle-piece:before { content: "\f12e"; }
.fa-ticket:before { content: "\f145"; }
.fa-upload:before { content: "\f093"; }
.fa-palette:before { content: "\f53f"; }
.fa-display:before { content: "\e163"; }
.fa-pen:before { content: "\f304"; }
.fa-trash:before { content: "\f1f8"; }
.fa-plus:before { content: "\2b"; }
.fa-arrow-left:before { content: "\f060"; }
.fa-circle-check:before { content: "\f058"; }
.fa-clock:before { content: "\f017"; }
.fa-microchip:before { content: "\f2db"; }
/* daisyUI-derived palettes: each theme sets four base colours; the rest is
derived with color-mix so surfaces/borders/muted follow automatically.
Defaults (:root) match the "her" theme. */
:root {
--base-100: #651d1d; --bc: #f0e6e6; --primary: #d5abab; --accent: #fef3c7;
--accent-fg: #1a1a1a;
--ok: #34d399; --warn: #fbbf24; --err: #f87171; --info: #60a5fa;
}
[data-theme="her"] { --base-100:#651d1d; --bc:#f0e6e6; --primary:#d5abab; --accent:#fef3c7; }
[data-theme="afterdark"] { --base-100:#201d65; --bc:#e7e6f4; --primary:#acabd5; --accent:#fef3c7; }
[data-theme="forest"] { --base-100:#052e16; --bc:#dcf5e6; --primary:#86efac; --accent:#fef3c7; }
[data-theme="sky"] { --base-100:#082f49; --bc:#dceafb; --primary:#7dd3fc; --accent:#fef3c7; }
[data-theme="clays"] { --base-100:#451a03; --bc:#f6e8dc; --primary:#f59e0b; --accent:#fef3c7; }
[data-theme="stones"] { --base-100:#292524; --bc:#e9e7e5; --primary:#9ca3af; --accent:#fef3c7; }
[data-theme="lofi"] { --base-100:#ffffff; --bc:#0d0d0d; --primary:#0d0d0d; --accent:#0d0d0d; --accent-fg:#f5f5f5; }
[data-theme="black"] { --base-100:#000000; --bc:#cfcfcf; --primary:#4b4b4b; --accent:#6b6b6b; --accent-fg:#f5f5f5; }
:root {
--bg: var(--base-100);
--fg: var(--bc);
--surface: color-mix(in srgb, var(--base-100) 90%, var(--bc));
--surface2: color-mix(in srgb, var(--base-100) 82%, var(--bc));
--border: color-mix(in srgb, var(--base-100) 74%, var(--bc));
--muted: color-mix(in srgb, var(--bc) 60%, var(--base-100));
--primary-fg: color-mix(in srgb, var(--primary) 92%, black);
}
* { box-sizing: border-box; }
html, body { min-height: 100%; }
body {
margin: 0; color: var(--fg); background: var(--bg);
font: 15px/1.55 "B612 Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}
/* daisyUI navbar component (same structure/classes as ../dms). */
.navbar { display: flex; align-items: center; gap: .25rem; min-height: 4rem;
padding: .5rem 1rem; border-bottom: 1px solid var(--border); background: var(--surface);
position: sticky; top: 0; z-index: 20; }
.navbar .flex-1 { flex: 1 1 auto; }
.navbar .flex-none { flex: 0 0 auto; }
/* Only the top-level nav list is a flex row — must NOT match the nested
.dropdown-content menu (that would force it visible + horizontal). */
.navbar > .flex-none > ul { list-style: none; display: flex; flex-direction: row;
align-items: center; gap: .25rem; margin: 0; padding: 0; }
.navbar > .flex-none > ul > li { list-style: none; }
.navbar a, .navbar form { text-decoration: none; }
.brand { font-weight: 700; letter-spacing: .16em; color: var(--accent);
text-transform: lowercase; }
/* Base button (daisyUI sizing: 3rem tall). Variants below must come after so
they win on source order. */
button, .btn { font: inherit; cursor: pointer; display: inline-flex; align-items: center;
justify-content: center; gap: .5rem; height: 3rem; min-height: 3rem; padding: 0 1rem;
border-radius: 8px; border: 1px solid var(--primary); background: var(--primary);
color: var(--primary-fg); font-weight: 700; font-size: .9rem; white-space: nowrap; }
button:hover, .btn:hover { filter: brightness(1.08); }
.btn.secondary { background: transparent; color: var(--primary); }
/* daisyUI button variants used by the nav. */
.btn-ghost { background: transparent; border-color: transparent; color: var(--fg); }
.btn-ghost:hover { background: color-mix(in srgb, var(--fg) 12%, transparent); filter: none; }
.btn-accent { background: var(--accent); border-color: var(--accent); color: var(--accent-fg); }
.btn-sm { height: 2rem; min-height: 2rem; padding: 0 .75rem; font-size: .8rem; font-weight: 400; gap: .4rem; }
.divider-horizontal { display: inline-block; width: 1px; height: 1.3rem;
background: var(--border); margin: 0 .3rem; }
@media (max-width: 640px) { .sm-inline { display: none; } }
main { max-width: 900px; margin: 1.6rem auto; padding: 0 1.2rem; }
h1 { font-size: 1.35rem; } h2 { font-size: 1.05rem; margin-top: 1.6rem; }
a { color: var(--primary); }
table { width: 100%; border-collapse: collapse; margin: 1rem 0; }
th, td { text-align: left; padding: .5rem .6rem; border-bottom: 1px solid var(--border); }
th { color: var(--muted); font-weight: 700; font-size: .8rem; text-transform: uppercase; letter-spacing: .04em; }
.card { background: var(--surface); border: 1px solid var(--border); border-radius: 10px;
padding: 1rem 1.2rem; margin: 1rem 0; }
.muted { color: var(--muted); }
.pill { display: inline-block; padding: .1rem .55rem; border-radius: 999px; font-size: .78rem; font-weight: 700; }
.pill.ok { background: color-mix(in srgb, var(--ok) 22%, transparent); color: var(--ok); }
.pill.changed { background: color-mix(in srgb, var(--primary) 26%, transparent); color: var(--primary); }
.pill.failed { background: color-mix(in srgb, var(--err) 24%, transparent); color: var(--err); }
.pill.none { background: color-mix(in srgb, var(--muted) 22%, transparent); color: var(--muted); }
/* Title badge (uptime / load next to the device title). */
.badge { display: inline-flex; align-items: center; gap: .4rem; vertical-align: middle;
margin-left: .6rem; padding: .2rem .6rem; border-radius: 999px; font-size: .72rem;
font-weight: 400; color: var(--muted); background: var(--surface2);
border: 1px solid var(--border); white-space: nowrap; }
.badge i { color: var(--primary); }
.badge-sep { opacity: .5; }
/* Live service-health traffic light (next to the State column). */
.dot { display: inline-block; width: .65rem; height: .65rem; border-radius: 999px;
vertical-align: middle; margin-left: .35rem; box-shadow: 0 0 0 1px color-mix(in srgb, var(--bc) 25%, transparent); }
.dot.ok { background: var(--ok); }
.dot.pending { background: var(--warn); }
.dot.bad { background: var(--err); }
.dot.unknown { background: var(--muted); }
input[type=text], select, textarea { font-family: inherit; width: 100%; padding: .5rem;
border: 1px solid var(--border); border-radius: 7px; background: var(--surface2); color: var(--fg); }
select { width: auto; }
textarea { min-height: 22rem; }
pre, code { font-family: inherit; }
pre.code, .code { background: var(--surface2); padding: 1rem; border-radius: 8px; overflow-x: auto; }
code { background: color-mix(in srgb, var(--base-100) 82%, var(--bc)); padding: .05rem .3rem; border-radius: 4px; }
pre.code code { background: none; padding: 0; }
.break { word-break: break-all; }
/* daisyUI dropdown behaviour (appearance comes from the utility classes on
the elements, exactly as ../dms writes them). Focus-driven: open while
the trigger or menu holds focus. */
.dropdown { position: relative; display: inline-block; }
.dropdown-content { position: absolute; display: none; }
.dropdown-end > .dropdown-content { right: 0; }
.dropdown:focus-within > .dropdown-content { display: block; }
.dropdown > [role="button"] { cursor: pointer; user-select: none; }
.menu { list-style: none; margin: 0; }
.menu li { list-style: none; }
.menu li > button, .menu li > a { display: flex; align-items: center; gap: .5rem; width: 100%;
background: transparent; color: var(--fg); border: 0; padding: .45rem .6rem; border-radius: .5rem;
font: inherit; font-size: .85rem; text-align: left; text-decoration: none; cursor: pointer; }
.menu li > button:hover, .menu li > a:hover { background: color-mix(in srgb, var(--fg) 10%, transparent); }
/* Minimal Tailwind/daisyUI utilities used by the copied ../dms markup. */
.hidden { display: none; }
@media (min-width: 640px) { .sm\:inline { display: inline; } }
.flex { display: flex; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-2 { gap: .5rem; }
.capitalize { text-transform: capitalize; }
.z-10 { z-index: 10; }
.mt-1 { margin-top: .25rem; }
.p-1 { padding: .25rem; }
.w-44 { width: 11rem; }
.rounded-box { border-radius: 1rem; }
.rounded-full { border-radius: 9999px; }
.size-3 { width: .75rem; height: .75rem; }
.border { border-width: 1px; border-style: solid; }
.bg-base-200 { background: var(--surface); }
.border-base-300 { border-color: var(--border); }
.border-base-content\/20 { border-color: color-mix(in srgb, var(--bc) 20%, transparent); }
.shadow-lg { box-shadow: 0 10px 15px -3px rgba(0,0,0,.3), 0 4px 6px -4px rgba(0,0,0,.25); }
</style>
</head>
<body>
<header class="navbar">
<div class="flex-1">
<a href="/"><span class="brand">devendra</span></a>
</div>
<div class="flex-none">
<ul>
<li><a href="/" class="btn btn-ghost btn-sm"><i class="fas fa-server fa-fw"></i><span class="sm-inline">Hosts</span></a></li>
<li><a href="/fragments" class="btn btn-ghost btn-sm"><i class="fas fa-puzzle-piece fa-fw"></i><span class="sm-inline">Fragments</span></a></li>
<li><a href="/ticket" class="btn btn-ghost btn-sm"><i class="fas fa-ticket fa-fw"></i><span class="sm-inline">Ticket</span></a></li>
<li><span class="divider-horizontal"></span></li>
<li>{% include "_theme_toggle.html" %}</li>
<li>
<form method="post" action="/publish" style="margin:0">
<button type="submit" class="btn btn-sm btn-accent"><i class="fas fa-upload fa-fw"></i><span class="sm-inline">Publish</span></button>
</form>
</li>
</ul>
</div>
</header>
<main>{% block content %}{% endblock %}</main>
</body>
</html>
neiam
/devendra
public · Issues · Pulls · Labels · Forks · Compare · Actions failure · Badges · Packages
⭐
Log in to mark this repository.
12.6 KiB · text
History
e832e77