Add Charcoal Outline theme, README, and preview

This commit is contained in:
clay 2026-11-09 19:04:04 -05:00
parent dfec542240
commit 3c3473f914
3 changed files with 564 additions and 0 deletions

View file

@ -0,0 +1,83 @@
# Charcoal Outline
A clean, dark Fluxer theme with a solid charcoal background, transparent main panels, blue feature accents, and thin gray hover outlines.
![Charcoal Outline preview](screenshots/preview.png)
## Features
- Solid charcoal background (`#1e1e1e`).
- Transparent main panels with subtle gray borders.
- Thin gray hover outlines on targeted controls and selectable rows.
- Blue accents for primary actions and selected states.
- Distinct danger, warning, success, and presence colors.
- Opaque menus, tooltips, and popouts for readability.
- System fonts with no external assets or network dependencies.
- No custom JavaScript, gradients, glow, or animations.
## Installation
1. Download `Charcoal Outline.css` from this repository.
2. Open Fluxer's theme settings and add the stylesheet using the CSS import or editor option available in your client.
3. Enable Charcoal Outline.
This is a complete replacement stylesheet, not an append-only patch. If you used an earlier version, replace its CSS rather than appending this version.
The exact theme-management controls may vary by client version.
## Customization
The palette is defined in the `:root, body` block near the top of the stylesheet:
```css
--co-background: #1e1e1e;
--co-text: #e8ebf2;
--co-muted: #98a1b3;
--co-accent: #4fa3ff;
--co-danger: #ef6565;
--co-success: #7bdca2;
--co-warning: #f2ce75;
--co-line: rgba(128,128,128,.35);
--co-code: rgba(128,128,128,.2);
--co-hover: rgba(128,128,128,.08);
--co-selected: rgba(79,163,255,.14);
```
- `--co-line` controls panel borders and gray hover outlines.
- `--co-accent` controls mapped blue feature accents.
- `--co-hover` controls subtle hover fills.
- `--co-selected` controls mapped selection fills.
Some secondary shades and mention backgrounds use explicit color values. Changing `--co-accent` alone does not recolor every blue detail.
## Layout and accessibility
The theme avoids custom sidebar offsets, forced control sizes, clipping workarounds, and resize-handle changes. Native layout and scrolling behavior are left in place as far as practical.
Keyboard-focus indicators remain separate from mouse-hover outlines. Existing selected-server outlines and semantic feature colors are preserved. No custom motion effects are added.
## Changelog
### 1.0.1
- Consolidated gray hover styling into the complete stylesheet.
- Removed redundant outlines from already-bordered buttons.
- Preserved keyboard-focus and selected-server outlines.
- Applied consistent disabled-state exclusions to targeted hover rules.
- Retained existing feature colors and native layout geometry.
### 1.0.0
- Initial Fluxer adaptation of the charcoal dark stylesheet.
- Added token mappings and component-scoped styling.
- Kept the theme self-contained without external assets or scripts.
## License
```text
THE BEER-WARE LICENSE (Revision 42):
Michael Moon wrote this file. As long as you retain this notice you
can do whatever you want with this stuff. If we meet some day, and you
think this stuff is worth it, you can buy me a beer in return.
Michael Moon
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 KiB

View file

@ -0,0 +1,481 @@
/*
* @name Charcoal Outline
* @description Solid charcoal, transparent panels, blue feature accents and thin gray hover outlines. No external assets.
* @version 1.0.1
* Standalone replacement based on the supplied CSS and Fluxer reference.
* Consolidated hover rules; preserves the supplied feature colors and native layout.
* CSS syntax checked; not live-tested in Fluxer.
*/
:root, body {
--co-background: #1e1e1e;
--co-text: #e8ebf2;
--co-muted: #98a1b3;
--co-accent: #4fa3ff;
--co-danger: #ef6565;
--co-success: #7bdca2;
--co-warning: #f2ce75;
--co-line: rgba(128,128,128,.35);
--co-code: rgba(128,128,128,.2);
--co-hover: rgba(128,128,128,.08);
--co-selected: rgba(79,163,255,.14);
--co-font: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
--co-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
--background-primary: var(--co-background);
--background-secondary: var(--co-background);
--background-secondary-lighter: var(--co-background);
--background-secondary-alt: var(--co-background);
--background-tertiary: var(--co-background);
--guild-badge-surface: var(--co-background);
--composer-surface-color: var(--co-background);
--text-on-brand-primary: var(--co-background);
--text-on-brand-primary-light: var(--co-background);
--brand-primary-foreground: var(--co-background);
--settings-panel-background: var(--co-background);
--tooltip-surface: var(--co-background);
--background-channel-header: transparent;
--background-header-primary: transparent;
--background-header-secondary: transparent;
--background-textarea: transparent;
--guilds-layout-item-bg: transparent;
--form-surface-background: transparent;
--panel-control-bg: transparent;
--button-primary-fill: transparent;
--button-secondary-fill: transparent;
--button-danger-fill: transparent;
--control-button-normal-bg: transparent;
--message-preview-card-background: transparent;
--bg-table-row-odd: transparent;
--scrollbar-track-bg: transparent;
--background-header-primary-hover: var(--co-hover);
--panel-control-highlight: var(--co-hover);
--background-modifier-hover: var(--co-hover);
--background-modifier-accent: var(--co-hover);
--surface-interactive-hover-bg: var(--co-hover);
--button-secondary-active-fill: var(--co-hover);
--control-button-hover-bg: var(--co-hover);
--message-reply-bg: var(--co-hover);
--bg-blockquote: var(--co-hover);
--bg-table-row-even: var(--co-hover);
--background-modifier-selected: var(--co-selected);
--background-modifier-accent-focus: var(--co-selected);
--surface-interactive-selected-bg: var(--co-selected);
--brand-tint: var(--co-selected);
--button-primary-active-fill: var(--co-selected);
--control-button-active-bg: var(--co-selected);
--markup-mention-fill: var(--co-selected);
--panel-control-border: var(--co-line);
--panel-control-divider: var(--co-line);
--floating-surface-ring-color: var(--co-line);
--user-area-divider-color: var(--co-line);
--skeleton-chrome-border-color: var(--co-line);
--border-color: var(--co-line);
--button-outline-border: var(--co-line);
--message-preview-card-border: var(--co-line);
--message-preview-card-divider: var(--co-line);
--code-block-border: var(--co-line);
--scrollbar-thumb-bg: var(--co-line);
--composer-box-ring-color: var(--co-line);
--settings-border-color: var(--co-line);
--tooltip-border-color: var(--co-line);
--surface-interactive-selected-color: var(--co-accent);
--floating-surface-ring-color-strong: var(--co-accent);
--border-color-hover: var(--co-accent);
--border-color-focus: var(--co-accent);
--focus-primary: var(--co-accent);
--text-link: var(--co-accent);
--text-on-brand-tint: var(--co-accent);
--brand-primary: var(--co-accent);
--brand-primary-fill: var(--co-accent);
--brand-secondary: var(--co-accent);
--accent-primary: var(--co-accent);
--accent-info: var(--co-accent);
--button-primary-text: var(--co-accent);
--button-ghost-text: var(--co-accent);
--button-outline-text: var(--co-accent);
--control-button-active-text: var(--co-accent);
--message-mention-color: var(--co-accent);
--markup-mention-text: var(--co-accent);
--settings-hover-border-color: var(--co-accent);
--settings-selected-border-color: var(--co-accent);
--text-primary: var(--co-text);
--text-chat: var(--co-text);
--text-on-dark: var(--co-text);
--interactive-active: var(--co-text);
--button-secondary-text: var(--co-text);
--button-secondary-active-text: var(--co-text);
--control-button-hover-text: var(--co-text);
--markup-interactive-hover-text: var(--co-text);
--code-text: var(--co-text);
--guild-list-foreground: var(--co-muted);
--text-secondary: var(--co-muted);
--text-primary-muted: var(--co-muted);
--text-chat-muted: var(--co-muted);
--text-tertiary: var(--co-muted);
--text-tertiary-muted: var(--co-muted);
--text-tertiary-secondary: var(--co-muted);
--interactive-muted: var(--co-muted);
--message-timestamp-color: var(--co-muted);
--status-offline: var(--co-muted);
--control-button-normal-text: var(--co-muted);
--message-reply-color: var(--co-muted);
--scrollbar-thumb-bg-hover: var(--co-muted);
--text-selection: rgba(79,163,255,.28);
--brand-primary-light: #78b8ff;
--brand-primary-light-fill: #78b8ff;
--brand-primary-pressed: #378bdd;
--brand-primary-shade: #378bdd;
--brand-tint-hover: rgba(79,163,255,.22);
--markup-interactive-hover-fill: rgba(79,163,255,.22);
--brand-tint-border: rgba(79,163,255,.45);
--accent-success: var(--co-success);
--status-online: var(--co-success);
--accent-warning: var(--co-warning);
--status-idle: var(--co-warning);
--status-warning: var(--co-warning);
--markup-everyone-text: var(--co-warning);
--markup-here-text: var(--co-warning);
--accent-danger: var(--co-danger);
--status-dnd: var(--co-danger);
--status-danger: var(--co-danger);
--button-danger-text: var(--co-danger);
--accent-purple: #ba9cff;
--button-danger-active-fill: rgba(239,101,101,.14);
--message-mention-bg: rgba(79,163,255,.10);
--message-mention-bg-hover: rgba(79,163,255,.16);
--markup-mention-border: rgba(79,163,255,.35);
--markup-everyone-fill: rgba(242,206,117,.12);
--markup-here-fill: rgba(242,206,117,.12);
--markup-everyone-border: rgba(242,206,117,.35);
--markup-here-border: rgba(242,206,117,.35);
--code-block-bg: var(--co-code);
--code-inline-bg: var(--co-code);
--bg-table-header: var(--co-code);
--shadow-sm: none;
--shadow-md: none;
--shadow-lg: none;
--shadow-xl: none;
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 10px;
--radius-xl: 14px;
--radius-2xl: 14px;
--font-sans-primary: var(--co-font);
}
/* Preserve native dimensions, scroll containers and control geometry. */
html, body {
background: var(--co-background) !important;
color: var(--co-text);
font-family: var(--co-font);
}
::selection {
background: rgba(79,163,255,.28);
}
:focus-visible {
outline: 2px solid var(--co-accent);
outline-offset: 2px;
}
[class*='App.module__appContainer___'] {
background: var(--co-background) !important;
font-family: var(--co-font);
}
:is(
[class*='GuildsLayout.module__guildsLayoutContainer___'],
[class*='GuildsLayout.module__guildListScrollerWrapper___'],
[class*='GuildsLayout.module__guildListScrollContainer___'],
[class*='GuildsLayout.module__contentContainer___'],
[class*='GuildsLayout.module__contentInner___'],
[class*='GuildLayout.module__guildLayoutContainer___'],
[class*='GuildLayout.module__guildMainContent___'],
[class*='GuildNavbar.module__guildNavbarContainer___'],
[class*='ChannelListContent.module__channelListScroller___'],
[class*='ChannelLayout.module__channelLayoutContainer___'],
[class*='ChannelChatLayout.module__container___'],
[class*='MemberListContainer.module__memberListContainer___'],
[class*='MemberListContainer.module__memberListScroller___']
) {
background: transparent !important;
}
[class*='GuildNavbar.module__guildNavbarContainer___'] {
border-right: 1px solid var(--co-line);
}
[class*='MemberListContainer.module__memberListContainer___'] {
border-left: 1px solid var(--co-line);
}
:is(
[class*='GuildHeader.module__headerContainer___'],
[class*='ChannelHeader.module__headerContainer___']
) {
background: transparent !important;
border-bottom: 1px solid var(--co-line);
box-shadow: none !important;
}
[class*='ChannelHeader.module__channelName'] {
color: var(--co-text);
}
[class*='GuildsLayout.module__guildDivider___'] {
background: var(--co-line);
}
[class*='GuildsLayout.module__guildIndicatorBar___'] {
background: var(--co-accent);
}
[class*='GuildsLayout.module__guildIconSelected___'] {
outline: 2px solid var(--co-accent);
outline-offset: 2px;
}
:is(
[class*='SettingsSection.module__sectionTitle___'],
[class*='ChannelItem.module__categoryName___']
) {
color: var(--co-muted);
font-size: .8rem;
font-weight: 600;
letter-spacing: .06em;
text-transform: uppercase;
}
[class*='SettingsModalHeader.module__title___'] {
color: var(--co-text);
}
/* Full-sized buttons: preserve feature colors; hover borders are gray. */
:is(
[class*='Button.module__secondary___'],
[class*='Button.module__primary___'],
[class*='Button.module__danger']
) {
background: transparent !important;
background-image: none !important;
border: 1px solid var(--co-line) !important;
border-radius: 10px;
box-shadow: none !important;
}
[class*='Button.module__secondary___'] {
color: var(--co-text) !important;
}
[class*='Button.module__primary___'] {
color: var(--co-accent) !important;
border-color: var(--co-accent) !important;
}
[class*='Button.module__danger'] {
color: var(--co-danger) !important;
}
:is(
[class*='Button.module__secondary___'],
[class*='Button.module__primary___']
):not(:disabled):not([aria-disabled='true']):not([data-disabled='true']):not([data-disabled='']):hover {
background: var(--co-hover) !important;
border-color: var(--co-line) !important;
}
[class*='Button.module__danger']:not(:disabled):not([aria-disabled='true']):not([data-disabled='true']):not([data-disabled='']):hover {
background: rgba(239,101,101,.10) !important;
border-color: var(--co-line) !important;
}
:is(
[class*='ChannelItemSurface.module__channelItemSurface___'],
[class*='SettingsModalLayout.module__sidebarItem___'],
[class*='SettingsModalLayout.module__sidebarSubItem___']
) {
border-radius: 8px;
}
:is(
[class*='ChannelItemSurface.module__channelItemSurface___'],
[class*='SettingsModalLayout.module__sidebarItem___'],
[class*='SettingsModalLayout.module__sidebarSubItem___']
):not(:disabled):not([aria-disabled='true']):not([data-disabled='true']):not([data-disabled='']):hover {
background-color: var(--co-hover) !important;
}
:is(
[class*='ChannelItemSurface.module__channelItemSurfaceSelected___'],
[class*='SettingsModalLayout.module__sidebarItemSelected___'],
[class*='SettingsModalLayout.module__sidebarSubItemActive___']
) {
background-color: var(--co-selected) !important;
color: var(--co-accent);
}
:is(
[class*='ChannelHeader.module__iconButton___'],
[class*='TextareaButton.module__button___'],
[class*='UserArea.module__controlButton___'],
[class*='MessageActionBar.module__button___']
) {
border-radius: 8px;
box-shadow: none;
}
:is(
[class*='ChannelHeader.module__iconButton___'],
[class*='TextareaButton.module__button___'],
[class*='UserArea.module__controlButton___'],
[class*='MessageActionBar.module__button___']
):not(:disabled):not([aria-disabled='true']):not([data-disabled='true']):not([data-disabled='']):hover {
background-color: var(--co-hover);
}
:is(
[class*='ChannelHeader.module__iconButtonSelected___'],
[class*='TextareaButton.module__selected___']
) {
background-color: var(--co-selected) !important;
color: var(--co-accent);
}
[class*='UserArea.module__userAreaInnerWrapper___'] {
background: var(--co-background) !important;
border-top: 1px solid var(--co-line);
box-shadow: none;
}
:is(
[class*='TextareaInput.module__textareaOuterRow___'],
[class*='MessageSearchBar.module__inputContainer___']
) {
background: transparent !important;
border: 1px solid var(--co-line);
border-radius: 10px;
box-shadow: none !important;
}
:is(
[class*='TextareaInput.module__textareaOuterRow___'],
[class*='MessageSearchBar.module__inputContainer___']
):focus-within {
border-color: var(--co-accent);
}
[class*='MessageSearchBar.module__scopeBadge___'] {
background: var(--co-hover);
color: var(--co-muted);
border-radius: 4px;
}
/* Opaque floating surfaces preserve readability without clipping overlays. */
:is(
[class*='ContextMenu.module__contextMenu___'],
[class*='PopoverPopout.module__popout___'],
[class*='Tooltip.module__tooltip___'],
[class*='Toast.module__toast___'],
[class*='MessageActionBar.module__actionBar___']
) {
background: var(--co-background) !important;
background-image: none !important;
border: 1px solid var(--co-line);
border-radius: 10px;
box-shadow: none !important;
}
[class*='ContextMenu.module__item___'] {
border-radius: 6px;
}
[class*='ContextMenu.module__item___']:not(:disabled):not([aria-disabled='true']):not([data-disabled='true']):not([data-disabled='']):is(:hover, :focus-visible, [data-highlighted]:not([data-highlighted='false'])) {
background-color: var(--co-hover) !important;
}
[class*='ContextMenu.module__danger___'] {
color: var(--co-danger) !important;
}
[class*='ContextMenu.module__separator___'] {
background-color: var(--co-line);
}
[class*='SettingsModalLayout.module__container___'] {
background: var(--co-background) !important;
border: 1px solid var(--co-line);
border-radius: 14px;
box-shadow: none !important;
}
:is(
[class*='SettingsModalLayout.module__desktopSidebar___'],
[class*='SettingsModalLayout.module__desktopContent___'],
[class*='SettingsModalLayout.module__desktopHeader___']
) {
background: transparent !important;
}
[class*='SettingsModalLayout.module__desktopSidebar___'] {
border-right: 1px solid var(--co-line);
}
[class*='SettingsModalLayout.module__desktopHeader___'] {
border-bottom: 1px solid var(--co-line);
}
[class*='Message.module__message___'] :is(code, kbd, samp) {
background: var(--co-code);
border-radius: 4px;
font-family: var(--co-mono);
}
[class*='Message.module__message___'] pre {
background: var(--co-code);
border: 1px solid var(--co-line);
border-radius: 8px;
font-family: var(--co-mono);
}
[class*='Message.module__message___'] pre code {
background: transparent;
}
[class*='Message.module__message___'] a[href] {
color: var(--co-accent);
}
:is(
[class*='GuildsLayout.module__guildListScrollContainer___'],
[class*='ChannelListContent.module__channelListScroller___'],
[class*='MemberListContainer.module__memberListScroller___']
) {
scrollbar-width: thin;
scrollbar-color: var(--co-line) transparent;
}
/* Consolidated hover outline.
All state filters belong to the SAME element (no descendant whitespace).
Keyboard-focus and selected-guild outlines are intentionally preserved.
Existing bordered buttons use their border, avoiding a double line. */
:is(
[class*='ChannelHeader.module__iconButton___'],
[class*='TextareaButton.module__button___'],
[class*='UserArea.module__controlButton___'],
[class*='MessageActionBar.module__button___'],
[class*='ChannelItemSurface.module__channelItemSurface___'],
[class*='SettingsModalLayout.module__sidebarItem___'],
[class*='SettingsModalLayout.module__sidebarSubItem___'],
[class*='ContextMenu.module__item___'],
[class*='GuildsLayout.module__guildListItem___'],
[class*='TextareaInput.module__textareaOuterRow___'],
[class*='MessageSearchBar.module__inputContainer___']
):not(:disabled):not([aria-disabled='true']):not([data-disabled='true']):not([data-disabled='']):hover:not(:focus-visible):not(:focus-within) {
outline: 1px solid var(--co-line) !important;
outline-offset: -1px;
}
/* Do not replace an already-visible selected server outline on hover. */
[class*='GuildsLayout.module__guildListItem___']:has([class*='GuildsLayout.module__guildIconSelected___']):not(:disabled):not([aria-disabled='true']):not([data-disabled='true']):not([data-disabled='']):hover:not(:focus-visible):not(:focus-within) {
outline: none !important;
}