Merge branch 'master' of https://git.uesome.de/tanztee/hyprcrd into feature/check-whether-works-as-pwa

This commit is contained in:
tu committed 2026-04-19 14:23:54 +02:00
commit 0bf7137428
10 files changed
+65 -29

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "hyprcrd", "name": "hyprcrd",
"version": "2.0.12", "version": "2.0.13",
"description": "hyprcrd — self-hosted card manager", "description": "hyprcrd — self-hosted card manager",
"main": "main.js", "main": "main.js",
"scripts": { "scripts": {
+20 -10
View File
@@ -109,17 +109,14 @@ select[class*="border-t-accent"] {
.prose img { border-radius: var(--ui-radius-image); } .prose img { border-radius: var(--ui-radius-image); }
.board-card.card-has-cover { border-radius: var(--ui-radius-card); } .board-card.card-has-cover { border-radius: var(--ui-radius-card); }
/* Modal containers (the inner box of each overlay) */ /* Modal containers (the inner box of each overlay). Only for floating /
#modal > div, * framed modals — the fullscreen overlays (modal, detail, search, tasks,
#detail > div, * calendar, gallery, and the support / plugin overlays) fill the whole
* viewport now and don't want the rounded-corner + overflow:hidden
* combo, which would clip the top color bar and soften the edge-to-edge
* look. */
#settings-overlay > div, #settings-overlay > div,
#search > div, #dialog > div {
#tasks > div,
#calendar > div,
#gallery > div,
#dialog > div,
#detail > div,
#modal > div {
border-radius: var(--ui-radius-modal); border-radius: var(--ui-radius-modal);
box-shadow: var(--ui-shadow-modal); box-shadow: var(--ui-shadow-modal);
overflow: hidden; overflow: hidden;
@@ -402,6 +399,19 @@ body.settings-peeking #settings-overlay > div { pointer-events: auto; }
.due-pill { display: inline-flex; align-items: center; gap: 3px; padding: 0 5px; border-radius: 8px; font-size: 9px; line-height: 16px; color: var(--t-bg); font-family: var(--t-font-pixel); } .due-pill { display: inline-flex; align-items: center; gap: 3px; padding: 0 5px; border-radius: 8px; font-size: 9px; line-height: 16px; color: var(--t-bg); font-family: var(--t-font-pixel); }
.card-done-badge { position: absolute; bottom: 0; right: 0; width: 0; height: 0; border-style: solid; border-width: 0 0 24px 24px; border-color: transparent transparent #4ade80 transparent; z-index: 1; } .card-done-badge { position: absolute; bottom: 0; right: 0; width: 0; height: 0; border-style: solid; border-width: 0 0 24px 24px; border-color: transparent transparent #4ade80 transparent; z-index: 1; }
.card-done-badge i { position: absolute; bottom: -22px; right: 1px; font-size: 10px; color: #000; } .card-done-badge i { position: absolute; bottom: -22px; right: 1px; font-size: 10px; color: #000; }
/* Rounded-cards variant: the corner triangle gets clipped by the
* rounded border, so toggle to a circle pill that sits comfortably
* inside any radius. JS adds `rounded-cards` on body whenever
* --ui-radius-card is > 0. */
body.rounded-cards .card-done-badge {
width: 18px; height: 18px;
bottom: 6px; right: 6px;
border: none;
border-radius: 50%;
background: #4ade80;
display: flex; align-items: center; justify-content: center;
}
body.rounded-cards .card-done-badge i { position: static; bottom: auto; right: auto; font-size: 11px; color: #000; font-weight: bold; }
.board-card:has(.card-bar-pulse) .card-bar-pulse ~ * .text-t-danger { animation: pulse-glow 2s ease-in-out infinite; } .board-card:has(.card-bar-pulse) .card-bar-pulse ~ * .text-t-danger { animation: pulse-glow 2s ease-in-out infinite; }
.card-spinner { animation: spin 0.8s linear infinite; display: inline-block; } .card-spinner { animation: spin 0.8s linear infinite; display: inline-block; }
+11 -6
View File
@@ -1565,6 +1565,11 @@ if (str_starts_with($route, '/api/')) {
if (d.animSpeed === 'off') document.body.classList.add('anim-off'); if (d.animSpeed === 'off') document.body.classList.add('anim-off');
if (d.animSpeed === 'fast') document.body.classList.add('anim-fast'); if (d.animSpeed === 'fast') document.body.classList.add('anim-fast');
if (d.animSpeed === 'slow') document.body.classList.add('anim-slow'); if (d.animSpeed === 'slow') document.body.classList.add('anim-slow');
// Rounded-card badge variant: the default "done" corner triangle
// gets clipped by a rounded border, so when the user opts into
// rounded cards we swap it for a circle pill in the BR corner
// (see .rounded-cards .card-done-badge in style.css).
document.body.classList.toggle('rounded-cards', (Number(d.radiusCard) || 0) > 0);
}; };
window.loadDesign = function() { window.loadDesign = function() {
let saved = {}; let saved = {};
@@ -2337,7 +2342,7 @@ if (str_starts_with($route, '/api/')) {
<!-- Search --> <!-- Search -->
<div class="overlay fixed inset-0 z-[70]" style="background:var(--t-overlay)" id="search"> <div class="overlay fixed inset-0 z-[70]" style="background:var(--t-overlay)" id="search">
<div class="bg-t-surface border border-t-border rounded-sm shadow-2xl flex flex-col absolute" style="inset:40px;"> <div class="bg-t-surface flex flex-col absolute" style="inset:0;">
<div class="flex flex-col border-b border-t-border"> <div class="flex flex-col border-b border-t-border">
<div class="flex items-center gap-3 px-4 py-3"> <div class="flex items-center gap-3 px-4 py-3">
<i class="ph ph-magnifying-glass text-t-accent text-base"></i> <i class="ph ph-magnifying-glass text-t-accent text-base"></i>
@@ -2390,7 +2395,7 @@ if (str_starts_with($route, '/api/')) {
<!-- Tasks --> <!-- Tasks -->
<div class="overlay fixed inset-0 z-[72]" style="background:var(--t-overlay)" id="tasks"> <div class="overlay fixed inset-0 z-[72]" style="background:var(--t-overlay)" id="tasks">
<div class="bg-t-surface border border-t-border rounded-sm shadow-2xl flex flex-col absolute" style="inset:54px;"> <div class="bg-t-surface flex flex-col absolute" style="inset:0;">
<div class="flex items-center gap-3 px-4 py-3 border-b border-t-border"> <div class="flex items-center gap-3 px-4 py-3 border-b border-t-border">
<i class="ph ph-check-square-offset text-t-accent2 text-base"></i> <i class="ph ph-check-square-offset text-t-accent2 text-base"></i>
<h2 class="font-pixel text-xs text-t-accent2">global_tasks</h2> <h2 class="font-pixel text-xs text-t-accent2">global_tasks</h2>
@@ -2415,7 +2420,7 @@ if (str_starts_with($route, '/api/')) {
<!-- Detail --> <!-- Detail -->
<div class="overlay fixed inset-0 z-[75]" style="background:var(--t-overlay)" id="detail"> <div class="overlay fixed inset-0 z-[75]" style="background:var(--t-overlay)" id="detail">
<div class="bg-t-surface border border-t-border flex absolute" style="inset:40px;"> <div class="bg-t-surface flex absolute" style="inset:0;">
<!-- Group sidebar (hidden for single cards) --> <!-- Group sidebar (hidden for single cards) -->
<div id="detail-sidebar" class="hidden w-56 shrink-0 border-r border-t-border flex flex-col"> <div id="detail-sidebar" class="hidden w-56 shrink-0 border-r border-t-border flex flex-col">
<div class="px-3 py-3 border-b border-t-border flex items-center gap-2"> <div class="px-3 py-3 border-b border-t-border flex items-center gap-2">
@@ -2483,7 +2488,7 @@ if (str_starts_with($route, '/api/')) {
<!-- Calendar --> <!-- Calendar -->
<div class="overlay fixed inset-0 z-[73]" style="background:var(--t-overlay)" id="calendar"> <div class="overlay fixed inset-0 z-[73]" style="background:var(--t-overlay)" id="calendar">
<div class="bg-t-surface border border-t-border flex flex-col absolute" style="inset:40px;"> <div class="bg-t-surface flex flex-col absolute" style="inset:0;">
<div class="flex items-center gap-2 px-5 py-3 border-b border-t-border shrink-0 relative"> <div class="flex items-center gap-2 px-5 py-3 border-b border-t-border shrink-0 relative">
<i class="ph ph-calendar-dots text-t-accent text-base"></i> <i class="ph ph-calendar-dots text-t-accent text-base"></i>
<button id="cal-today" class="font-pixel text-[10px] px-2 py-0.5 border border-t-border text-t-muted hover:border-t-accent hover:text-t-accent transition-colors">Today</button> <button id="cal-today" class="font-pixel text-[10px] px-2 py-0.5 border border-t-border text-t-muted hover:border-t-accent hover:text-t-accent transition-colors">Today</button>
@@ -2506,7 +2511,7 @@ if (str_starts_with($route, '/api/')) {
<!-- Assets (was Gallery) --> <!-- Assets (was Gallery) -->
<div class="overlay fixed inset-0 z-[72]" style="background:var(--t-overlay)" id="gallery"> <div class="overlay fixed inset-0 z-[72]" style="background:var(--t-overlay)" id="gallery">
<div class="bg-t-surface border border-t-border rounded-sm shadow-2xl flex flex-col absolute" style="inset:40px;"> <div class="bg-t-surface flex flex-col absolute" style="inset:0;">
<div class="flex items-center gap-3 px-4 py-3 border-b border-t-border shrink-0"> <div class="flex items-center gap-3 px-4 py-3 border-b border-t-border shrink-0">
<i class="ph ph-folder-open text-t-accent text-base"></i> <i class="ph ph-folder-open text-t-accent text-base"></i>
<h2 class="font-pixel text-xs text-t-accent">assets</h2> <h2 class="font-pixel text-xs text-t-accent">assets</h2>
@@ -2579,7 +2584,7 @@ if (str_starts_with($route, '/api/')) {
<!-- Editor --> <!-- Editor -->
<div class="overlay fixed inset-0 z-[60]" style="background:var(--t-overlay)" id="modal"> <div class="overlay fixed inset-0 z-[60]" style="background:var(--t-overlay)" id="modal">
<div class="bg-t-surface border border-t-border flex flex-col absolute" style="inset:40px;"> <div class="bg-t-surface flex flex-col absolute" style="inset:0;">
<div class="card-bar w-full shrink-0" id="editor-color"></div> <div class="card-bar w-full shrink-0" id="editor-color"></div>
<div class="flex items-center justify-between px-4 py-2.5 border-b border-t-border shrink-0"> <div class="flex items-center justify-between px-4 py-2.5 border-b border-t-border shrink-0">
<div class="flex items-center gap-3"><i class="ph ph-file-plus text-t-accent text-sm"></i><h2 id="modal-title" class="font-pixel text-xs text-t-accent">new_card</h2></div> <div class="flex items-center gap-3"><i class="ph ph-file-plus text-t-accent text-sm"></i><h2 id="modal-title" class="font-pixel text-xs text-t-accent">new_card</h2></div>
+1 -4
View File
@@ -53,11 +53,8 @@
/* Overlay shell */ /* Overlay shell */
.bookmarks-shell { .bookmarks-shell {
position: absolute; position: absolute;
inset: 40px; inset: 0;
background: var(--t-surface); background: var(--t-surface);
border: 1px solid var(--t-border);
border-radius: var(--ui-radius-modal, 4px);
box-shadow: 0 8px 40px rgba(0,0,0,0.5);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow: hidden; overflow: hidden;
+1 -1
View File
@@ -1,6 +1,6 @@
<!-- Email Plugin: full-screen mail viewer overlay --> <!-- Email Plugin: full-screen mail viewer overlay -->
<div class="overlay fixed inset-0" id="email-overlay" style="z-index:75;"> <div class="overlay fixed inset-0" id="email-overlay" style="z-index:75;">
<div class="email-modal bg-t-bg border border-t-border shadow-2xl flex flex-col" style="position:absolute;inset:24px;border-radius:4px;"> <div class="email-modal bg-t-bg flex flex-col" style="position:absolute;inset:0;">
<!-- Header --> <!-- Header -->
<div class="flex items-center gap-3 px-4 py-2 border-b border-t-border shrink-0 bg-t-surface"> <div class="flex items-center gap-3 px-4 py-2 border-b border-t-border shrink-0 bg-t-surface">
+1 -1
View File
@@ -1,6 +1,6 @@
<!-- Gitea Plugin: full-screen issue browser overlay --> <!-- Gitea Plugin: full-screen issue browser overlay -->
<div class="overlay fixed inset-0" id="gitea-overlay" style="z-index:75;"> <div class="overlay fixed inset-0" id="gitea-overlay" style="z-index:75;">
<div class="gitea-modal bg-t-bg border border-t-border shadow-2xl flex flex-col" style="position:absolute;inset:24px;border-radius:4px;"> <div class="gitea-modal bg-t-bg flex flex-col" style="position:absolute;inset:0;">
<!-- Header --> <!-- Header -->
<div class="flex items-center gap-3 px-4 py-2 border-b border-t-border shrink-0 bg-t-surface"> <div class="flex items-center gap-3 px-4 py-2 border-b border-t-border shrink-0 bg-t-surface">
@@ -1,5 +1,5 @@
<div class="overlay fixed inset-0 z-[75]" style="background:var(--t-overlay)" id="oumta-overlay"> <div class="overlay fixed inset-0 z-[75]" style="background:var(--t-overlay)" id="oumta-overlay">
<div class="bg-t-surface border border-t-border flex flex-col absolute" style="inset:40px;"> <div class="bg-t-surface flex flex-col absolute" style="inset:0;">
<!-- Header --> <!-- Header -->
<div class="flex items-center gap-3 px-5 py-3 border-b border-t-border shrink-0"> <div class="flex items-center gap-3 px-5 py-3 border-b border-t-border shrink-0">
+26 -2
View File
@@ -124,13 +124,37 @@
flex-direction: column; flex-direction: column;
gap: 18px; gap: 18px;
} }
.support-empty, .support-empty-hero { .support-empty {
color: var(--t-dim); color: var(--t-dim);
text-align: center; text-align: center;
padding: 40px 20px; padding: 40px 20px;
font-size: 13px; font-size: 13px;
} }
.support-empty-hero i { font-size: 48px; display: block; margin: 0 auto 12px; color: var(--t-muted); } /* Hero empty-state ("pick a ticket on the left") matches the board's
* "no cards found" placeholder: centred in the available column, pixel
* font with blink cursor, 4xl dim icon above. flex:1 consumes the
* detail column so the axis centring actually has a box to work in. */
.support-empty-hero {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
padding: 20px;
}
.support-empty-hero i {
display: block;
font-size: 2.25rem; /* matches text-4xl */
color: var(--t-dim);
margin-bottom: 1rem; /* matches mb-4 */
}
.support-empty-hero p {
margin: 0;
font-family: var(--t-font-ui, var(--t-font-pixel, 'Silkscreen', cursive));
font-size: 0.875rem; /* text-sm */
color: var(--t-dim);
}
.support-ticket-header h2 { font-family: var(--t-font-pixel); color: var(--t-bright); font-size: 14px; margin: 0 0 4px; } .support-ticket-header h2 { font-family: var(--t-font-pixel); color: var(--t-bright); font-size: 14px; margin: 0 0 4px; }
.support-ticket-header .meta { color: var(--t-dim); font-size: 11px; display: flex; gap: 12px; flex-wrap: wrap; } .support-ticket-header .meta { color: var(--t-dim); font-size: 11px; display: flex; gap: 12px; flex-wrap: wrap; }
+1 -1
View File
@@ -28,7 +28,7 @@
<section id="support-detail" class="support-detail"> <section id="support-detail" class="support-detail">
<div class="support-empty-hero"> <div class="support-empty-hero">
<i class="ph ph-envelope-open"></i> <i class="ph ph-envelope-open"></i>
<p>Pick a ticket on the left.</p> <p class="cursor-blink">select a ticket</p>
</div> </div>
</section> </section>
</div> </div>
+2 -2
View File
@@ -132,7 +132,7 @@ function renderDetail(t) {
const host = $('support-detail'); const host = $('support-detail');
if (!host) return; if (!host) return;
if (!t) { if (!t) {
host.innerHTML = `<div class="support-empty-hero"><i class="ph ph-envelope-open"></i><p>Pick a ticket on the left.</p></div>`; host.innerHTML = `<div class="support-empty-hero"><i class="ph ph-envelope-open"></i><p class="cursor-blink">select a ticket</p></div>`;
return; return;
} }
const replies = (t.replies || []).map(r => ` const replies = (t.replies || []).map(r => `
@@ -168,7 +168,7 @@ function renderDetail(t) {
<span id="support-composer-status" class="support-composer-status"></span> <span id="support-composer-status" class="support-composer-status"></span>
<button class="support-btn" id="support-save-fragment"><i class="ph ph-plus-circle"></i> Save as fragment</button> <button class="support-btn" id="support-save-fragment"><i class="ph ph-plus-circle"></i> Save as fragment</button>
<span class="spacer"></span> <span class="spacer"></span>
<button class="support-btn support-btn-ghost" id="support-status-closed" title="Close without replying">Close ticket</button> <button class="support-btn" id="support-status-closed" title="Close without replying"><i class="ph ph-archive"></i> Close ticket</button>
<button class="support-btn support-btn-primary" id="support-send-btn"><i class="ph ph-paper-plane-tilt"></i> Send reply</button> <button class="support-btn support-btn-primary" id="support-send-btn"><i class="ph ph-paper-plane-tilt"></i> Send reply</button>
</div> </div>
</div> </div>