fluxer-themes/clarth/charcoal outline/charcoal-outline-motion.css
2026-11-09 19:30:31 -05:00

655 lines
22 KiB
CSS

/*
* @name Charcoal Outline — Motion Addon
* @description Optional subtle feedback for Charcoal Outline 1.0.1.
* @version 1.0.0
* Beer-Ware (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.
*/
/*
* @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;
}
/*Motion stuff is below
@media (prefers-reduced-motion: no-preference) {
/* Neutral starting outline; the base theme supplies the hover color.
Exclude keyboard focus and rows containing a selected guild icon. */
:is(
[class*='ChannelHeader.module__iconButton___'],
[class*='TextareaButton.module__button___'],
[class*='UserArea.module__controlButton___'],
[class*='MessageActionBar.module__button___'],
[class*='ContextMenu.module__item___'],
[class*='GuildsLayout.module__guildListItem___'],
[class*='MessageSearchBar.module__inputContainer___'],
[class*='ChannelItemSurface.module__channelItemSurface___'],
[class*='SettingsModalLayout.module__sidebarItem___'],
[class*='SettingsModalLayout.module__sidebarSubItem___'],
[class*='TextareaInput.module__textareaOuterRow___']
):not(:focus-visible):not(:focus-within):not(:has([class*='GuildsLayout.module__guildIconSelected___'])) {
outline: 1px solid transparent;
outline-offset: -1px;
}
/* One transition list per component group avoids competing patches. */
:is(
[class*='UserArea.module__controlButton___'],
[class*='MessageActionBar.module__button___'],
[class*='ContextMenu.module__item___'],
[class*='GuildsLayout.module__guildListItem___'],
[class*='MessageSearchBar.module__inputContainer___']
) {
transition: outline-color 140ms ease;
}
:is(
[class*='ChannelHeader.module__iconButton___'],
[class*='TextareaButton.module__button___']
) {
transition: scale 90ms ease, outline-color 140ms ease;
}
:is(
[class*='ChannelItemSurface.module__channelItemSurface___'],
[class*='SettingsModalLayout.module__sidebarItem___'],
[class*='SettingsModalLayout.module__sidebarSubItem___']
) {
transition: background-color 120ms ease, outline-color 140ms ease;
}
[class*='TextareaInput.module__textareaOuterRow___'] {
transition: border-color 120ms ease, outline-color 140ms ease;
}
/* Focus outlines appear immediately; other feedback stays enabled. */
:is(
[class*='UserArea.module__controlButton___'],
[class*='MessageActionBar.module__button___'],
[class*='ContextMenu.module__item___'],
[class*='GuildsLayout.module__guildListItem___'],
[class*='MessageSearchBar.module__inputContainer___']
):is(:focus-visible, :focus-within) {
transition: none;
}
:is(
[class*='ChannelHeader.module__iconButton___'],
[class*='TextareaButton.module__button___']
):is(:focus-visible, :focus-within) {
transition: scale 90ms ease;
}
:is(
[class*='ChannelItemSurface.module__channelItemSurface___'],
[class*='SettingsModalLayout.module__sidebarItem___'],
[class*='SettingsModalLayout.module__sidebarSubItem___']
):is(:focus-visible, :focus-within) {
transition: background-color 120ms ease;
}
[class*='TextareaInput.module__textareaOuterRow___']:is(:focus-visible, :focus-within) {
transition: border-color 120ms ease;
}
:is(
[class*='Button.module__secondary___'],
[class*='Button.module__primary___'],
[class*='Button.module__danger']
) {
transition: scale 100ms ease, border-color 140ms ease;
}
:is(
[class*='Button.module__secondary___'],
[class*='Button.module__primary___'],
[class*='Button.module__danger']
):not(:disabled):not([aria-disabled='true']):not([data-disabled='true']):not([data-disabled='']):active {
scale: .98;
}
:is(
[class*='ChannelHeader.module__iconButton___'],
[class*='TextareaButton.module__button___']
):not(:disabled):not([aria-disabled='true']):not([data-disabled='true']):not([data-disabled='']):active {
scale: .95;
}
/* Entrances run when elements are inserted/rendered, not necessarily
whenever a persistently mounted element becomes visible.
No fill-mode: native styles resume after each entrance.
These declarations replace native animation lists on these targets. */
:is(
[class*='ContextMenu.module__contextMenu___'],
[class*='PopoverPopout.module__popout___']
) {
animation: co-motion-enter 140ms ease-out;
}
[class*='Toast.module__toast___'] {
animation: co-motion-enter 150ms ease-out;
}
[class*='Tooltip.module__tooltip___'] {
animation: co-motion-fade 110ms ease-out;
}
[class*='MessageActionBar.module__actionBar___'] {
animation: co-motion-fade 120ms ease-out;
}
}
/* Move only the server icon, and only for fine hover-capable pointers. */
@media (hover: hover) and (pointer: fine) and
(prefers-reduced-motion: no-preference) {
[class*='GuildsLayout.module__guildIcon___'] {
transition: translate 140ms ease;
}
[class*='GuildsLayout.module__guildListItem___']:not(:disabled):not([aria-disabled='true']):not([data-disabled='true']):not([data-disabled='']):hover
[class*='GuildsLayout.module__guildIcon___'] {
translate: 0 -2px;
}
[class*='GuildsLayout.module__guildListItem___']:not(:disabled):not([aria-disabled='true']):not([data-disabled='true']):not([data-disabled='']):active
[class*='GuildsLayout.module__guildIcon___'] {
translate: 0 0;
}
}
/* Reduced-motion mode receives no motion rules from this addon.
Native client animations are deliberately left alone. */
@keyframes co-motion-enter {
from { opacity: 0; translate: 0 3px; }
to { opacity: 1; translate: 0 0; }
}
@keyframes co-motion-fade {
from { opacity: 0; }
to { opacity: 1; }
}