From 7e97ab7fbfd0b798a22bac1a294641f31f26adea Mon Sep 17 00:00:00 2001 From: Ricardo Date: Sat, 21 Feb 2026 14:22:28 +0100 Subject: [PATCH] style: rewrite CSS to use Indiekit theme system MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace all nonexistent CSS variable references with Indiekit's actual custom properties. This enables automatic dark mode support (variables swap via prefers-color-scheme) and visual consistency with the rest of the admin UI. Key changes: - Map --color-text → --color-on-background, --color-text-muted → --color-on-offset, --border-radius → --border-radius-small, etc. - Add post-type differentiation via colored left borders: purple for notes, green for articles, yellow for boosts, primary for replies - Replace hardcoded hex colors (#e11d48, #16a34a) with Indiekit's palette variables (--color-red45, --color-green50, etc.) - Use Indiekit's border-width tokens for consistent border sizing - Add background/color to form inputs for dark mode compatibility --- assets/reader.css | 386 +++++++++++++++++++------------- package.json | 2 +- views/partials/ap-item-card.njk | 2 +- 3 files changed, 235 insertions(+), 155 deletions(-) diff --git a/assets/reader.css b/assets/reader.css index 4607c35..fe5e3be 100644 --- a/assets/reader.css +++ b/assets/reader.css @@ -1,7 +1,7 @@ /** * ActivityPub Reader Styles * Card-based layout inspired by Phanpy/Elk - * Uses Indiekit CSS custom properties + * Uses Indiekit CSS custom properties for automatic dark mode support */ /* ========================================================================== @@ -9,7 +9,7 @@ ========================================================================== */ .ap-tabs { - border-bottom: 1px solid var(--color-offset); + border-bottom: var(--border-width-thin) solid var(--color-outline); display: flex; gap: var(--space-xs); margin-bottom: var(--space-m); @@ -18,9 +18,9 @@ } .ap-tab { - border-bottom: 2px solid transparent; - color: var(--color-text-muted); - font-size: var(--font-size-body); + border-bottom: var(--border-width-thick) solid transparent; + color: var(--color-on-offset); + font-size: var(--font-size-m); padding: var(--space-s) var(--space-m); text-decoration: none; transition: @@ -30,7 +30,7 @@ } .ap-tab:hover { - color: var(--color-text); + color: var(--color-on-background); } .ap-tab--active { @@ -50,13 +50,14 @@ } /* ========================================================================== - Item Card + Item Card — Base ========================================================================== */ .ap-card { - background: var(--color-background); - border: 1px solid var(--color-offset); - border-radius: var(--border-radius); + background: var(--color-offset); + border: var(--border-width-thin) solid var(--color-outline); + border-left: var(--border-width-thickest) solid var(--color-outline); + border-radius: var(--border-radius-small); overflow: hidden; padding: var(--space-m); transition: @@ -65,32 +66,79 @@ } .ap-card:hover { - border-color: var(--color-offset-active); + border-color: var(--color-outline-variant); + border-left-color: var(--color-outline-variant); } -/* Boost header */ +/* ========================================================================== + Item Card — Post Type Differentiation + ========================================================================== */ + +/* Notes: default purple-ish accent (the most common type) */ +.ap-card--note { + border-left-color: var(--color-purple45); +} + +.ap-card--note:hover { + border-left-color: var(--color-purple45); +} + +/* Articles: green accent (long-form content stands out) */ +.ap-card--article { + border-left-color: var(--color-green50); +} + +.ap-card--article:hover { + border-left-color: var(--color-green50); +} + +/* Boosts: yellow accent (shared content) */ +.ap-card--boost { + border-left-color: var(--color-yellow50); +} + +.ap-card--boost:hover { + border-left-color: var(--color-yellow50); +} + +/* Replies: blue accent (via primary color) */ +.ap-card--reply { + border-left-color: var(--color-primary); +} + +.ap-card--reply:hover { + border-left-color: var(--color-primary); +} + +/* ========================================================================== + Boost Header + ========================================================================== */ + .ap-card__boost { - color: var(--color-text-muted); - font-size: var(--font-size-small); + color: var(--color-on-offset); + font-size: var(--font-size-s); margin-bottom: var(--space-s); padding-bottom: var(--space-xs); } .ap-card__boost a { - color: var(--color-text-muted); + color: var(--color-on-offset); font-weight: 600; text-decoration: none; } .ap-card__boost a:hover { - color: var(--color-text); + color: var(--color-on-background); text-decoration: underline; } -/* Reply context */ +/* ========================================================================== + Reply Context + ========================================================================== */ + .ap-card__reply-to { - color: var(--color-text-muted); - font-size: var(--font-size-small); + color: var(--color-on-offset); + font-size: var(--font-size-s); margin-bottom: var(--space-s); overflow: hidden; text-overflow: ellipsis; @@ -106,7 +154,10 @@ text-decoration: underline; } -/* Author header */ +/* ========================================================================== + Author Header + ========================================================================== */ + .ap-card__author { align-items: center; display: flex; @@ -115,7 +166,7 @@ } .ap-card__avatar { - border: 1px solid var(--color-offset); + border: var(--border-width-thin) solid var(--color-outline); border-radius: 50%; flex-shrink: 0; height: 40px; @@ -125,8 +176,8 @@ .ap-card__avatar--default { align-items: center; - background: var(--color-offset); - color: var(--color-text-muted); + background: var(--color-offset-variant); + color: var(--color-on-offset); display: inline-flex; font-size: 1.1em; font-weight: 600; @@ -157,24 +208,27 @@ } .ap-card__author-handle { - color: var(--color-text-muted); - font-size: var(--font-size-small); + color: var(--color-on-offset); + font-size: var(--font-size-s); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .ap-card__timestamp { - color: var(--color-text-muted); + color: var(--color-on-offset); flex-shrink: 0; - font-size: var(--font-size-small); + font-size: var(--font-size-xs); } -/* Post title (articles) */ +/* ========================================================================== + Post Title (Articles) + ========================================================================== */ + .ap-card__title { - font-size: var(--font-size-heading-4); + font-size: var(--font-size-l); font-weight: 600; - line-height: 1.3; + line-height: var(--line-height-tight); margin-bottom: var(--space-s); } @@ -187,10 +241,13 @@ text-decoration: underline; } -/* Content */ +/* ========================================================================== + Content + ========================================================================== */ + .ap-card__content { - color: var(--color-text); - line-height: 1.6; + color: var(--color-on-background); + line-height: var(--line-height-prose); margin-bottom: var(--space-s); overflow-wrap: break-word; word-break: break-word; @@ -209,20 +266,20 @@ } .ap-card__content blockquote { - border-left: 3px solid var(--color-offset); + border-left: var(--border-width-thickest) solid var(--color-outline); margin: var(--space-s) 0; padding-left: var(--space-m); } .ap-card__content pre { - background: var(--color-offset); - border-radius: var(--border-radius); + background: var(--color-offset-variant); + border-radius: var(--border-radius-small); overflow-x: auto; padding: var(--space-s); } .ap-card__content code { - background: var(--color-offset); + background: var(--color-offset-variant); border-radius: 3px; font-size: 0.9em; padding: 1px 4px; @@ -234,24 +291,27 @@ } .ap-card__content img { - border-radius: var(--border-radius); + border-radius: var(--border-radius-small); height: auto; max-width: 100%; } -/* Content warning */ +/* ========================================================================== + Content Warning + ========================================================================== */ + .ap-card__cw { margin-bottom: var(--space-s); } .ap-card__cw-toggle { - background: var(--color-offset); - border: 1px solid var(--color-offset-active); - border-radius: var(--border-radius); - color: var(--color-text); + background: var(--color-offset-variant); + border: var(--border-width-thin) solid var(--color-outline); + border-radius: var(--border-radius-small); + color: var(--color-on-background); cursor: pointer; display: block; - font-size: var(--font-size-small); + font-size: var(--font-size-s); padding: var(--space-s) var(--space-m); text-align: left; transition: background 0.2s ease; @@ -259,12 +319,15 @@ } .ap-card__cw-toggle:hover { - background: var(--color-offset-active); + background: var(--color-offset-variant-darker); } -/* Photo gallery */ +/* ========================================================================== + Photo Gallery + ========================================================================== */ + .ap-card__gallery { - border-radius: var(--border-radius); + border-radius: var(--border-radius-small); display: grid; gap: 2px; margin-bottom: var(--space-s); @@ -277,7 +340,7 @@ } .ap-card__gallery img { - background: var(--color-offset); + background: var(--color-offset-variant); display: block; height: 200px; object-fit: cover; @@ -285,7 +348,7 @@ } .ap-card__gallery-link--more::after { - background: rgba(0, 0, 0, 0.5); + background: hsl(var(--tint-neutral) 10% / 0.5); bottom: 0; content: ""; left: 0; @@ -295,7 +358,7 @@ } .ap-card__gallery-more { - color: #fff; + color: var(--color-neutral99); font-size: 1.5em; font-weight: 600; left: 50%; @@ -315,12 +378,12 @@ max-height: 400px; } -/* 2 photos - side by side */ +/* 2 photos — side by side */ .ap-card__gallery--2 { grid-template-columns: 1fr 1fr; } -/* 3 photos - one large, two small */ +/* 3 photos — one large, two small */ .ap-card__gallery--3 { grid-template-columns: 2fr 1fr; grid-template-rows: 1fr 1fr; @@ -331,24 +394,30 @@ height: 100%; } -/* 4+ photos - 2x2 grid */ +/* 4+ photos — 2x2 grid */ .ap-card__gallery--4 { grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; } -/* Video embed */ +/* ========================================================================== + Video Embed + ========================================================================== */ + .ap-card__video { margin-bottom: var(--space-s); } .ap-card__video video { - border-radius: var(--border-radius); + border-radius: var(--border-radius-small); max-height: 400px; width: 100%; } -/* Audio player */ +/* ========================================================================== + Audio Player + ========================================================================== */ + .ap-card__audio { margin-bottom: var(--space-s); } @@ -357,7 +426,10 @@ width: 100%; } -/* Tags */ +/* ========================================================================== + Tags + ========================================================================== */ + .ap-card__tags { display: flex; flex-wrap: wrap; @@ -366,22 +438,25 @@ } .ap-card__tag { - background: var(--color-offset); - border-radius: var(--border-radius); - color: var(--color-text-muted); - font-size: var(--font-size-small); + background: var(--color-offset-variant); + border-radius: var(--border-radius-large); + color: var(--color-on-offset); + font-size: var(--font-size-s); padding: 2px var(--space-xs); text-decoration: none; } .ap-card__tag:hover { - background: var(--color-offset-active); - color: var(--color-text); + background: var(--color-offset-variant-darker); + color: var(--color-on-background); } -/* Interaction buttons */ +/* ========================================================================== + Interaction Buttons + ========================================================================== */ + .ap-card__actions { - border-top: 1px solid var(--color-offset); + border-top: var(--border-width-thin) solid var(--color-outline); display: flex; flex-wrap: wrap; gap: var(--space-s); @@ -391,12 +466,12 @@ .ap-card__action { align-items: center; background: transparent; - border: 1px solid var(--color-offset); - border-radius: var(--border-radius); - color: var(--color-text-muted); + border: var(--border-width-thin) solid var(--color-outline); + border-radius: var(--border-radius-small); + color: var(--color-on-offset); cursor: pointer; display: inline-flex; - font-size: var(--font-size-small); + font-size: var(--font-size-s); gap: var(--space-xs); padding: var(--space-xs) var(--space-s); text-decoration: none; @@ -404,22 +479,22 @@ } .ap-card__action:hover { - background: var(--color-offset); - border-color: var(--color-offset-active); - color: var(--color-text); + background: var(--color-offset-variant); + border-color: var(--color-outline-variant); + color: var(--color-on-background); } -/* Active interaction states */ +/* Active interaction states — using Indiekit's color palette */ .ap-card__action--like.ap-card__action--active { - background: rgba(225, 29, 72, 0.1); - border-color: #e11d48; - color: #e11d48; + background: var(--color-red90); + border-color: var(--color-red45); + color: var(--color-red45); } .ap-card__action--boost.ap-card__action--active { - background: rgba(22, 163, 74, 0.1); - border-color: #16a34a; - color: #16a34a; + background: var(--color-green90); + border-color: var(--color-green50); + color: var(--color-green50); } .ap-card__action:disabled { @@ -429,8 +504,8 @@ /* Error message */ .ap-card__action-error { - color: #e11d48; - font-size: var(--font-size-small); + color: var(--color-error); + font-size: var(--font-size-s); width: 100%; } @@ -439,7 +514,7 @@ ========================================================================== */ .ap-pagination { - border-top: 1px solid var(--color-offset); + border-top: var(--border-width-thin) solid var(--color-outline); display: flex; gap: var(--space-m); justify-content: space-between; @@ -462,15 +537,15 @@ .ap-compose__context { background: var(--color-offset); - border-left: 3px solid var(--color-primary); - border-radius: var(--border-radius); + border-left: var(--border-width-thickest) solid var(--color-primary); + border-radius: var(--border-radius-small); margin-bottom: var(--space-m); padding: var(--space-m); } .ap-compose__context-label { - color: var(--color-text-muted); - font-size: var(--font-size-small); + color: var(--color-on-offset); + font-size: var(--font-size-s); margin-bottom: var(--space-xs); } @@ -481,15 +556,15 @@ .ap-compose__context-text { border: 0; - font-size: var(--font-size-small); - line-height: 1.5; + font-size: var(--font-size-s); + line-height: var(--line-height-loose); margin: var(--space-xs) 0; padding: 0; } .ap-compose__context-link { - color: var(--color-text-muted); - font-size: var(--font-size-small); + color: var(--color-on-offset); + font-size: var(--font-size-s); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; @@ -502,8 +577,8 @@ } .ap-compose__mode { - border: 1px solid var(--color-offset); - border-radius: var(--border-radius); + border: var(--border-width-thin) solid var(--color-outline); + border-radius: var(--border-radius-small); display: flex; flex-direction: column; gap: var(--space-s); @@ -522,9 +597,9 @@ } .ap-compose__mode-hint { - color: var(--color-text-muted); + color: var(--color-on-offset); display: block; - font-size: var(--font-size-small); + font-size: var(--font-size-s); margin-left: 1.5em; width: 100%; } @@ -534,11 +609,13 @@ } .ap-compose__textarea { - border: 1px solid var(--color-offset-active); - border-radius: var(--border-radius); + background: var(--color-background); + border: var(--border-width-thick) solid var(--color-outline); + border-radius: var(--border-radius-small); + color: var(--color-on-background); font-family: inherit; - font-size: var(--font-size-body); - line-height: 1.6; + font-size: var(--font-size-m); + line-height: var(--line-height-prose); padding: var(--space-s); resize: vertical; width: 100%; @@ -546,28 +623,28 @@ .ap-compose__textarea:focus { border-color: var(--color-primary); - outline: 2px solid var(--color-primary); + outline: var(--border-width-thick) solid var(--color-primary); outline-offset: -2px; } .ap-compose__counter { - font-size: var(--font-size-small); + font-size: var(--font-size-s); padding-top: var(--space-xs); text-align: right; } .ap-compose__counter--warn { - color: #d97706; + color: var(--color-yellow50); } .ap-compose__counter--over { - color: #e11d48; + color: var(--color-error); font-weight: 600; } .ap-compose__syndication { - border: 1px solid var(--color-offset); - border-radius: var(--border-radius); + border: var(--border-width-thin) solid var(--color-outline); + border-radius: var(--border-radius-small); display: flex; flex-direction: column; gap: var(--space-xs); @@ -593,10 +670,10 @@ .ap-compose__submit { background: var(--color-primary); border: 0; - border-radius: var(--border-radius); - color: #fff; + border-radius: var(--border-radius-small); + color: var(--color-on-primary, var(--color-neutral99)); cursor: pointer; - font-size: var(--font-size-body); + font-size: var(--font-size-m); font-weight: 600; padding: var(--space-s) var(--space-l); } @@ -606,12 +683,12 @@ } .ap-compose__cancel { - color: var(--color-text-muted); + color: var(--color-on-offset); text-decoration: none; } .ap-compose__cancel:hover { - color: var(--color-text); + color: var(--color-on-background); text-decoration: underline; } @@ -621,17 +698,17 @@ .ap-notification { align-items: flex-start; - background: var(--color-background); - border: 1px solid var(--color-offset); - border-radius: var(--border-radius); + background: var(--color-offset); + border: var(--border-width-thin) solid var(--color-outline); + border-radius: var(--border-radius-small); display: flex; gap: var(--space-s); padding: var(--space-m); } .ap-notification--unread { - border-color: rgba(255, 204, 0, 0.5); - box-shadow: 0 0 8px 0 rgba(255, 204, 0, 0.3); + border-color: var(--color-yellow50); + box-shadow: 0 0 8px 0 hsl(var(--tint-yellow) 50% / 0.3); } .ap-notification__icon { @@ -649,13 +726,13 @@ } .ap-notification__action { - color: var(--color-text-muted); + color: var(--color-on-offset); } .ap-notification__target { - color: var(--color-text-muted); + color: var(--color-on-offset); display: block; - font-size: var(--font-size-small); + font-size: var(--font-size-s); margin-top: var(--space-xs); overflow: hidden; text-overflow: ellipsis; @@ -663,17 +740,17 @@ } .ap-notification__excerpt { - background: var(--color-offset); - border-radius: var(--border-radius); - font-size: var(--font-size-small); + background: var(--color-offset-variant); + border-radius: var(--border-radius-small); + font-size: var(--font-size-s); margin-top: var(--space-xs); padding: var(--space-xs) var(--space-s); } .ap-notification__time { - color: var(--color-text-muted); + color: var(--color-on-offset); flex-shrink: 0; - font-size: var(--font-size-small); + font-size: var(--font-size-xs); } /* ========================================================================== @@ -681,7 +758,7 @@ ========================================================================== */ .ap-profile__header { - border-radius: var(--border-radius); + border-radius: var(--border-radius-small); height: 200px; margin-bottom: var(--space-m); overflow: hidden; @@ -702,7 +779,7 @@ } .ap-profile__avatar { - border: 3px solid var(--color-background); + border: var(--border-width-thickest) solid var(--color-background); border-radius: 50%; height: 80px; object-fit: cover; @@ -711,8 +788,8 @@ .ap-profile__avatar--placeholder { align-items: center; - background: var(--color-offset); - color: var(--color-text-muted); + background: var(--color-offset-variant); + color: var(--color-on-offset); display: flex; font-size: 2em; font-weight: 600; @@ -720,17 +797,17 @@ } .ap-profile__name { - font-size: var(--font-size-heading-3); + font-size: var(--font-size-xl); margin-bottom: var(--space-xs); } .ap-profile__handle { - color: var(--color-text-muted); + color: var(--color-on-offset); margin-bottom: var(--space-s); } .ap-profile__bio { - line-height: 1.6; + line-height: var(--line-height-prose); margin-bottom: var(--space-s); } @@ -747,11 +824,11 @@ .ap-profile__action { background: transparent; - border: 1px solid var(--color-offset-active); - border-radius: var(--border-radius); - color: var(--color-text); + border: var(--border-width-thin) solid var(--color-outline); + border-radius: var(--border-radius-small); + color: var(--color-on-background); cursor: pointer; - font-size: var(--font-size-small); + font-size: var(--font-size-s); padding: var(--space-xs) var(--space-m); text-decoration: none; } @@ -763,12 +840,12 @@ .ap-profile__action--follow.ap-profile__action--active { background: var(--color-primary); border-color: var(--color-primary); - color: #fff; + color: var(--color-on-primary, var(--color-neutral99)); } .ap-profile__action--danger:hover { - border-color: #e11d48; - color: #e11d48; + border-color: var(--color-error); + color: var(--color-error); } .ap-profile__posts { @@ -776,8 +853,8 @@ } .ap-profile__posts h3 { - border-bottom: 1px solid var(--color-offset); - font-size: var(--font-size-heading-4); + border-bottom: var(--border-width-thin) solid var(--color-outline); + font-size: var(--font-size-l); margin-bottom: var(--space-m); padding-bottom: var(--space-s); } @@ -791,7 +868,7 @@ } .ap-moderation__section h2 { - font-size: var(--font-size-heading-4); + font-size: var(--font-size-l); margin-bottom: var(--space-s); } @@ -803,7 +880,7 @@ .ap-moderation__entry { align-items: center; - border-bottom: 1px solid var(--color-offset); + border-bottom: var(--border-width-thin) solid var(--color-outline); display: flex; gap: var(--space-s); justify-content: space-between; @@ -819,18 +896,18 @@ .ap-moderation__remove { background: transparent; - border: 1px solid var(--color-offset-active); - border-radius: var(--border-radius); - color: var(--color-text-muted); + border: var(--border-width-thin) solid var(--color-outline); + border-radius: var(--border-radius-small); + color: var(--color-on-offset); cursor: pointer; flex-shrink: 0; - font-size: var(--font-size-small); + font-size: var(--font-size-s); padding: var(--space-xs) var(--space-s); } .ap-moderation__remove:hover { - border-color: #e11d48; - color: #e11d48; + border-color: var(--color-error); + color: var(--color-error); } .ap-moderation__add-form { @@ -839,24 +916,27 @@ } .ap-moderation__input { - border: 1px solid var(--color-offset-active); - border-radius: var(--border-radius); + background: var(--color-background); + border: var(--border-width-thick) solid var(--color-outline); + border-radius: var(--border-radius-small); + color: var(--color-on-background); flex: 1; - font-size: var(--font-size-body); + font-size: var(--font-size-m); padding: var(--space-xs) var(--space-s); } .ap-moderation__add-btn { background: var(--color-offset); - border: 1px solid var(--color-offset-active); - border-radius: var(--border-radius); + border: var(--border-width-thin) solid var(--color-outline); + border-radius: var(--border-radius-small); + color: var(--color-on-background); cursor: pointer; - font-size: var(--font-size-body); + font-size: var(--font-size-m); padding: var(--space-xs) var(--space-m); } .ap-moderation__add-btn:hover { - background: var(--color-offset-active); + background: var(--color-offset-variant); } /* ========================================================================== diff --git a/package.json b/package.json index fd9dcdd..32b58e9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@rmdes/indiekit-endpoint-activitypub", - "version": "1.1.4", + "version": "1.1.5", "description": "ActivityPub federation endpoint for Indiekit via Fedify. Adds full fediverse support: actor, inbox, outbox, followers, following, syndication, and Mastodon migration.", "keywords": [ "indiekit", diff --git a/views/partials/ap-item-card.njk b/views/partials/ap-item-card.njk index 4d250c1..44d3ebb 100644 --- a/views/partials/ap-item-card.njk +++ b/views/partials/ap-item-card.njk @@ -1,6 +1,6 @@ {# Timeline item card partial - reusable across timeline and profile views #} -
+
{# Boost header if this is a boosted post #} {% if item.type == "boost" and item.boostedBy %}