mirror of
https://github.com/svemagie/indiekit-endpoint-blogroll.git
synced 2026-04-02 15:34:59 +02:00
refactor: align views with upstream @indiekit/frontend patterns
- Extract ~560 lines of inline CSS to external assets/styles.css - Create intermediate layout (layouts/blogroll.njk) for CSS loading - Use section(), badge(), button(), prose() macros instead of raw HTML - Remove custom page headers (document.njk heading() handles via title/parent) - Add parent breadcrumb navigation to all sub-pages - Add consumeFlashMessage() to dashboard and sources controllers - Rename CSS class prefix from br-* to blogroll-* for clarity - Use upstream CSS custom properties without fallback values - Fix Microsub orphan detection (soft-delete unsubscribed blogs) - Fix upsert to conditionally set microsub fields (avoid path conflicts) - Skip soft-deleted blogs during clear-and-resync Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
342
assets/styles.css
Normal file
342
assets/styles.css
Normal file
@@ -0,0 +1,342 @@
|
||||
/* Blogroll endpoint styles */
|
||||
|
||||
/* Stats grid */
|
||||
.blogroll-stats {
|
||||
display: grid;
|
||||
gap: var(--space-s);
|
||||
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
|
||||
}
|
||||
|
||||
.blogroll-stat {
|
||||
background: var(--color-background);
|
||||
border-radius: var(--radius-s);
|
||||
padding: var(--space-s);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.blogroll-stat dt {
|
||||
color: var(--color-text-secondary);
|
||||
font-size: var(--step--1);
|
||||
margin-block-end: var(--space-2xs);
|
||||
}
|
||||
|
||||
.blogroll-stat dd {
|
||||
font-size: var(--step-0);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.blogroll-stat dd.blogroll-stat--error {
|
||||
color: var(--color-error);
|
||||
}
|
||||
|
||||
/* Quick links (button row) */
|
||||
.blogroll-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--space-s);
|
||||
margin-block-start: var(--space-m);
|
||||
}
|
||||
|
||||
/* List (shared between blogs, sources, errors, dashboard lists) */
|
||||
.blogroll-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-s);
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.blogroll-list__item {
|
||||
align-items: flex-start;
|
||||
background: var(--color-offset);
|
||||
border-radius: var(--radius-m);
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--space-s);
|
||||
justify-content: space-between;
|
||||
padding: var(--space-m);
|
||||
}
|
||||
|
||||
.blogroll-list__item--compact {
|
||||
padding: var(--space-xs) var(--space-s);
|
||||
}
|
||||
|
||||
.blogroll-list__item--pinned {
|
||||
border-inline-start: 3px solid var(--color-accent);
|
||||
}
|
||||
|
||||
.blogroll-list__item--hidden {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
/* Item content (left side) */
|
||||
.blogroll-item__info {
|
||||
flex: 1;
|
||||
min-inline-size: 200px;
|
||||
}
|
||||
|
||||
.blogroll-item__title {
|
||||
font-size: var(--step-0);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
margin: 0 0 var(--space-2xs);
|
||||
}
|
||||
|
||||
.blogroll-item__title a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.blogroll-item__title a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.blogroll-item__meta {
|
||||
align-items: center;
|
||||
color: var(--color-text-secondary);
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
font-size: var(--step--1);
|
||||
gap: var(--space-xs);
|
||||
}
|
||||
|
||||
.blogroll-item__url {
|
||||
color: var(--color-accent);
|
||||
font-family: monospace;
|
||||
font-size: var(--step--2);
|
||||
margin-block-start: var(--space-2xs);
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.blogroll-item__error {
|
||||
color: var(--color-error);
|
||||
font-size: var(--step--1);
|
||||
margin-block-start: var(--space-2xs);
|
||||
}
|
||||
|
||||
/* Item actions (right side) */
|
||||
.blogroll-item__actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--space-xs);
|
||||
}
|
||||
|
||||
/* Filters */
|
||||
.blogroll-filters {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--space-s);
|
||||
}
|
||||
|
||||
.blogroll-filter-select {
|
||||
appearance: none;
|
||||
background-color: var(--color-background);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-s);
|
||||
font-size: var(--step--1);
|
||||
min-inline-size: 150px;
|
||||
padding: var(--space-2xs) var(--space-s);
|
||||
}
|
||||
|
||||
/* Form fields */
|
||||
.blogroll-form {
|
||||
max-inline-size: 600px;
|
||||
}
|
||||
|
||||
.blogroll-field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-2xs);
|
||||
margin-block-end: var(--space-m);
|
||||
}
|
||||
|
||||
.blogroll-field label {
|
||||
font-weight: var(--font-weight-semibold);
|
||||
}
|
||||
|
||||
.blogroll-field-hint {
|
||||
color: var(--color-text-secondary);
|
||||
font-size: var(--step--1);
|
||||
}
|
||||
|
||||
.blogroll-field input,
|
||||
.blogroll-field select,
|
||||
.blogroll-field textarea {
|
||||
appearance: none;
|
||||
background-color: var(--color-background);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-s);
|
||||
font-size: var(--step--1);
|
||||
padding: var(--space-2xs) var(--space-s);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.blogroll-field textarea {
|
||||
min-block-size: 100px;
|
||||
}
|
||||
|
||||
.blogroll-field input:focus,
|
||||
.blogroll-field select:focus,
|
||||
.blogroll-field textarea:focus {
|
||||
border-color: var(--color-accent);
|
||||
outline: 2px solid var(--color-accent);
|
||||
outline-offset: 1px;
|
||||
}
|
||||
|
||||
.blogroll-field--inline {
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
gap: var(--space-s);
|
||||
}
|
||||
|
||||
.blogroll-field--inline input[type="checkbox"] {
|
||||
appearance: auto;
|
||||
cursor: pointer;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
/* API list */
|
||||
.blogroll-api-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-xs);
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.blogroll-api-list li {
|
||||
background: var(--color-background);
|
||||
border-radius: var(--radius-s);
|
||||
font-size: var(--step--1);
|
||||
padding: var(--space-xs) var(--space-s);
|
||||
}
|
||||
|
||||
.blogroll-api-list code {
|
||||
color: var(--color-accent);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
}
|
||||
|
||||
/* Feed items (inside blog-edit) */
|
||||
.blogroll-items-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-xs);
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.blogroll-items-list li {
|
||||
background: var(--color-offset);
|
||||
border-radius: var(--radius-s);
|
||||
padding: var(--space-xs) var(--space-s);
|
||||
}
|
||||
|
||||
.blogroll-items-list .blogroll-item__title {
|
||||
font-size: var(--step--1);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.blogroll-items-list .blogroll-item__meta {
|
||||
font-size: var(--step--2);
|
||||
}
|
||||
|
||||
/* Feed discovery (blog-edit new) */
|
||||
.blogroll-discover {
|
||||
background: var(--color-offset);
|
||||
border-radius: var(--radius-m);
|
||||
margin-block-end: var(--space-m);
|
||||
padding: var(--space-m);
|
||||
}
|
||||
|
||||
.blogroll-discover .blogroll-field {
|
||||
margin-block-end: var(--space-s);
|
||||
}
|
||||
|
||||
.blogroll-discover__input {
|
||||
display: flex;
|
||||
gap: var(--space-s);
|
||||
}
|
||||
|
||||
.blogroll-discover__input input {
|
||||
appearance: none;
|
||||
background-color: var(--color-background);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-s);
|
||||
flex: 1;
|
||||
font-size: var(--step--1);
|
||||
padding: var(--space-2xs) var(--space-s);
|
||||
}
|
||||
|
||||
.blogroll-discover__result {
|
||||
background: var(--color-background);
|
||||
border-radius: var(--radius-s);
|
||||
font-size: var(--step--1);
|
||||
margin-block-start: var(--space-s);
|
||||
padding: var(--space-s);
|
||||
}
|
||||
|
||||
.blogroll-discover__result--error {
|
||||
color: var(--color-error);
|
||||
}
|
||||
|
||||
.blogroll-discover__result--success {
|
||||
color: var(--color-success);
|
||||
}
|
||||
|
||||
.blogroll-discover__feeds {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-xs);
|
||||
list-style: none;
|
||||
margin: var(--space-xs) 0 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.blogroll-discover__feed {
|
||||
align-items: center;
|
||||
background: var(--color-offset);
|
||||
border-radius: var(--radius-s);
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
gap: var(--space-s);
|
||||
padding: var(--space-xs);
|
||||
}
|
||||
|
||||
.blogroll-discover__feed:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.blogroll-discover__feed-url {
|
||||
flex: 1;
|
||||
font-family: monospace;
|
||||
font-size: var(--step--2);
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.blogroll-discover__feed-type {
|
||||
background: var(--color-accent);
|
||||
border-radius: var(--radius-s);
|
||||
color: var(--color-on-accent);
|
||||
font-size: var(--step--2);
|
||||
padding: var(--space-3xs) var(--space-2xs);
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
/* Empty state */
|
||||
.blogroll-empty {
|
||||
color: var(--color-text-secondary);
|
||||
font-size: var(--step--1);
|
||||
padding: var(--space-m);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Divider */
|
||||
.blogroll-divider {
|
||||
border: none;
|
||||
border-block-start: 1px solid var(--color-border);
|
||||
margin: var(--space-m) 0;
|
||||
}
|
||||
Reference in New Issue
Block a user