diff --git a/clarth/charcoal outline/README.md b/clarth/charcoal outline/README.md new file mode 100644 index 0000000..ded3f54 --- /dev/null +++ b/clarth/charcoal outline/README.md @@ -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 +``` diff --git a/clarth/charcoal outline/screenshots/preview.png b/clarth/charcoal outline/screenshots/preview.png new file mode 100644 index 0000000..2cc020c Binary files /dev/null and b/clarth/charcoal outline/screenshots/preview.png differ diff --git a/clarth/charcoal outline/theme.css b/clarth/charcoal outline/theme.css new file mode 100644 index 0000000..ea4abbe --- /dev/null +++ b/clarth/charcoal outline/theme.css @@ -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; +}