source: Klonkt/src/views/partials/admin-styles.ejs@ 5280532

main
Last change on this file since 5280532 was 5280532, checked in by Robin <roboburr@…>, 3 weeks ago

Beheer: admin-audio neemt de maten van de gedeelde romp over

Robin zag dat /admin/audio nog de oude knop had en /admin/playlists de
goede. De markup was al gelijk -- beide gebruiken de terugknop-partial --
maar admin-audio had een EIGEN .ax-btn in zijn style-blok, en die staat
na de include en wint dus.

Het bleek geen los geval. admin-audio droeg een oudere, systematisch
kleinere kopie van het hele systeem:

.ax-btn 40px / radius 6 / 0.9rem -> 44px / radius 8 / 0.95rem
.ax-track hoes 56px / radius 10 -> 64px / radius 12
.ax-track-title 0.95rem -> 1.05rem
.ax-track-sub 0.8rem -> 0.85rem
@media 480px hoes 48px -> 56px

De partial kwam van admin-playlists, en dat is precies de versie die er
"goed" uitzag. Alle tien de afwijkingen zijn nu weg; audio en playlists
hebben nul regels die van de partial verschillen.

TWEE DINGEN DIE ECHT VERANDEREN, en niet alleen in maat:

  • Lange tracktitels op /admin/audio WRAPPEN nu in plaats van af te kappen met een ellipsis. De gedeelde .ax-track-title is een flex-regel (playlists zet er een pill in) en text-overflow werkt daar niet. De hele titel blijft zo zichtbaar; dat leek me de betere kant van de ruil, maar het is een keuze en geen bijvangst.
  • Het ♫-teken in de lege toestand verliest zijn display-font en eigen kleur, en erft nu van .ax-empty.

object-fit: cover staat nu OP .ax-track-cover en niet alleen op een img
erbinnen: admin-audio zet die klasse rechtstreeks op een <img>,
admin-listeners op een omhulsel. Op een niet-vervangen element doet
object-fit niets, dus de tweede vorm merkt er niets van. Zonder dit had
het weghalen van audio's kopie de hoezen uitgerekt.

scripts/admin-css.mjs heeft er --forceer bij: die haalt OOK de afwijkende
regels weg, zodat de pagina de vorm van de partial overneemt. Apart van
--doen, want --doen verplaatst alleen en dit VERANDERT hoe een pagina
eruitziet -- dat hoort een expliciete keuze te zijn. Met --toon laat hij
per eigenschap zien wat er verschilt; zo zijn bovenstaande maten
gevonden.

Co-Authored-By: Claude Opus 5 <noreply@…>

  • Property mode set to 100644
File size: 10.3 KB
Line 
1<%# De ax-*-primitieven voor de beheerpagina's, op EEN plek.
2
3 WAAROM DIT BESTAAT. Deze regels stonden vijf keer los in vijf pagina's, en
4 admin-playlists schreef er zelf boven waarom: "Define them here too so this
5 page is self-contained -- both pages get refreshed independently." Dat is
6 precies wat er daarna gebeurde. Gemeten op 16-8: .ax-header, .ax-header h1,
7 .ax-back en .ax-back:hover stonden in vijf bestanden byte voor byte gelijk,
8 .ax-flash-ok/-err in vier -- terwijl .ax-page in de ene 880px was en in
9 account 720px, en admin-media en admin-videos helemaal buiten het systeem
10 vielen met alles inline.
11
12 Gelijktrekken zonder dit is eenmalig: de volgende die een knop aanpast doet
13 dat in een van de acht kopieen en dan lopen ze weer uiteen. De vorm moet de
14 fout onmogelijk maken, niet alleen onwaarschijnlijk -- zelfde afweging als
15 bij de luisteraarstabel.
16
17 HOE JE HEM GEBRUIKT: neem hem met een include bovenaan de pagina op, en zet
18 daarna alleen nog in een eigen style-blok wat ECHT bij die ene pagina hoort.
19 Staat een regel in twee pagina's, dan hoort hij hier.
20
21 Een <style>-partial en geen los .css-bestand omdat shell.ejs geen
22 pageCss-haak heeft (wel pageJs) en een globale link deze regels op elke
23 pagina van de site zou laden. %>
24<style>
25/* ─── Paginaromp ───────────────────────────────────────────────── */
26.ax-page { max-width: 880px; margin: 1.5rem auto 4rem; padding: 0 1rem; }
27.ax-header { display: flex; align-items: flex-start; gap: 0.75rem; margin-bottom: 1.5rem; }
28.ax-header h1 { font-family: var(--font-display, serif); font-size: 1.75rem; margin: 0 0 0.25rem; }
29.ax-tagline { color: var(--ink-muted, var(--ink-soft)); margin: 0; font-size: 0.9rem; line-height: 1.5; }
30.ax-tagline code { background: var(--paper-2); padding: 0.1em 0.4em; border-radius: 4px; font-size: 0.9em; }
31.ax-back {
32 display: inline-flex; align-items: center; justify-content: center;
33 width: 40px; height: 40px;
34 border: 1px solid var(--rule); border-radius: 8px;
35 background: var(--paper); color: var(--ink); text-decoration: none;
36 font-size: 1.1rem; flex-shrink: 0; transition: border-color 120ms;
37}
38.ax-back:hover { border-color: var(--accent); }
39
40.ax-actions-bar { display: flex; margin-bottom: 1rem; }
41
42/* ─── Tabbalk ──────────────────────────────────────────────────── */
43/* Stond volledig inline in partials/media-tabs.ejs -- een gedeeld element dat
44 zijn eigen opmaak meedroeg, en daardoor niet mee kon met de rest. */
45.ax-tabs {
46 display: flex; gap: 0.4rem; flex-wrap: wrap;
47 margin: 0 0 1.25rem;
48 border-bottom: 1px solid var(--rule);
49}
50.ax-tab {
51 display: inline-flex; align-items: center;
52 padding: 0.55rem 0.9rem;
53 border: 1px solid var(--rule); border-bottom: none;
54 border-radius: 8px 8px 0 0;
55 background: var(--paper-2); color: var(--ink);
56 font-family: var(--font-ui, system-ui), sans-serif;
57 font-size: 0.9rem; text-decoration: none;
58 opacity: 0.8; transition: opacity 120ms, border-color 120ms;
59}
60.ax-tab:hover { opacity: 1; border-color: var(--accent); }
61.ax-tab[aria-current="page"] {
62 opacity: 1; font-weight: 600;
63 background: var(--paper);
64 border-bottom: 2px solid var(--accent);
65}
66
67/* ─── Meldingen ────────────────────────────────────────────────── */
68.ax-flash { padding: 0.75rem 1rem; border-radius: 8px; margin-bottom: 1rem; font-size: 0.9rem; }
69.ax-flash-ok { background: rgba(40,160,90,.15); color: #2a9d5e; border: 1px solid rgba(40,160,90,.3); }
70.ax-flash-err { background: rgba(200,60,60,.15); color: #c33; border: 1px solid rgba(200,60,60,.3); }
71
72/* ─── Kaart ────────────────────────────────────────────────────── */
73.ax-card {
74 background: var(--paper);
75 border: 1px solid var(--rule);
76 border-radius: 12px;
77 padding: 1.25rem;
78 margin-bottom: 1rem;
79}
80
81/* ─── Knoppen ──────────────────────────────────────────────────── */
82.ax-btn {
83 display: inline-flex; align-items: center; justify-content: center; gap: 0.4rem;
84 padding: 0.6rem 1.1rem;
85 border: 1px solid var(--rule); background: var(--paper-2);
86 color: var(--ink);
87 font-family: var(--font-ui, system-ui), sans-serif;
88 font-size: 0.95rem; font-weight: 500;
89 text-decoration: none; border-radius: 8px; cursor: pointer;
90 min-height: 44px;
91 transition: background 120ms, border-color 120ms;
92 -webkit-tap-highlight-color: transparent;
93}
94.ax-btn:hover { border-color: var(--accent); }
95.ax-btn-primary { background: var(--accent); color: white; border-color: var(--accent); }
96.ax-btn-primary:hover { opacity: 0.92; border-color: var(--accent); }
97/* admin-audio heeft paper-2, admin-playlists transparent. Hier audio's waarde:
98 .ax-btn is al paper-2, dus dit is daar een no-op en verandert niets aan wat
99 er nu staat. Wie de twee ooit echt wil laten verschillen, kies dan bewust. */
100.ax-btn-secondary { background: var(--paper-2); }
101.ax-btn-danger { border-color: #b4452e; color: #b4452e; background: transparent; }
102.ax-btn-danger:hover { background: rgba(180,69,46,.1); border-color: #b4452e; }
103.ax-btn-sm { min-height: 0; padding: 0.3rem 0.6rem; font-size: 0.78rem; }
104
105.ax-icon-btn {
106 display: inline-flex; align-items: center; justify-content: center;
107 width: 40px; height: 40px;
108 border: 1px solid var(--rule); border-radius: 8px;
109 background: var(--paper-2); color: var(--ink);
110 cursor: pointer; font-size: 1rem;
111 transition: background 120ms, border-color 120ms, color 120ms;
112}
113.ax-icon-btn:hover { border-color: var(--accent); }
114.ax-icon-btn-danger:hover { color: #dc2626; border-color: #dc2626; }
115
116/* ─── Lege toestand ────────────────────────────────────────────── */
117.ax-empty { text-align: center; padding: 2rem 1rem; color: var(--ink-muted, var(--ink-soft)); }
118.ax-empty-icon { font-size: 2.5rem; margin-bottom: 0.5rem; opacity: 0.5; }
119.ax-empty p { margin: 0; }
120.ax-empty-sub { font-size: 0.85rem; margin-top: 0.5rem !important; }
121
122/* ─── Lijstrij (audio, playlists, luisteraars) ─────────────────── */
123.ax-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 0.6rem; }
124.ax-track {
125 display: grid;
126 grid-template-columns: 64px 1fr auto;
127 gap: 0.85rem; align-items: center;
128 padding: 0.85rem;
129 background: var(--paper);
130 border: 1px solid var(--rule);
131 border-radius: 12px;
132 transition: border-color 120ms;
133}
134.ax-track:hover { border-color: var(--accent); }
135/* object-fit staat OOK op het element zelf, niet alleen op een img erbinnen:
136 admin-audio zet .ax-track-cover rechtstreeks op een <img>, admin-listeners
137 op een omhulsel met een img erin. Op een niet-vervangen element doet
138 object-fit niets, dus het kost de tweede vorm niets. */
139.ax-track-cover {
140 width: 64px; height: 64px; border-radius: 8px;
141 background: var(--paper-2);
142 display: flex; align-items: center; justify-content: center;
143 font-family: var(--font-display, serif);
144 font-size: 1.5rem; color: var(--accent);
145 flex-shrink: 0;
146 overflow: hidden;
147 object-fit: cover;
148}
149.ax-track-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
150.ax-track-meta { min-width: 0; display: flex; flex-direction: column; gap: 0.25rem; }
151.ax-track-title {
152 font-family: var(--font-display, serif);
153 font-weight: 600; font-size: 1.05rem; color: var(--ink);
154 display: flex; align-items: baseline; gap: 0.5rem; flex-wrap: wrap;
155}
156.ax-pill {
157 font-family: var(--font-ui);
158 font-size: 0.7rem; font-weight: 500;
159 color: var(--ink-soft);
160 background: var(--paper-2);
161 padding: 0.15em 0.55em; border-radius: 999px;
162 letter-spacing: 0;
163}
164.ax-track-sub {
165 font-size: 0.85rem;
166 color: var(--ink-muted, var(--ink-soft));
167 display: flex; flex-wrap: wrap; gap: 0.3rem; align-items: center;
168}
169.ax-track-sep { opacity: 0.5; }
170.ax-embed {
171 display: inline-block;
172 background: var(--paper-2);
173 padding: 0.15rem 0.5rem;
174 border-radius: 4px;
175 font-family: var(--font-mono, ui-monospace, monospace);
176 font-size: 0.75rem;
177 color: var(--ink-soft);
178 cursor: pointer; user-select: all;
179 margin-top: 0.15rem;
180 word-break: break-all;
181 align-self: flex-start;
182 transition: background 120ms;
183}
184.ax-embed:hover { background: var(--rule); }
185.ax-embed.is-copied { background: rgba(40,160,90,0.2); color: #2a9d5e; }
186.ax-track-actions { display: flex; gap: 0.4rem; flex-shrink: 0; }
187
188/* ─── Tegelraster (afbeeldingen, video's) ──────────────────────── */
189/* Dezelfde randen, hoeken en achtergrond als .ax-track, alleen in een raster
190 in plaats van een rij -- zodat een plaatjespagina en een lijstpagina van
191 hetzelfde ontwerp zijn en niet van twee. */
192.ax-grid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fill, minmax(var(--ax-tile, 150px), 1fr)); }
193.ax-tile {
194 border: 1px solid var(--rule); border-radius: 12px;
195 overflow: hidden; background: var(--paper);
196 transition: border-color 120ms;
197}
198.ax-tile:hover { border-color: var(--accent); }
199.ax-tile-media { position: relative; background: var(--paper-2); }
200.ax-tile-media img, .ax-tile-media video { width: 100%; height: 100%; display: block; }
201.ax-tile-body { padding: 0.55rem 0.65rem; font-size: 0.8rem; }
202.ax-tile-meta { color: var(--ink-muted, var(--ink-soft)); }
203.ax-tile-actions { display: flex; gap: 0.4rem; margin-top: 0.45rem; }
204.ax-tile-badge {
205 position: absolute; top: 6px; left: 6px; z-index: 1;
206 background: #b4452e; color: #fff;
207 border-radius: 6px; padding: 1px 6px; font-size: 0.68rem;
208}
209.ax-tile-badge-r { left: auto; right: 6px; background: rgba(0,0,0,.6); }
210
211@media (max-width: 480px) {
212 .ax-track {
213 grid-template-columns: 56px 1fr;
214 grid-template-areas: "cover meta" "actions actions";
215 gap: 0.6rem;
216 }
217 .ax-track-cover { grid-area: cover; width: 56px; height: 56px; }
218 .ax-track-meta { grid-area: meta; }
219 .ax-track-actions {
220 grid-area: actions;
221 justify-content: flex-end;
222 border-top: 1px solid var(--rule);
223 padding-top: 0.5rem;
224 margin-top: 0.25rem;
225 }
226}
227</style>
Note: See TracBrowser for help on using the repository browser.