style: fix biome check errors (import order + formatting)

npx biome check reported 14 errors on app/public/assets/css/,
app/public/assets/js/app/ and scripts/:
  - assist/source/organizeImports: scripts/css-content-sources.mjs,
    scripts/css-unused-report.mjs
  - format: 9 CSS files + 3 JS files

Fixed via biome check --write. Verified: npx biome check clean,
npm run build succeeds, PHPUnit 316 tests / 628 assertions pass.
This commit is contained in:
Pontoporeia
2026-09-18 16:26:49 +02:00
parent 554ba3ee8d
commit bfde71caaa
14 changed files with 2772 additions and 2721 deletions
File diff suppressed because it is too large Load Diff
+45 -36
View File
@@ -7,75 +7,84 @@
/* Full-height flex layout: header → main → (optional footer) */
html,
body {
height: 100%;
overflow: hidden;
height: 100%;
overflow: hidden;
}
/* ── Discreet scrollbars (WebKit / Blink / Firefox) ──────────────── */
/* CSS custom properties defined in colors.css:
--scrollbar-thumb, --scrollbar-thumb-hover, --scrollbar-track, --scrollbar-corner */
::-webkit-scrollbar {
width: var(--scrollbar-width, 5px);
height: var(--scrollbar-width, 5px);
width: var(--scrollbar-width, 5px);
height: var(--scrollbar-width, 5px);
}
::-webkit-scrollbar-track {
background: var(--scrollbar-track);
}
::-webkit-scrollbar-thumb {
background: var(--scrollbar-thumb);
border-radius: 3px;
}
::-webkit-scrollbar-thumb:hover {
background: var(--scrollbar-thumb-hover);
}
::-webkit-scrollbar-corner {
background: var(--scrollbar-corner);
}
::-webkit-scrollbar-track { background: var(--scrollbar-track); }
::-webkit-scrollbar-thumb { background: var(--scrollbar-thumb); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: var(--scrollbar-thumb-hover); }
::-webkit-scrollbar-corner { background: var(--scrollbar-corner); }
html {
scrollbar-width: thin;
scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track);
scrollbar-gutter: stable;
scrollbar-width: thin;
scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track);
scrollbar-gutter: stable;
}
body {
font-family: var(--font-body);
font-weight: 300;
color: var(--text-primary);
background: linear-gradient(
180deg,
rgba(0, 0, 0, 0) 85%,
rgba(149, 87, 181, 0.8) 100%
);
display: flex;
flex-direction: column;
font-family: var(--font-body);
font-weight: 300;
color: var(--text-primary);
background: linear-gradient(
180deg,
rgba(0, 0, 0, 0) 85%,
rgba(149, 87, 181, 0.8) 100%
);
display: flex;
flex-direction: column;
}
main {
flex: 1;
min-height: 0;
overflow-wrap: anywhere;
flex: 1;
min-height: 0;
overflow-wrap: anywhere;
}
main * {
overflow-wrap: anywhere;
word-break: break-word;
overflow-wrap: anywhere;
word-break: break-word;
}
/* Global heading scale — used by admin + public pages */
h1 {
font-size: var(--step-4);
font-size: var(--step-4);
}
h2 {
font-size: var(--step-3);
font-size: var(--step-3);
}
h3 {
font-size: var(--step-2);
font-size: var(--step-2);
}
h4 {
font-size: var(--step-1);
font-size: var(--step-1);
}
h5 {
font-size: var(--step--1);
font-size: var(--step--1);
}
h6 {
font-size: var(--step--2);
font-size: var(--step--2);
}
:where(h1, h2, h3, h4, h5, h6) {
font-family: var(--font-display);
font-weight: 400;
margin: 0 0 var(--space-m) 0;
line-height: 1.15;
font-family: var(--font-display);
font-weight: 400;
margin: 0 0 var(--space-m) 0;
line-height: 1.15;
}
+1 -1
View File
@@ -205,7 +205,7 @@
/* Small arrow below the bubble pointing at the button */
.btn[data-tip]::before {
content: '';
content: "";
position: absolute;
left: 50%;
bottom: calc(100% + 4px);
+139 -126
View File
@@ -6,82 +6,82 @@
/* ── Header bar ─────────────────────────────────────────────────────── */
header {
vertical-align: center;
flex-shrink: 0;
background: linear-gradient(
0deg,
rgba(192, 93, 225, 1) 0%,
rgba(51, 191, 135, 1) 66%,
rgba(60, 133, 108, 1) 100%
);
vertical-align: center;
flex-shrink: 0;
background: linear-gradient(
0deg,
rgba(192, 93, 225, 1) 0%,
rgba(51, 191, 135, 1) 66%,
rgba(60, 133, 108, 1) 100%
);
}
/* ── Navigation ────────────────────────────────────────────────────── */
header nav {
padding: var(--space-s) var(--space-s);
display: flex;
align-items: center;
justify-content: space-between;
font-size: var(--step-0);
padding: var(--space-s) var(--space-s);
display: flex;
align-items: center;
justify-content: space-between;
font-size: var(--step-0);
}
header nav ul {
display: flex;
gap: var(--space-l);
align-items: center;
list-style: none;
margin: 0;
padding: 0;
display: flex;
gap: var(--space-l);
align-items: center;
list-style: none;
margin: 0;
padding: 0;
}
header nav ul a {
font-family: var(--font-display);
font-size: var(--step--1);
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--accent-foreground);
text-decoration: none;
padding: var(--space-3xs) var(--space-xs);
text-shadow:
0 0 16px var(--header-shadow-strong),
0 0 32px var(--header-shadow-soft);
transition: opacity 0.15s;
font-family: var(--font-display);
font-size: var(--step--1);
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--accent-foreground);
text-decoration: none;
padding: var(--space-3xs) var(--space-xs);
text-shadow:
0 0 16px var(--header-shadow-strong),
0 0 32px var(--header-shadow-soft);
transition: opacity 0.15s;
}
header nav ul a:hover {
color: var(--accent-primary);
color: var(--accent-primary);
}
header nav ul a[aria-current="page"] {
color: var(--accent-primary);
border-radius: 0;
border-bottom: 2px solid currentColor;
padding-bottom: 1px;
color: var(--accent-primary);
border-radius: 0;
border-bottom: 2px solid currentColor;
padding-bottom: 1px;
}
/* ── Logo ───────────────────────────────────────────────────────────── */
.nav-logo {
text-decoration: none;
text-decoration: none;
}
.nav-left-links,
.nav-right-links {
display: flex;
gap: var(--space-l);
align-items: center;
list-style: none;
margin: 0;
padding: 0;
display: flex;
gap: var(--space-l);
align-items: center;
list-style: none;
margin: 0;
padding: 0;
}
.nav-top-row {
display: contents;
display: contents;
}
.nav-mobile-links {
display: none;
display: none;
}
/* ── Hamburger menu (pure CSS, checkbox trick) ──────────────────────── */
@@ -95,119 +95,132 @@ header nav ul a[aria-current="page"] {
ul.nav-mobile-links ← full dropdown (hidden by default) */
.menu-btn {
position: absolute;
top: -9999px;
left: -9999px;
position: absolute;
top: -9999px;
left: -9999px;
}
.menu-icon {
display: none;
cursor: pointer;
padding: var(--space-2xs) var(--space-s);
align-items: center;
justify-content: center;
display: none;
cursor: pointer;
padding: var(--space-2xs) var(--space-s);
align-items: center;
justify-content: center;
}
/* Middle bar of the burger icon */
.navicon {
background: var(--accent-foreground);
display: block;
height: 2px;
width: 24px;
position: relative;
transition: all 0.3s ease-out;
background: var(--accent-foreground);
display: block;
height: 2px;
width: 24px;
position: relative;
transition: all 0.3s ease-out;
}
.navicon::before,
.navicon::after {
content: "";
background: var(--accent-foreground);
display: block;
height: 2px;
width: 100%;
position: absolute;
transition: all 0.3s ease-out;
content: "";
background: var(--accent-foreground);
display: block;
height: 2px;
width: 100%;
position: absolute;
transition: all 0.3s ease-out;
}
.navicon::before {
top: -7px;
top: -7px;
}
.navicon::after {
bottom: -7px;
bottom: -7px;
}
/* ── Mobile (≤ 640px) ───────────────────────────────────────────────── */
@media screen and (max-width: 640px) {
header nav[aria-label="Navigation principale"] {
display: flex;
flex-direction: column;
align-items: stretch;
padding: 0;
}
header nav[aria-label="Navigation principale"] {
display: flex;
flex-direction: column;
align-items: stretch;
padding: 0;
}
header nav[aria-label="Navigation principale"] .nav-top-row {
display: flex;
align-items: center;
justify-content: space-between;
padding: var(--space-s);
}
header nav[aria-label="Navigation principale"] .nav-top-row {
display: flex;
align-items: center;
justify-content: space-between;
padding: var(--space-s);
}
header nav[aria-label="Navigation principale"] .nav-right-links {
display: none;
}
header nav[aria-label="Navigation principale"] .nav-right-links {
display: none;
}
header nav[aria-label="Navigation principale"] .nav-left-links {
display: flex;
gap: 0;
}
header nav[aria-label="Navigation principale"] .nav-left-links {
display: flex;
gap: 0;
}
header nav[aria-label="Navigation principale"] .nav-left-links li:not(:first-child) {
display: none;
}
header
nav[aria-label="Navigation principale"]
.nav-left-links
li:not(:first-child) {
display: none;
}
.menu-icon {
display: flex;
}
.menu-icon {
display: flex;
}
header nav[aria-label="Navigation principale"] .nav-mobile-links {
display: block;
list-style: none;
margin: 0;
padding: 0;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
}
header nav[aria-label="Navigation principale"] .nav-mobile-links {
display: block;
list-style: none;
margin: 0;
padding: 0;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
}
.menu-btn:checked ~ nav[aria-label="Navigation principale"] .nav-mobile-links {
max-height: 300px;
}
.menu-btn:checked
~ nav[aria-label="Navigation principale"]
.nav-mobile-links {
max-height: 300px;
}
header nav[aria-label="Navigation principale"] .nav-mobile-links li {
border-top: 1px solid var(--header-nav-active-border);
text-align: left;
}
header nav[aria-label="Navigation principale"] .nav-mobile-links li {
border-top: 1px solid var(--header-nav-active-border);
text-align: left;
}
header nav[aria-label="Navigation principale"] .nav-mobile-links li a {
display: block;
width: 100%;
padding: var(--space-s) var(--space-s);
text-align: left;
}
header nav[aria-label="Navigation principale"] .nav-mobile-links li a {
display: block;
width: 100%;
padding: var(--space-s) var(--space-s);
text-align: left;
}
/* Animate burger → X */
.menu-btn:checked ~ nav[aria-label="Navigation principale"] .menu-icon .navicon {
background: transparent;
}
/* Animate burger → X */
.menu-btn:checked ~ nav[aria-label="Navigation principale"]
.menu-icon
.navicon {
background: transparent;
}
.menu-btn:checked ~ nav[aria-label="Navigation principale"] .menu-icon .navicon::before {
transform: rotate(-45deg);
top: 0;
}
.menu-btn:checked
~ nav[aria-label="Navigation principale"]
.menu-icon
.navicon::before {
transform: rotate(-45deg);
top: 0;
}
.menu-btn:checked ~ nav[aria-label="Navigation principale"] .menu-icon .navicon::after {
transform: rotate(45deg);
bottom: 0;
}
.menu-btn:checked
~ nav[aria-label="Navigation principale"]
.menu-icon
.navicon::after {
transform: rotate(45deg);
bottom: 0;
}
}
+12 -4
View File
@@ -39,11 +39,19 @@
}
/* Indent sub-headings in TOC */
.toc-list .toc-level-2 { padding-left: var(--space-s); }
.toc-list .toc-level-3 { padding-left: var(--space-m); }
.toc-list .toc-level-2 {
padding-left: var(--space-s);
}
.toc-list .toc-level-3 {
padding-left: var(--space-m);
}
.toc-list .toc-level-2 a { font-size: var(--step--1); }
.toc-list .toc-level-3 a { font-size: var(--step--2); }
.toc-list .toc-level-2 a {
font-size: var(--step--1);
}
.toc-list .toc-level-3 a {
font-size: var(--step--2);
}
/* ── Public TOC (details/summary block) ─────────────────────────────────── */
.toc {
+143 -137
View File
@@ -5,56 +5,56 @@
/* Override inherited padding on main-content */
#main-content {
padding-top: 0;
padding-top: 0;
}
.page-content {
flex: 1;
min-height: 0;
overflow-y: auto;
overflow-x: hidden;
scroll-behavior: smooth;
/* Bottom spacing lives on .page-content > article::after (below): Firefox
flex: 1;
min-height: 0;
overflow-y: auto;
overflow-x: hidden;
scroll-behavior: smooth;
/* Bottom spacing lives on .page-content > article::after (below): Firefox
drops/clips the scroll container's own padding-bottom in this nested flex
layout, while Chromium honours it — moving the pad into a block pseudo
element keeps both browsers consistent. */
padding: var(--space-xl) var(--space-l) 0;
display: grid;
grid-template-columns: 180px 1fr;
gap: var(--space-2xl);
align-items: start;
padding: var(--space-xl) var(--space-l) 0;
display: grid;
grid-template-columns: 180px 1fr;
gap: var(--space-2xl);
align-items: start;
}
/* ── TOC styles → components/toc.css (shared with admin) ───────────────── */
/* Grid column positioning for content pages with sidebar TOC */
@media (min-width: 768px) {
.page-content > article {
grid-column: 2;
min-width: 0;
max-width: 100%;
}
.page-content > article {
grid-column: 2;
min-width: 0;
max-width: 100%;
}
}
@media (max-width: 767px) {
.page-content {
grid-template-columns: 1fr;
gap: var(--space-l);
padding: var(--space-m) var(--space-s) 0;
}
.page-content {
grid-template-columns: 1fr;
gap: var(--space-l);
padding: var(--space-m) var(--space-s) 0;
}
.page-content > article {
grid-column: 1;
}
.page-content > article {
grid-column: 1;
}
.toc {
margin-top: var(--space-s);
}
.toc {
margin-top: var(--space-s);
}
}
/* ── First content child aligns with TOC heading top ───────────────────── */
.page-content > article > :first-child {
margin-top: 2.2rem;
margin-top: 2.2rem;
}
/* ------------------------------------------------------------------ */
@@ -62,127 +62,133 @@
/* ------------------------------------------------------------------ */
.page-content > article {
display: block;
max-width: 100%;
font-family: var(--font-body);
font-size: var(--step-0);
line-height: 1.6;
color: var(--text-primary);
font-weight: 300;
display: block;
max-width: 100%;
font-family: var(--font-body);
font-size: var(--step-0);
line-height: 1.6;
color: var(--text-primary);
font-weight: 300;
}
/* Trailing bottom spacing. Pseudo-element (real content in the scroll area)
rather than the container's padding-bottom, which Firefox clips. */
.page-content > article::after {
content: "";
display: block;
height: var(--space-2xl);
content: "";
display: block;
height: var(--space-2xl);
}
@media (max-width: 767px) {
.page-content > article::after {
height: var(--space-xl);
}
.page-content > article::after {
height: var(--space-xl);
}
}
.page-content > article * {
max-width: 100%;
overflow-wrap: anywhere;
word-break: break-word;
max-width: 100%;
overflow-wrap: anywhere;
word-break: break-word;
}
.page-content > article p {
margin: 0 0 1em 0;
margin: 0 0 1em 0;
}
.page-content > article p:last-child {
margin-bottom: 0;
margin-bottom: 0;
}
.page-content > article a {
color: inherit;
text-decoration: underline;
text-decoration-thickness: 0.08em;
text-underline-offset: 0.15em;
font-weight: 700;
color: inherit;
text-decoration: underline;
text-decoration-thickness: 0.08em;
text-underline-offset: 0.15em;
font-weight: 700;
}
.page-content > article a:hover {
color: var(--accent-primary);
text-decoration-thickness: 0.12em;
color: var(--accent-primary);
text-decoration-thickness: 0.12em;
}
.page-content > article ul,
.page-content > article ol {
padding-left: var(--space-m);
margin-bottom: var(--space-s);
padding-left: var(--space-m);
margin-bottom: var(--space-s);
}
.page-content > article li {
margin-bottom: 0.3em;
margin-bottom: 0.3em;
}
.page-content > article strong {
font-weight: 700;
font-weight: 700;
}
.page-content > article em {
font-style: italic;
font-style: italic;
}
.page-content > article :where(pre, pre code, code) {
display: block;
max-width: 100%;
overflow-x: auto;
overflow-wrap: normal;
word-break: normal;
font-family: "Courier New", Courier, monospace;
font-size: 0.88em;
background: color-mix(in srgb, var(--bg-tertiary) 50%, transparent);
padding: 0.5em 0.75em;
border-radius: var(--radius);
white-space: pre-wrap;
word-wrap: break-word;
display: block;
max-width: 100%;
overflow-x: auto;
overflow-wrap: normal;
word-break: normal;
font-family: "Courier New", Courier, monospace;
font-size: 0.88em;
background: color-mix(in srgb, var(--bg-tertiary) 50%, transparent);
padding: 0.5em 0.75em;
border-radius: var(--radius);
white-space: pre-wrap;
word-wrap: break-word;
}
#apropos-intro *,
#apropos-contacts *,
#apropos-credits * {
overflow-wrap: anywhere;
word-break: break-word;
max-width: 100%;
overflow-wrap: anywhere;
word-break: break-word;
max-width: 100%;
}
#apropos-contacts,
#apropos-intro {
border-bottom: none;
border-bottom: none;
}
/* Section separators (about page only) */
.page-content > article > section {
/* padding-bottom: var(--space-xl); */
border-bottom: 1px solid var(--border-primary);
margin-bottom: var(--space-xl);
/* padding-bottom: var(--space-xl); */
border-bottom: 1px solid var(--border-primary);
margin-bottom: var(--space-xl);
}
.page-content > article > section:last-child {
border-bottom: none;
margin-bottom: 0;
padding-bottom: var(--space-xl);
border-bottom: none;
margin-bottom: 0;
padding-bottom: var(--space-xl);
}
/* Scroll margin so anchor links account for the sticky header */
.page-content > article :where(h1, h2, h3) {
scroll-margin-top: var(--space-l);
scroll-margin-top: var(--space-l);
}
/* Content-page heading scale — smaller, distinct, no step-system dependency */
.page-content > article h1 { font-size: clamp(1.7rem, 1.55rem + 0.68vw, 2.1rem); }
.page-content > article h2 { font-size: clamp(1.35rem, 1.23rem + 0.55vw, 1.65rem); }
.page-content > article h3 { font-size: clamp(1.1rem, 1.03rem + 0.34vw, 1.3rem); }
.page-content > article h1 {
font-size: clamp(1.7rem, 1.55rem + 0.68vw, 2.1rem);
}
.page-content > article h2 {
font-size: clamp(1.35rem, 1.23rem + 0.55vw, 1.65rem);
}
.page-content > article h3 {
font-size: clamp(1.1rem, 1.03rem + 0.34vw, 1.3rem);
}
/* Hide CommonMark heading permalink anchors */
.heading-permalink {
display: none;
display: none;
}
/* ------------------------------------------------------------------ */
@@ -190,12 +196,12 @@
/* ------------------------------------------------------------------ */
.content-section-title {
font-family: var(--font-display);
font-size: clamp(1.35rem, 1.23rem + 0.55vw, 1.65rem);
font-weight: 400;
color: var(--text-primary);
margin: 0 0 var(--space-m) 0;
line-height: 1.1;
font-family: var(--font-display);
font-size: clamp(1.35rem, 1.23rem + 0.55vw, 1.65rem);
font-weight: 400;
color: var(--text-primary);
margin: 0 0 var(--space-m) 0;
line-height: 1.1;
}
/* ------------------------------------------------------------------ */
@@ -203,28 +209,28 @@
/* ------------------------------------------------------------------ */
.apropos-contacts-grid {
display: flex;
flex-direction: column;
gap: 0;
display: flex;
flex-direction: column;
gap: 0;
}
.apropos-contact-card {
font-style: normal;
padding: var(--space-s) 0;
font-style: normal;
padding: var(--space-s) 0;
}
.apropos-contact-card strong {
display: block;
font-weight: 600;
color: var(--text-primary);
margin-bottom: var(--space-3xs);
display: block;
font-weight: 600;
color: var(--text-primary);
margin-bottom: var(--space-3xs);
}
.apropos-contact-card span {
display: block;
color: var(--text-secondary);
line-height: 1.4;
margin-bottom: var(--space-3xs);
display: block;
color: var(--text-secondary);
line-height: 1.4;
margin-bottom: var(--space-3xs);
}
/* ------------------------------------------------------------------ */
@@ -232,33 +238,33 @@
/* ------------------------------------------------------------------ */
.apropos-credits-list {
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
gap: 0;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
gap: 0;
}
.apropos-credit-row {
display: grid;
grid-template-columns: 1fr 1.6fr;
gap: var(--space-s);
padding: var(--space-s) 0;
align-items: baseline;
display: grid;
grid-template-columns: 1fr 1.6fr;
gap: var(--space-s);
padding: var(--space-s) 0;
align-items: baseline;
}
.apropos-credits-list dt {
/* font-size: var(--step--1); */
font-weight: 300;
letter-spacing: 0.04em;
text-transform: uppercase;
/* font-size: var(--step--1); */
font-weight: 300;
letter-spacing: 0.04em;
text-transform: uppercase;
}
.apropos-credits-list dd {
/* font-size: var(--step-; */
color: var(--text-primary);
margin: 0;
line-height: 1.5;
/* font-size: var(--step-; */
color: var(--text-primary);
margin: 0;
line-height: 1.5;
}
/* ------------------------------------------------------------------ */
@@ -266,7 +272,7 @@
/* ------------------------------------------------------------------ */
.apropos-single {
max-width: 720px;
max-width: 720px;
}
/* ------------------------------------------------------------------ */
@@ -274,20 +280,20 @@
/* ------------------------------------------------------------------ */
@media (max-width: 600px) {
.page-content {
padding: var(--space-m) var(--space-s) 0;
}
.page-content {
padding: var(--space-m) var(--space-s) 0;
}
.page-content > article {
font-size: var(--step-0);
}
.page-content > article {
font-size: var(--step-0);
}
.content-section-title {
font-size: clamp(1.2rem, 1.1rem + 0.45vw, 1.45rem);
}
.content-section-title {
font-size: clamp(1.2rem, 1.1rem + 0.45vw, 1.45rem);
}
.apropos-credit-row {
grid-template-columns: 1fr;
gap: var(--space-3xs);
}
.apropos-credit-row {
grid-template-columns: 1fr;
gap: var(--space-3xs);
}
}
+184 -182
View File
@@ -5,293 +5,295 @@
/* Cards grid — scrollable main area */
.home-main {
flex: 1;
min-height: 0;
overflow-y: auto;
overflow-x: hidden;
padding: 0;
flex: 1;
min-height: 0;
overflow-y: auto;
overflow-x: hidden;
padding: 0;
}
.cards-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: var(--space-s);
list-style: none;
margin: 0;
padding: var(--space-xs) var(--space-s) var(--space-m);
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: var(--space-s);
list-style: none;
margin: 0;
padding: var(--space-xs) var(--space-s) var(--space-m);
}
@media (max-width: 768px) {
.cards-container {
grid-template-columns: repeat(2, 1fr);
}
.cards-container {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 480px) {
.cards-container {
grid-template-columns: 1fr;
}
.cards-container {
grid-template-columns: 1fr;
}
}
/* Each card = list item containing a block <a> link */
.card {
display: flex;
flex-direction: column;
cursor: pointer;
border-radius: var(--radius);
background: var(--bg-primary);
overflow: hidden;
transition:
border-color 0.2s ease,
box-shadow 0.2s ease;
display: flex;
flex-direction: column;
cursor: pointer;
border-radius: var(--radius);
background: var(--bg-primary);
overflow: hidden;
transition:
border-color 0.2s ease,
box-shadow 0.2s ease;
}
.card:hover {
box-shadow: 0 4px 16px var(--accent-secondary);
/* border-color: var(--accent-primary); */
box-shadow: 0 4px 16px var(--accent-secondary);
/* border-color: var(--accent-primary); */
}
.card > a {
text-decoration: none;
color: inherit;
display: flex;
flex-direction: column;
flex: 1;
border-radius: inherit;
text-decoration: none;
color: inherit;
display: flex;
flex-direction: column;
flex: 1;
border-radius: inherit;
}
/* Media wrapper: <figure> for real images/video, <div class="card__media--gradient"> for placeholders */
.home-body figure {
width: 100%;
aspect-ratio: 4 / 3;
overflow: hidden;
background: var(--bg-tertiary);
position: relative;
margin: 0; /* reset <figure> default margin */
/* border-radius: 7px 7px 0 0; */
border-radius: var(--radius);
width: 100%;
aspect-ratio: 4 / 3;
overflow: hidden;
background: var(--bg-tertiary);
position: relative;
margin: 0; /* reset <figure> default margin */
/* border-radius: 7px 7px 0 0; */
border-radius: var(--radius);
}
.home-body figure img,
.home-body figure video {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
transition: transform 0.3s ease, opacity 300ms ease-in;
width: 100%;
height: 100%;
object-fit: cover;
display: block;
transition:
transform 0.3s ease,
opacity 300ms ease-in;
}
/* Cover thumbnails are served as a <picture> (WebP + fallback); keep the
wrapper block-level so the <img> fills the 4:3 figure. */
.home-body figure picture {
display: block;
width: 100%;
height: 100%;
display: block;
width: 100%;
height: 100%;
}
.card:hover figure img,
.card:hover figure video {
transform: scale(1.02);
transform: scale(1.02);
}
.card__media--placeholder {
width: 100%;
height: 100%;
background: linear-gradient(135deg, var(--bg-tertiary), var(--bg-active));
display: flex;
align-items: center;
justify-content: center;
color: var(--text-tertiary);
font-size: var(--step-3);
width: 100%;
height: 100%;
background: linear-gradient(135deg, var(--bg-tertiary), var(--bg-active));
display: flex;
align-items: center;
justify-content: center;
color: var(--text-tertiary);
font-size: var(--step-3);
}
/* HTMX lazy-loaded cover: spinner + settle fade-in (mirrors htmx
docs' `htmx-settling img` transition pattern). */
.card__cover-loading {
animation: card-cover-pulse 1.1s ease-in-out infinite;
animation: card-cover-pulse 1.1s ease-in-out infinite;
}
@keyframes card-cover-pulse {
0%,
100% {
opacity: 0.3;
}
50% {
opacity: 1;
}
0%,
100% {
opacity: 0.3;
}
50% {
opacity: 1;
}
}
.home-body figure.htmx-settling img {
opacity: 0;
opacity: 0;
}
.card__media--gradient {
width: 100%;
aspect-ratio: 4 / 3;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: var(--space-s);
text-align: center;
box-sizing: border-box;
border-radius: 0 0 var(--radius) var(--radius);
background: linear-gradient(
0deg,
rgba(192, 93, 225, 1) 0%,
rgba(51, 191, 135, 1) 66%,
rgba(60, 133, 108, 1) 100%
);
width: 100%;
aspect-ratio: 4 / 3;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: var(--space-s);
text-align: center;
box-sizing: border-box;
border-radius: 0 0 var(--radius) var(--radius);
background: linear-gradient(
0deg,
rgba(192, 93, 225, 1) 0%,
rgba(51, 191, 135, 1) 66%,
rgba(60, 133, 108, 1) 100%
);
}
.card__gradient-author {
color: var(--accent-foreground);
font-size: var(--step--2);
opacity: 0.85;
margin-bottom: 0.25rem;
display: block;
color: var(--accent-foreground);
font-size: var(--step--2);
opacity: 0.85;
margin-bottom: 0.25rem;
display: block;
}
.card__gradient-title {
color: var(--accent-foreground);
font-size: var(--step--1);
font-weight: 600;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
color: var(--accent-foreground);
font-size: var(--step--1);
font-weight: 600;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
/* Section label */
.home-section-label {
font-style: normal;
background: transparent;
color: var(--text-primary);
font-size: var(--step--2);
font-weight: 600;
letter-spacing: 0.1em;
text-transform: uppercase;
padding: var(--space-s) var(--space-s) var(--space-xs);
border-bottom: 1px solid var(--border-primary);
margin: 0;
font-style: normal;
background: transparent;
color: var(--text-primary);
font-size: var(--step--2);
font-weight: 600;
letter-spacing: 0.1em;
text-transform: uppercase;
padding: var(--space-s) var(--space-s) var(--space-xs);
border-bottom: 1px solid var(--border-primary);
margin: 0;
}
/* Card caption — <p> directly inside the card <a> link, below the media */
.home-body li > a > p {
padding: var(--space-2xs) var(--space-xs) var(--space-xs);
font-size: var(--step--1);
line-height: 1.35;
color: var(--text-primary);
margin: 0;
font-weight: 400;
padding: var(--space-2xs) var(--space-xs) var(--space-xs);
font-size: var(--step--1);
line-height: 1.35;
color: var(--text-primary);
margin: 0;
font-weight: 400;
}
/* Empty-state message shown when no cards exist */
.cards-empty {
padding: var(--space-l);
color: var(--text-tertiary);
font-size: var(--step--1);
list-style: none;
padding: var(--space-l);
color: var(--text-tertiary);
font-size: var(--step--1);
list-style: none;
}
/* Filter info */
.filter-info {
background: var(--accent-muted);
color: var(--accent-secondary);
padding: var(--space-3xs) var(--space-s);
font-size: var(--step--1);
display: flex;
align-items: center;
gap: var(--space-s);
flex-shrink: 0;
background: var(--accent-muted);
color: var(--accent-secondary);
padding: var(--space-3xs) var(--space-s);
font-size: var(--step--1);
display: flex;
align-items: center;
gap: var(--space-s);
flex-shrink: 0;
}
.clear-filter {
color: var(--accent-secondary);
text-decoration: none;
padding: var(--space-3xs) var(--space-2xs);
background: var(--accent-muted);
border-radius: var(--radius);
font-size: var(--step--1);
color: var(--accent-secondary);
text-decoration: none;
padding: var(--space-3xs) var(--space-2xs);
background: var(--accent-muted);
border-radius: var(--radius);
font-size: var(--step--1);
}
.clear-filter:hover {
background: var(--accent-secondary);
color: var(--accent-foreground);
background: var(--accent-secondary);
color: var(--accent-foreground);
}
/* Pagination */
.pagination-wrap {
border-top: 1px solid var(--border-secondary);
background: var(--bg-primary);
flex-shrink: 0;
border-top: 1px solid var(--border-secondary);
background: var(--bg-primary);
flex-shrink: 0;
}
.pagination-wrap ul {
display: flex;
justify-content: center;
align-items: center;
gap: var(--space-2xs);
padding: var(--space-s);
list-style: none;
margin: 0;
display: flex;
justify-content: center;
align-items: center;
gap: var(--space-2xs);
padding: var(--space-s);
list-style: none;
margin: 0;
}
.pagination-btn {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 2.75rem;
min-height: 2.75rem;
padding: 0 var(--space-2xs);
border: 1px solid var(--border-secondary);
border-radius: var(--radius);
color: var(--text-primary);
font-size: var(--step--1);
text-decoration: none;
font-weight: 400;
transition: all 0.15s;
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 2.75rem;
min-height: 2.75rem;
padding: 0 var(--space-2xs);
border: 1px solid var(--border-secondary);
border-radius: var(--radius);
color: var(--text-primary);
font-size: var(--step--1);
text-decoration: none;
font-weight: 400;
transition: all 0.15s;
}
.pagination-btn:hover:not(.disabled) {
border-color: var(--accent-primary);
color: var(--accent-primary);
border-color: var(--accent-primary);
color: var(--accent-primary);
}
.pagination-btn.disabled {
opacity: 0.3;
cursor: not-allowed;
pointer-events: none;
opacity: 0.3;
cursor: not-allowed;
pointer-events: none;
}
.pagination-info {
font-size: var(--step--1);
color: var(--text-secondary);
padding: 0 var(--space-2xs);
font-size: var(--step--1);
color: var(--text-secondary);
padding: 0 var(--space-2xs);
}
.page-current {
font-weight: 600;
color: var(--text-primary);
font-weight: 600;
color: var(--text-primary);
}
/* Suppress card hover scale for users who prefer reduced motion */
@media (prefers-reduced-motion: reduce) {
.home-body figure img,
.home-body figure video {
transition: none;
}
.card:hover figure img,
.card:hover figure video {
transform: none;
}
.card__media--gradient {
transition: none;
}
.card {
transition: none;
}
.card:hover {
transform: none;
}
.home-body figure img,
.home-body figure video {
transition: none;
}
.card:hover figure img,
.card:hover figure video {
transform: none;
}
.card__media--gradient {
transition: none;
}
.card {
transition: none;
}
.card:hover {
transform: none;
}
}
File diff suppressed because it is too large Load Diff
+341 -335
View File
@@ -4,14 +4,14 @@
============================================================ */
.tfe-main {
display: flex;
flex: 1;
min-height: 0;
overflow: hidden;
/* Left padding keeps content aligned with the rest of the page;
display: flex;
flex: 1;
min-height: 0;
overflow: hidden;
/* Left padding keeps content aligned with the rest of the page;
no right padding so the right column (and its scrollbar) sits
flush against the viewport edge. */
padding-left: var(--space-m);
padding-left: var(--space-m);
}
/* Stacked article layout — fills main height */
@@ -33,28 +33,28 @@
/* Two-column layout: left 40vw (info), right fills remaining (files) */
.tfe-content-row {
display: grid;
grid-template-columns: 49vw 1fr;
width: 100%;
height: 100%;
min-height: 0;
display: grid;
grid-template-columns: 49vw 1fr;
width: 100%;
height: 100%;
min-height: 0;
}
.tfe-left-column {
display: grid;
overflow-y: auto;
min-width: 0;
padding: var(--space-xl) var(--space-m) var(--space-xl) var(--space-m);
padding-right: 0.5ch;
gap: 1ch;
display: grid;
overflow-y: auto;
min-width: 0;
padding: var(--space-xl) var(--space-m) var(--space-xl) var(--space-m);
padding-right: 0.5ch;
gap: 1ch;
}
.tfe-right-column {
display: flex;
flex-direction: column;
overflow-y: auto;
min-width: 0;
padding: var(--space-xl) var(--space-m) var(--space-xl) var(--space-m);
display: flex;
flex-direction: column;
overflow-y: auto;
min-width: 0;
padding: var(--space-xl) var(--space-m) var(--space-xl) var(--space-m);
}
/* Left column: stacks author, title, meta, synopsis — scrolls independently */
@@ -72,12 +72,12 @@
/* Files container inside right column: padded on the right so content
sits clear of the column's right-edge scrollbar */
.tfe-files {
display: grid;
gap: var(--space-m);
display: grid;
gap: var(--space-m);
}
.tfe-files:has(.pdf-expanded) {
height: 100%;
height: 100%;
display: flex;
flex-direction: column;
gap: var(--space-m);
@@ -87,309 +87,311 @@
}
.tfe-file-item {
width: 100%;
min-width: 0;
border-radius: var(--radius);
width: 100%;
min-width: 0;
border-radius: var(--radius);
}
.tfe-file-item:last-of-type {
padding-bottom: 4ch;
padding-bottom: 4ch;
}
.tfe-file-item:has(.pdf-embed-wrapper) {
overflow: visible;
overflow: visible;
}
.tfe-file-item:has(.pdf-expanded) {
min-height: 0;
overflow: visible;
min-height: 0;
overflow: visible;
}
.tfe-file-item:has(.tfe-website-wrapper) {
min-height: 0;
overflow: visible;
min-height: 0;
overflow: visible;
}
/* When a PDF is expanded, freeze the right column and hide
sibling file items so they can't render above the expanded view.
Also trim column padding so the PDF fills more vertical space. */
.tfe-right-column:has(.pdf-expanded) {
overflow: hidden;
padding-top: var(--space-xs);
padding-bottom: var(--space-xs);
overflow: hidden;
padding-top: var(--space-xs);
padding-bottom: var(--space-xs);
}
.tfe-right-column:has(.pdf-expanded) .tfe-file-item:not(:has(.pdf-expanded)) {
display: none;
display: none;
}
.tfe-file-item img {
width: 100%;
height: auto;
display: block;
border-radius: var(--radius);
user-select: none;
-webkit-user-drag: none;
width: 100%;
height: auto;
display: block;
border-radius: var(--radius);
user-select: none;
-webkit-user-drag: none;
}
.tfe-file-item embed,
.tfe-file-item video {
width: 100%;
max-width: 100%;
display: block;
border: none;
width: 100%;
max-width: 100%;
display: block;
border: none;
}
.tfe-file-item video {
max-height: 500px;
max-height: 500px;
}
.tfe-file-item embed,
.tfe-file-item iframe {
width: 100%;
max-width: 100%;
height: 100%;
min-height: 400px;
display: block;
border: none;
width: 100%;
max-width: 100%;
height: 100%;
min-height: 400px;
display: block;
border: none;
}
/* ── Website embed wrapper (like PDF overlay) ── */
.tfe-website-wrapper {
position: relative;
width: 100%;
display: grid;
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius);
overflow: hidden;
position: relative;
width: 100%;
display: grid;
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius);
overflow: hidden;
}
.tfe-website-badge {
position: absolute;
top: var(--space-xs);
left: var(--space-xs);
z-index: 2;
display: inline-block;
padding: 0.15em 0.6em;
font-size: var(--step--2);
font-weight: 500;
line-height: 1.4;
color: color-mix(in srgb, var(--accent-primary) 90%, #000);
background: color-mix(in srgb, var(--accent-primary) 12%, transparent);
border: 1px solid color-mix(in srgb, var(--accent-primary) 25%, transparent);
border-radius: var(--radius);
position: absolute;
top: var(--space-xs);
left: var(--space-xs);
z-index: 2;
display: inline-block;
padding: 0.15em 0.6em;
font-size: var(--step--2);
font-weight: 500;
line-height: 1.4;
color: color-mix(in srgb, var(--accent-primary) 90%, #000);
background: color-mix(in srgb, var(--accent-primary) 12%, transparent);
border: 1px solid color-mix(in srgb, var(--accent-primary) 25%, transparent);
border-radius: var(--radius);
}
.tfe-website-open-btn {
position: absolute;
bottom: var(--space-xs);
right: var(--space-xs);
z-index: 2;
display: grid;
place-items: center;
width: 40px;
height: 40px;
background: var(--accent-primary);
color: #fff;
border: none;
border-radius: var(--radius);
text-decoration: none;
cursor: pointer;
box-shadow: 0 2px 8px rgb(0 0 0 / 0.25);
transition: transform 0.15s, box-shadow 0.15s;
position: absolute;
bottom: var(--space-xs);
right: var(--space-xs);
z-index: 2;
display: grid;
place-items: center;
width: 40px;
height: 40px;
background: var(--accent-primary);
color: #fff;
border: none;
border-radius: var(--radius);
text-decoration: none;
cursor: pointer;
box-shadow: 0 2px 8px rgb(0 0 0 / 0.25);
transition:
transform 0.15s,
box-shadow 0.15s;
}
.tfe-website-open-btn:hover {
transform: translateY(-1px);
box-shadow: 0 4px 12px rgb(0 0 0 / 0.35);
background: var(--accent-primary);
color: #fff;
transform: translateY(-1px);
box-shadow: 0 4px 12px rgb(0 0 0 / 0.35);
background: var(--accent-primary);
color: #fff;
}
.tfe-file-item figcaption {
font-size: var(--step--2);
color: var(--text-secondary);
margin: var(--space-3xs) 0 0;
font-style: italic;
font-size: var(--step--2);
color: var(--text-secondary);
margin: var(--space-3xs) 0 0;
font-style: italic;
}
/* Contextual note above synopsis */
.tfe-context-note {
font-style: italic;
font-size: var(--step--1);
line-height: 1.6;
color: var(--text-secondary);
margin: 0;
padding: var(--space-xs) var(--space-s);
background: color-mix(in srgb, var(--accent-primary) 10%, var(--bg-primary));
border-radius: var(--radius);
font-style: italic;
font-size: var(--step--1);
line-height: 1.6;
color: var(--text-secondary);
margin: 0;
padding: var(--space-xs) var(--space-s);
background: color-mix(in srgb, var(--accent-primary) 10%, var(--bg-primary));
border-radius: var(--radius);
}
/* Author (p) — inline with title */
.tfe-author {
font-size: var(--step-1);
font-weight: 400;
color: var(--text-primary);
margin: 0;
line-height: 1.3;
word-break: normal;
overflow-wrap: break-word;
hyphens: auto;
font-size: var(--step-1);
font-weight: 400;
color: var(--text-primary);
margin: 0;
line-height: 1.3;
word-break: normal;
overflow-wrap: break-word;
hyphens: auto;
}
/* Title (h1) — inherits global scale from base.css */
.tfe-title {
margin: 0;
font-size: var(--step-2);
word-break: normal;
overflow-wrap: break-word;
hyphens: auto;
margin: 0;
font-size: var(--step-2);
word-break: normal;
overflow-wrap: break-word;
hyphens: auto;
}
/* Metadata block */
.tfe-meta {
display: grid;
gap: var(--space-3xs);
font-size: var(--step--1);
line-height: 1.4;
margin: 0;
display: grid;
gap: var(--space-3xs);
font-size: var(--step--1);
line-height: 1.4;
margin: 0;
}
/* Each metadata line */
.tfe-meta-item {
margin: 0;
font-weight: 700;
word-break: normal;
overflow-wrap: break-word;
hyphens: auto;
margin: 0;
font-weight: 700;
word-break: normal;
overflow-wrap: break-word;
hyphens: auto;
}
.tfe-meta-label {
font-weight: 300;
font-weight: 300;
}
.tfe-meta-item a {
color: inherit;
font-weight: 700;
text-decoration: none;
color: inherit;
font-weight: 700;
text-decoration: none;
}
.tfe-meta-item a:hover {
color: var(--accent-primary);
color: var(--accent-primary);
}
/* Note field: align label to top, value in italics */
.tfe-meta-item.tfe-meta-note {
align-items: start;
align-items: start;
}
.tfe-note-value {
font-style: italic;
font-style: italic;
}
/* Synopsis paragraph */
.tfe-synopsis-text {
font-size: var(--step--1);
line-height: 1.7;
color: var(--text-primary);
margin: 0;
font-size: var(--step--1);
line-height: 1.7;
color: var(--text-primary);
margin: 0;
}
/* Audio player */
.tfe-audio {
width: 100%;
margin: 0;
display: block;
width: 100%;
margin: 0;
display: block;
}
/* "Not available" and "no files" notices */
.tfe-restricted,
.tfe-no-files {
font-size: var(--step--1);
color: var(--text-secondary);
font-style: italic;
padding: var(--space-s) 0;
margin: 0;
font-size: var(--step--1);
color: var(--text-secondary);
font-style: italic;
padding: var(--space-s) 0;
margin: 0;
}
/* ============================================================
RESTRICTED ACCESS UI
============================================================ */
.tfe-restricted-access {
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: var(--space-m);
display: grid;
gap: var(--space-m);
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: var(--space-m);
display: grid;
gap: var(--space-m);
}
.tfe-restricted-message {
font-size: var(--step--1);
color: var(--text-secondary);
line-height: 1.6;
margin: 0;
font-size: var(--step--1);
color: var(--text-secondary);
line-height: 1.6;
margin: 0;
}
.tfe-restricted-message strong {
color: var(--text-primary);
display: block;
margin-bottom: var(--space-3xs);
font-size: var(--step-0);
color: var(--text-primary);
display: block;
margin-bottom: var(--space-3xs);
font-size: var(--step-0);
}
.tfe-access-request-form {
display: grid;
gap: var(--space-s);
display: grid;
gap: var(--space-s);
}
.tfe-access-request-form .form-group {
display: grid;
gap: var(--space-3xs);
display: grid;
gap: var(--space-3xs);
}
.tfe-access-request-form label {
font-size: var(--step--1);
font-weight: 400;
color: var(--text-primary);
font-size: var(--step--1);
font-weight: 400;
color: var(--text-primary);
}
.tfe-access-request-form input[type="email"],
.tfe-access-request-form textarea {
padding: var(--space-2xs) var(--space-3xs);
padding: var(--space-2xs) var(--space-3xs);
}
.tfe-btn-request-access {
margin-top: var(--space-3xs);
margin-top: var(--space-3xs);
}
.tfe-btn-request-access:disabled {
opacity: 0.6;
cursor: not-allowed;
opacity: 0.6;
cursor: not-allowed;
}
.tfe-access-message {
font-size: var(--step--1);
padding: var(--space-2xs);
border-radius: var(--radius);
margin-top: var(--space-3xs);
font-size: var(--step--1);
padding: var(--space-2xs);
border-radius: var(--radius);
margin-top: var(--space-3xs);
}
.tfe-access-success {
background: #f0fff4;
border: 1px solid #48bb78;
color: #22543d;
background: #f0fff4;
border: 1px solid #48bb78;
color: #22543d;
}
.tfe-access-error {
background: #fff5f5;
border: 1px solid #fc8181;
color: #742a2a;
background: #fff5f5;
border: 1px solid #fc8181;
color: #742a2a;
}
.tfe-access-request-form input.input-error {
border-color: #fc8181;
outline-color: #fc8181;
border-color: #fc8181;
outline-color: #fc8181;
}
/* ============================================================
@@ -398,231 +400,235 @@
/*── Base wrapper ───────────────────────────── */
.pdf-embed-wrapper {
position: relative;
width: 100%;
height: auto;
display: grid;
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius);
transition: height 0.35s ease, border-color 0.35s ease;
outline: none;
position: relative;
width: 100%;
height: auto;
display: grid;
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius);
transition:
height 0.35s ease,
border-color 0.35s ease;
outline: none;
}
/* ── Collapsed state: thumbnail tile ────────── */
.pdf-collapsed {
cursor: pointer;
overflow: hidden;
display: grid;
place-items: center;
min-height: 200px;
max-height: 350px;
cursor: pointer;
overflow: hidden;
display: grid;
place-items: center;
min-height: 200px;
max-height: 350px;
}
.pdf-thumbnail {
display: block;
max-width: 100%;
max-height: 100%;
object-fit: contain;
display: block;
max-width: 100%;
max-height: 100%;
object-fit: contain;
}
/* ── Overlay veil + enter button ────────────── */
.pdf-overlay {
position: absolute;
inset: 0;
z-index: 1;
display: grid;
place-items: center;
background: rgb(0 0 0 / 0.15);
backdrop-filter: blur(4px) saturate(0.6);
transition: background 0.2s;
position: absolute;
inset: 0;
z-index: 1;
display: grid;
place-items: center;
background: rgb(0 0 0 / 0.15);
backdrop-filter: blur(4px) saturate(0.6);
transition: background 0.2s;
}
.pdf-overlay:hover {
background: rgb(0 0 0 / 0.08);
background: rgb(0 0 0 / 0.08);
}
/* Document type pill — top-left of the overlay */
.pdf-overlay-badge {
position: absolute;
top: var(--space-xs);
left: var(--space-xs);
z-index: 2;
display: inline-block;
padding: 0.15em 0.6em;
font-size: var(--step--2);
font-weight: 500;
line-height: 1.4;
color: color-mix(in srgb, var(--accent-primary) 90%, #000);
background: color-mix(in srgb, var(--accent-primary) 12%, transparent);
border: 1px solid color-mix(in srgb, var(--accent-primary) 25%, transparent);
border-radius: var(--radius);
position: absolute;
top: var(--space-xs);
left: var(--space-xs);
z-index: 2;
display: inline-block;
padding: 0.15em 0.6em;
font-size: var(--step--2);
font-weight: 500;
line-height: 1.4;
color: color-mix(in srgb, var(--accent-primary) 90%, #000);
background: color-mix(in srgb, var(--accent-primary) 12%, transparent);
border: 1px solid color-mix(in srgb, var(--accent-primary) 25%, transparent);
border-radius: var(--radius);
}
.pdf-enter-btn {
display: inline-grid;
grid-auto-flow: column;
align-items: center;
gap: var(--space-2xs);
padding: var(--space-xs) var(--space-m);
background: var(--accent-primary);
color: #fff;
border: none;
border-radius: var(--radius);
font-size: var(--step-0);
font-weight: 500;
cursor: pointer;
box-shadow: 0 2px 8px rgb(0 0 0 / 0.2);
transition: transform 0.15s, box-shadow 0.15s;
display: inline-grid;
grid-auto-flow: column;
align-items: center;
gap: var(--space-2xs);
padding: var(--space-xs) var(--space-m);
background: var(--accent-primary);
color: #fff;
border: none;
border-radius: var(--radius);
font-size: var(--step-0);
font-weight: 500;
cursor: pointer;
box-shadow: 0 2px 8px rgb(0 0 0 / 0.2);
transition:
transform 0.15s,
box-shadow 0.15s;
}
.pdf-enter-btn:hover {
transform: translateY(-1px);
box-shadow: 0 4px 12px rgb(0 0 0 / 0.25);
transform: translateY(-1px);
box-shadow: 0 4px 12px rgb(0 0 0 / 0.25);
}
/* ── Expanded state: wrapper becomes scroll panel ── */
/* Disable root-level overscroll (rubberbanding) while a PDF is open. */
body.pdf-viewer-open {
overscroll-behavior: none;
overscroll-behavior: none;
}
.pdf-expanded {
height: 100%;
min-height: 400px;
overflow-y: auto;
overflow-x: hidden;
overscroll-behavior-y: contain;
border: 2px solid var(--accent-primary);
display: grid;
justify-items: center;
background: color-mix(in srgb, var(--accent-secondary) 22%, transparent);
height: 100%;
min-height: 400px;
overflow-y: auto;
overflow-x: hidden;
overscroll-behavior-y: contain;
border: 2px solid var(--accent-primary);
display: grid;
justify-items: center;
background: color-mix(in srgb, var(--accent-secondary) 22%, transparent);
}
/* ── Toolbar ────────────────────────────────── */
.pdf-toolbar {
position: sticky;
justify-self: stretch;
top: 0;
z-index: 2;
display: flex;
align-items: center;
gap: var(--space-3xs);
padding: var(--space-2xs) var(--space-xs);
background: var(--bg-primary);
border-bottom: 1px solid var(--border);
border-radius: var(--radius);
flex-shrink: 0;
font-size: var(--step--1);
user-select: none;
overscroll-behavior: none;
position: sticky;
justify-self: stretch;
top: 0;
z-index: 2;
display: flex;
align-items: center;
gap: var(--space-3xs);
padding: var(--space-2xs) var(--space-xs);
background: var(--bg-primary);
border-bottom: 1px solid var(--border);
border-radius: var(--radius);
flex-shrink: 0;
font-size: var(--step--1);
user-select: none;
overscroll-behavior: none;
}
.pdf-toolbar-btn {
display: inline-grid;
place-items: center;
width: 2em;
height: 2em;
padding: 0;
border: 1px solid var(--border);
border-radius: var(--radius);
background: var(--surface);
color: var(--text-primary);
cursor: pointer;
font-size: inherit;
line-height: 1;
transition: background 0.15s;
display: inline-grid;
place-items: center;
width: 2em;
height: 2em;
padding: 0;
border: 1px solid var(--border);
border-radius: var(--radius);
background: var(--surface);
color: var(--text-primary);
cursor: pointer;
font-size: inherit;
line-height: 1;
transition: background 0.15s;
}
.pdf-toolbar-btn:hover {
background: color-mix(in srgb, var(--accent-primary) 15%, var(--surface));
background: color-mix(in srgb, var(--accent-primary) 15%, var(--surface));
}
.pdf-toolbar-close {
margin-right: var(--space-xs);
margin-right: var(--space-xs);
}
.pdf-toolbar-label {
min-width: 4.5em;
text-align: center;
color: var(--text-secondary);
font-variant-numeric: tabular-nums;
min-width: 4.5em;
text-align: center;
color: var(--text-secondary);
font-variant-numeric: tabular-nums;
}
.pdf-toolbar-scale {
min-width: 3em;
min-width: 3em;
}
/* ── Canvas ─────────────────────────────────── */
.pdf-canvas {
display: block;
width: 100%;
height: auto;
box-shadow: 0 1px 4px rgb(0 0 0 / 0.12);
background: #fff;
flex-shrink: 0;
display: block;
width: 100%;
height: auto;
box-shadow: 0 1px 4px rgb(0 0 0 / 0.12);
background: #fff;
flex-shrink: 0;
}
.pdf-canvas:first-of-type {
margin-top: var(--space-xs);
margin-top: var(--space-xs);
}
.pdf-canvas:last-of-type {
margin-bottom: var(--space-xs);
margin-bottom: var(--space-xs);
}
.pdf-canvas + .pdf-canvas {
margin-top: var(--space-2xs);
margin-top: var(--space-2xs);
}
/* ── Responsive ─────────────────────────────── */
@media (max-width: 900px) {
.tfe-main {
overflow-y: auto;
}
.tfe-main {
overflow-y: auto;
}
.tfe-content-row {
grid-template-columns: 1fr;
height: auto;
}
.tfe-content-row {
grid-template-columns: 1fr;
height: auto;
}
.tfe-left-column,
.tfe-right-column {
overflow-y: visible;
padding: var(--space-3xs);
}
.tfe-left-column,
.tfe-right-column {
overflow-y: visible;
padding: var(--space-3xs);
}
.tfe-title {
font-size: var(--step-2);
}
.tfe-title {
font-size: var(--step-2);
}
/* PDF expands to full viewport on mobile */
.pdf-expanded {
position: fixed;
inset: 0;
z-index: 100;
height: auto;
min-height: unset;
background: color-mix(in srgb, var(--accent-secondary) 92%, #000 8%);
border: none;
border-radius: 0;
}
.pdf-toolbar {
border-radius: 0 0 var(--radius) var(--radius);
}
/* PDF expands to full viewport on mobile */
.pdf-expanded {
position: fixed;
inset: 0;
z-index: 100;
height: auto;
min-height: unset;
background: color-mix(in srgb, var(--accent-secondary) 92%, #000 8%);
border: none;
border-radius: 0;
}
.pdf-toolbar {
border-radius: 0 0 var(--radius) var(--radius);
}
.tfe-file-iframe {
height: 100dvh;
}
.tfe-file-iframe {
height: 100dvh;
}
}
@media (max-width: 600px) {
.tfe-main {
padding: var(--space-m) var(--space-s) var(--space-l);
}
.tfe-main {
padding: var(--space-m) var(--space-s) var(--space-l);
}
.tfe-title {
font-size: var(--step-1);
}
.tfe-title {
font-size: var(--step-1);
}
}
+1 -2
View File
@@ -46,8 +46,7 @@
// Update active tab class after each HTMX swap on #sys-log-view
document.body.addEventListener("htmx:afterSwap", (evt) => {
if (!(evt.detail.target && evt.detail.target.id === "sys-log-view"))
return;
if (!(evt.detail.target && evt.detail.target.id === "sys-log-view")) return;
var rc = evt.detail.requestConfig;
var tab = null;
// Tab clicks carry ?tab=… in the path
@@ -904,9 +904,12 @@
var inputId = inputIdMap[queueType] || null;
var input = inputId ? document.getElementById(inputId) : null;
console.log(
"[relink] looking for input | queueType=" + queueType +
" | inputId=" + inputId +
" | found=" + !!input,
"[relink] looking for input | queueType=" +
queueType +
" | inputId=" +
inputId +
" | found=" +
!!input,
);
var closeModal = () => {
var modal = document.getElementById("relink-modal");
@@ -917,17 +920,19 @@
console.log(`[relink] looking for pond | found=${!!pond}`);
if (pond) {
pond
.addFiles([{
source: String(data.id),
options: {
type: "local",
file: {
name: fileName,
size: fileSize,
type: mimeType,
.addFiles([
{
source: String(data.id),
options: {
type: "local",
file: {
name: fileName,
size: fileSize,
type: mimeType,
},
},
},
}])
])
.then(() => {
console.log(
"[relink] addFile resolved | source=" +
@@ -1028,17 +1033,19 @@
var pond = FilePond.find(input);
if (pond) {
pond
.addFiles([{
source: String(data.id),
options: {
type: "local",
file: {
name: name,
size: 0,
type: "video/mp4",
.addFiles([
{
source: String(data.id),
options: {
type: "local",
file: {
name: name,
size: 0,
type: "video/mp4",
},
},
},
}])
])
.then(() => {
console.log("[pt-relink] addFile resolved");
closeModal();
+3 -1
View File
@@ -360,7 +360,9 @@
});
const oldToolbar = container.querySelector(".pdf-toolbar");
if (oldToolbar) oldToolbar.remove();
renderAllPages(container, pdfDoc).then(() => buildToolbar(container, pdfDoc));
renderAllPages(container, pdfDoc).then(() =>
buildToolbar(container, pdfDoc),
);
}
// ── Bootstrap ──────────────────────────────────────────────────