Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ The Nginx configurations on the web server can be found at `/etc/nginx/nginx.con

## AI Workflow

### Theme Work
Blackprint is the built-in default implemented by `/style.css`, `/template.html`, and `/template_mobile.html`; Classic is the retained packaged theme under `/themes`. Before creating or reworking themes, read `/themes/AGENTS.md` and treat the current five-section cascade in `/style.css` as the canonical component, responsive, accessibility, and cross-theme contract.

### Updating the Wiki
Whenever you make a change, you should always check if the change is worth mentioning in the wiki by looking through the pages and checking whether or not the topic of your change is mentioned.

Expand Down
1 change: 0 additions & 1 deletion api/settings/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,6 @@ function is_truthy_setting($value) {
$colorFields = ['bg', 'fg', 'border', 'subtle', 'links'];
$themeColorFields = [
'classic' => $colorFields,
'ambercrt' => ['links'],
];

$errors = [];
Expand Down
16 changes: 5 additions & 11 deletions js/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ const COLOR_PREFS_KEY = 'colorPrefs';
const COLOR_FIELDS = ['bg', 'fg', 'border', 'subtle', 'links'];
const THEME_COLOR_FIELDS = {
classic: COLOR_FIELDS,
ambercrt: ['links'],
};
const COLOR_DEFAULTS = {
bg: '#000000',
Expand All @@ -22,9 +21,6 @@ const COLOR_DEFAULTS = {
};
const THEME_COLOR_DEFAULTS = {
classic: COLOR_DEFAULTS,
ambercrt: {
links: '#FFB84D',
},
};
const MOBILE_VIEW_COOKIE = 'mobile_friendly_view';
const MOBILE_VIEW_DOMAIN = '.fridge.dev';
Expand Down Expand Up @@ -455,10 +451,7 @@ function normalizeTheme(theme) {
const normalized = theme.trim().toLowerCase();
if (normalized === '' || normalized === 'default') return 'default';
if (normalized === 'blackprint') return 'default';
if (normalized === 'crt') return 'ambercrt';
if (normalized === 'liminal') return 'default';
if (normalized === 'custom') return 'classic';
if (normalized === 'newsprint') return 'whiteprint';
if (/^[a-z0-9_-]+$/.test(normalized)) return normalized;
return 'default';
}
Expand Down Expand Up @@ -1531,16 +1524,14 @@ function initSettingsPage() {
colorSection.style.display = fields.length ? '' : 'none';
const heading = colorSection.querySelector('h3');
if (heading) {
heading.textContent = normalizedTheme === 'ambercrt' ? 'CRT phosphor' : 'color scheme';
heading.textContent = 'color scheme';
}
const allowed = new Set(fields);
colorInputs.forEach(inp => {
const row = inp.closest('.color-row');
if (row) row.style.display = allowed.has(inp.dataset.colorKey) ? '' : 'none';
const label = row ? row.querySelector('span') : null;
if (label && normalizedTheme === 'ambercrt' && inp.dataset.colorKey === 'links') {
label.textContent = 'main';
} else if (label && inp.dataset.colorKey === 'links') {
if (label && inp.dataset.colorKey === 'links') {
label.textContent = 'links';
}
});
Expand Down Expand Up @@ -2059,6 +2050,9 @@ function initSettingsPage() {
saveLocalThemePref(currentTheme);
setThemeCookie(currentTheme);
applyThemeSelection(currentTheme);
if (currentTheme === 'classic') {
resetColorsToDefault();
}
});
}

Expand Down
24 changes: 12 additions & 12 deletions lib/render.php
Original file line number Diff line number Diff line change
Expand Up @@ -263,21 +263,9 @@
if ($theme === 'blackprint') {
return 'default';
}
if ($theme === 'crt') {
return 'ambercrt';
}
if ($theme === 'liminal') {
return 'default';
}
if ($theme === 'syswave') {
return 'default';
}
if ($theme === 'custom') {
return 'classic';
}
if ($theme === 'newsprint') {
return 'whiteprint';
}
if (preg_match('/^[a-z0-9_-]+$/', $theme)) {
return $theme;
}
Expand Down Expand Up @@ -343,6 +331,10 @@

$name = trim((string)($meta['name'] ?? ''));
$description = trim((string)($meta['description'] ?? ''));
$base = strtolower(trim((string)($meta['base'] ?? '')));
if ($base !== '' && $base !== 'blackprint') {
continue;
}
$html = fridg3_normalize_theme_asset_path($meta['html'] ?? '');
$css = fridg3_normalize_theme_asset_path($meta['css'] ?? '');
$thumbnail = fridg3_normalize_theme_asset_path($meta['thumbnail'] ?? '');
Expand Down Expand Up @@ -373,6 +365,7 @@
'id' => $id,
'name' => $name,
'description' => $description,
'base' => $base,
'thumbnail' => $thumbnail,
'html' => $html,
'css' => $css,
Expand All @@ -385,6 +378,8 @@
}

uasort($themes, function($a, $b) {
// Blackprint is prepended by the themes API; packaged themes follow
// it with Whiteprint and Classic pinned ahead of future themes.
$priority = ['whiteprint' => 0, 'classic' => 1];
$aPriority = $priority[$a['id']] ?? 10;
$bPriority = $priority[$b['id']] ?? 10;
Expand Down Expand Up @@ -624,11 +619,11 @@
$injection = $bannerHtml . $runtime;

if (stripos($template, 'id="content-layout"') !== false) {
return preg_replace('/(<div\b[^>]*\bid=("|\')content-layout\2[^>]*>)/i', '$1' . $injection, $template, 1) ?: $template;

Check warning on line 622 in lib/render.php

View workflow job for this annotation

GitHub Actions / Qodana for PHP

Single character alternation

Single character alternation in RegExp
}

if (stripos($template, 'id="content"') !== false) {
return preg_replace('/(<div\b[^>]*\bid=("|\')content\2[^>]*>)/i', '$1' . $injection, $template, 1) ?: $template;

Check warning on line 626 in lib/render.php

View workflow job for this annotation

GitHub Actions / Qodana for PHP

Single character alternation

Single character alternation in RegExp
}

if (stripos($template, '<body') !== false) {
Expand Down Expand Up @@ -736,6 +731,11 @@
);
}

$template = fridg3_apply_body_theme_class($template, $theme['id'] . '-theme');
if (($theme['base'] ?? '') === 'blackprint') {
$template = fridg3_apply_body_theme_class($template, 'blackprint-theme');
}

$href = htmlspecialchars($theme['cssHref'], ENT_QUOTES, 'UTF-8');
if (strpos($template, 'href="' . $href . '"') !== false || strpos($template, "href='" . $href . "'") !== false) {
return fridg3_replace_logged_in_discord_footer_button(
Expand Down
1 change: 0 additions & 1 deletion main.js
Original file line number Diff line number Diff line change
Expand Up @@ -3372,7 +3372,6 @@ function setupSpaForms() {
document.querySelectorAll('form').forEach(form => {
if (form.dataset.searchWaitBound === '1') return;
const isSearchForm = form.id === 'search'
|| form.id === 'littlehelps-search'
|| form.getAttribute('role') === 'search'
|| !!form.querySelector('input[type="search"], input[name="q"]');
if (!isSearchForm) return;
Expand Down
35 changes: 8 additions & 27 deletions style.css
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,8 @@ body {
display: flex;
flex-direction: column;
overflow-y: auto; /* allow sidebar content to scroll if taller than viewport */
user-select: none;
-webkit-user-select: none;
opacity: 1;
transform: translateX(0);
transition:
Expand All @@ -529,6 +531,11 @@ body {
box-shadow 0.16s ease;
}

#sidebar img,
#sidebar a {
-webkit-user-drag: none;
}

body.sidebar-is-hidden #sidebar {
width: 0 !important;
min-width: 0 !important;
Expand Down Expand Up @@ -6295,33 +6302,6 @@ html.access-high-contrast body {
color: var(--fg) !important;
}

html.access-high-contrast body.whiteprint-theme,
html.access-high-contrast body.bubblegum-theme,
html.access-high-contrast body.cottagecore-theme,
html.access-high-contrast body.littlehelps-theme {
--bg: #ffffff !important;
--fg: #000000 !important;
--border: #000000 !important;
--subtle: #333333 !important;
--links: #003cff !important;
color: var(--fg) !important;
}

html.access-high-contrast body.whiteprint-theme,
html.access-high-contrast body.bubblegum-theme,
html.access-high-contrast body.cottagecore-theme,
html.access-high-contrast body.littlehelps-theme,
html.access-high-contrast body.whiteprint-theme #sidebar,
html.access-high-contrast body.bubblegum-theme #sidebar,
html.access-high-contrast body.cottagecore-theme #sidebar,
html.access-high-contrast body.littlehelps-theme #sidebar,
html.access-high-contrast body.whiteprint-theme #content-layout,
html.access-high-contrast body.bubblegum-theme #content-layout,
html.access-high-contrast body.cottagecore-theme #content-layout,
html.access-high-contrast body.littlehelps-theme #content-layout {
background: #ffffff !important;
}

html.access-high-contrast a,
html.access-high-contrast button,
html.access-high-contrast input,
Expand Down Expand Up @@ -8208,6 +8188,7 @@ pre code.hljs {

.theme-picker-description,
.theme-picker-option-description {
font-family: "MainRegular", var(--emoji-font), monospace;
font-size: 12px;
line-height: 1.25;
color: var(--subtle);
Expand Down
2 changes: 1 addition & 1 deletion template.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin>
<link rel="preload" href="/resources/IBM_VGA.woff" as="font" type="font/woff" crossorigin>
<link rel="preload" href="/resources/IosevkaFixedSS03-Regular.woff2" as="font" type="font/woff2" crossorigin>
<link rel="stylesheet" href="/style.css?v=chat-link-images-20260813-81">
<link rel="stylesheet" href="/style.css?v=picker-subtitle-font-20260816-1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css">
<link rel="icon" type="image/png" href="/resources/favicon-96x96.png" sizes="96x96" />
Expand Down
2 changes: 1 addition & 1 deletion template_mobile.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin>
<link rel="preload" href="/resources/IBM_VGA.woff" as="font" type="font/woff" crossorigin>
<link rel="preload" href="/resources/IosevkaFixedSS03-Regular.woff2" as="font" type="font/woff2" crossorigin>
<link rel="stylesheet" href="/style.css?v=chat-link-images-20260813-81">
<link rel="stylesheet" href="/style.css?v=picker-subtitle-font-20260816-1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css">

Expand Down
Loading
Loading