diff options
Diffstat (limited to 'front/src/styles')
-rw-r--r-- | front/src/styles/ThemeProvider.tsx | 302 | ||||
-rw-r--r-- | front/src/styles/ThemeSwitcher.css | 249 | ||||
-rw-r--r-- | front/src/styles/ThemeSwitcher.tsx | 131 | ||||
-rw-r--r-- | front/src/styles/styles.css | 438 | ||||
-rw-r--r-- | front/src/styles/trill.css | 612 |
5 files changed, 1732 insertions, 0 deletions
diff --git a/front/src/styles/ThemeProvider.tsx b/front/src/styles/ThemeProvider.tsx new file mode 100644 index 0000000..2cc0ca6 --- /dev/null +++ b/front/src/styles/ThemeProvider.tsx @@ -0,0 +1,302 @@ +import React, { + createContext, + useContext, + useEffect, + useState, + type ReactNode, +} from "react"; + +export type ThemeName = + | "light" + | "dark" + | "sepia" + | "noir" + | "ocean" + | "forest" + | "gruvbox"; + +export interface ThemeColors { + primary: string; + primaryHover: string; + secondary: string; + background: string; + surface: string; + surfaceHover: string; + text: string; + textSecondary: string; + textMuted: string; + border: string; + borderLight: string; + success: string; + warning: string; + error: string; + info: string; + link: string; + linkHover: string; + shadow: string; + overlay: string; +} + +export interface Theme { + name: ThemeName; + colors: ThemeColors; +} + +const themes: Record<ThemeName, Theme> = { + light: { + name: "light", + colors: { + primary: "#543fd7", + primaryHover: "#4532b8", + secondary: "#f39c12", + background: "#ffffff", + surface: "#f8f9fa", + surfaceHover: "#e9ecef", + text: "#212529", + textSecondary: "#495057", + textMuted: "#6c757d", + border: "#dee2e6", + borderLight: "#e9ecef", + success: "#28a745", + warning: "#ffc107", + error: "#dc3545", + info: "#17a2b8", + link: "#543fd7", + linkHover: "#4532b8", + shadow: "rgba(0, 0, 0, 0.1)", + overlay: "rgba(0, 0, 0, 0.5)", + }, + }, + dark: { + name: "dark", + colors: { + primary: "#7c6ef7", + primaryHover: "#9085f9", + secondary: "#f39c12", + background: "#0d1117", + surface: "#161b22", + surfaceHover: "#21262d", + text: "#c9d1d9", + textSecondary: "#8b949e", + textMuted: "#6e7681", + border: "#30363d", + borderLight: "#21262d", + success: "#3fb950", + warning: "#d29922", + error: "#f85149", + info: "#58a6ff", + link: "#58a6ff", + linkHover: "#79b8ff", + shadow: "rgba(0, 0, 0, 0.3)", + overlay: "rgba(0, 0, 0, 0.7)", + }, + }, + sepia: { + name: "sepia", + colors: { + primary: "#8b4513", + primaryHover: "#6b3410", + secondary: "#d2691e", + background: "#f4e8d0", + surface: "#ede0c8", + surfaceHover: "#e6d9c0", + text: "#3e2723", + textSecondary: "#5d4037", + textMuted: "#6d4c41", + border: "#d7ccc8", + borderLight: "#e0d5d0", + success: "#689f38", + warning: "#ff9800", + error: "#d32f2f", + info: "#0288d1", + link: "#8b4513", + linkHover: "#6b3410", + shadow: "rgba(62, 39, 35, 0.1)", + overlay: "rgba(62, 39, 35, 0.5)", + }, + }, + noir: { + name: "noir", + colors: { + primary: "#ffffff", + primaryHover: "#e0e0e0", + secondary: "#808080", + background: "#000000", + surface: "#0a0a0a", + surfaceHover: "#1a1a1a", + text: "#ffffff", + textSecondary: "#b0b0b0", + textMuted: "#808080", + border: "#333333", + borderLight: "#1a1a1a", + success: "#4caf50", + warning: "#ff9800", + error: "#f44336", + info: "#2196f3", + link: "#b0b0b0", + linkHover: "#ffffff", + shadow: "rgba(255, 255, 255, 0.1)", + overlay: "rgba(0, 0, 0, 0.9)", + }, + }, + ocean: { + name: "ocean", + colors: { + primary: "#006994", + primaryHover: "#005577", + secondary: "#00acc1", + background: "#e1f5fe", + surface: "#b3e5fc", + surfaceHover: "#81d4fa", + text: "#01579b", + textSecondary: "#0277bd", + textMuted: "#4fc3f7", + border: "#81d4fa", + borderLight: "#b3e5fc", + success: "#00c853", + warning: "#ffab00", + error: "#d50000", + info: "#00b0ff", + link: "#0277bd", + linkHover: "#01579b", + shadow: "rgba(1, 87, 155, 0.1)", + overlay: "rgba(1, 87, 155, 0.5)", + }, + }, + forest: { + name: "forest", + colors: { + primary: "#2e7d32", + primaryHover: "#1b5e20", + secondary: "#689f38", + background: "#f1f8e9", + surface: "#dcedc8", + surfaceHover: "#c5e1a5", + text: "#1b5e20", + textSecondary: "#33691e", + textMuted: "#558b2f", + border: "#aed581", + borderLight: "#c5e1a5", + success: "#4caf50", + warning: "#ff9800", + error: "#f44336", + info: "#03a9f4", + link: "#388e3c", + linkHover: "#2e7d32", + shadow: "rgba(27, 94, 32, 0.1)", + overlay: "rgba(27, 94, 32, 0.5)", + }, + }, + gruvbox: { + name: "gruvbox", + colors: { + primary: "#fe8019", + primaryHover: "#d65d0e", + secondary: "#fabd2f", + background: "#282828", + surface: "#3c3836", + surfaceHover: "#504945", + text: "#ebdbb2", + textSecondary: "#d5c4a1", + textMuted: "#bdae93", + border: "#665c54", + borderLight: "#504945", + success: "#b8bb26", + warning: "#fabd2f", + error: "#fb4934", + info: "#83a598", + link: "#8ec07c", + linkHover: "#b8bb26", + shadow: "rgba(0, 0, 0, 0.3)", + overlay: "rgba(40, 40, 40, 0.8)", + }, + }, +}; + +interface ThemeContextType { + theme: Theme; + themeName: ThemeName; + setTheme: (name: ThemeName) => void; + availableThemes: ThemeName[]; +} + +const ThemeContext = createContext<ThemeContextType | undefined>(undefined); + +interface ThemeProviderProps { + children: ReactNode; + defaultTheme?: ThemeName; +} + +export const ThemeProvider: React.FC<ThemeProviderProps> = ({ + children, + defaultTheme = "light", +}) => { + const [themeName, setThemeName] = useState<ThemeName>(() => { + const savedTheme = localStorage.getItem("theme") as ThemeName; + if (savedTheme && themes[savedTheme]) { + return savedTheme; + } + + if ( + window.matchMedia && + window.matchMedia("(prefers-color-scheme: dark)").matches + ) { + return "dark"; + } + + return defaultTheme; + }); + + const theme = themes[themeName]; + + useEffect(() => { + const root = document.documentElement; + + root.setAttribute("data-theme", themeName); + + Object.entries(theme.colors).forEach(([key, value]) => { + const cssVarName = `--color-${key.replace(/([A-Z])/g, "-$1").toLowerCase()}`; + root.style.setProperty(cssVarName, value); + }); + + localStorage.setItem("theme", themeName); + }, [themeName, theme]); + + useEffect(() => { + const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); + const handleChange = (e: MediaQueryListEvent) => { + const savedTheme = localStorage.getItem("theme"); + if (!savedTheme) { + setThemeName(e.matches ? "dark" : "light"); + } + }; + + mediaQuery.addEventListener("change", handleChange); + return () => mediaQuery.removeEventListener("change", handleChange); + }, []); + + const setTheme = (name: ThemeName) => { + if (themes[name]) { + setThemeName(name); + } + }; + + const value: ThemeContextType = { + theme, + themeName, + setTheme, + availableThemes: Object.keys(themes) as ThemeName[], + }; + + return ( + <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider> + ); +}; + +export const useTheme = (): ThemeContextType => { + const context = useContext(ThemeContext); + if (context === undefined) { + throw new Error("useTheme must be used within a ThemeProvider"); + } + return context; +}; diff --git a/front/src/styles/ThemeSwitcher.css b/front/src/styles/ThemeSwitcher.css new file mode 100644 index 0000000..518a00d --- /dev/null +++ b/front/src/styles/ThemeSwitcher.css @@ -0,0 +1,249 @@ +/* Theme Switcher Styles */ + +/* Compact variant */ +.theme-switcher-compact { + display: inline-flex; + align-items: center; + gap: var(--spacing-sm); + padding: var(--spacing-sm) var(--spacing-md); + background-color: var(--color-surface); + border: 1px solid var(--color-border); + border-radius: var(--radius-full); + cursor: pointer; + transition: all var(--transition-fast); + font-size: var(--font-md); + color: var(--color-text); +} + +.theme-switcher-compact:hover { + background-color: var(--color-surface-hover); + border-color: var(--color-primary); + transform: scale(1.05); +} + +.theme-switcher-compact:active { + transform: scale(0.98); +} + +.theme-switcher-compact .theme-icon { + font-size: 1.2em; + display: flex; + align-items: center; +} + +.theme-switcher-compact .theme-label { + font-weight: var(--font-medium); +} + +/* Buttons variant */ +.theme-switcher-buttons { + display: flex; + align-items: center; + gap: var(--spacing-md); +} + +.theme-switcher-buttons .theme-label { + color: var(--color-text-secondary); + font-weight: var(--font-medium); +} + +.theme-buttons-group { + display: flex; + gap: var(--spacing-xs); + background-color: var(--color-surface); + padding: var(--spacing-xs); + border-radius: var(--radius-lg); + border: 1px solid var(--color-border); +} + +.theme-button { + display: flex; + align-items: center; + gap: var(--spacing-xs); + padding: var(--spacing-xs) var(--spacing-sm); + background-color: transparent; + border: 1px solid transparent; + border-radius: var(--radius-md); + cursor: pointer; + transition: all var(--transition-fast); + color: var(--color-text-secondary); + font-size: var(--font-sm); +} + +.theme-button:hover { + background-color: var(--color-surface-hover); + color: var(--color-text); +} + +.theme-button.active { + background-color: var(--color-primary); + color: white; + border-color: var(--color-primary); +} + +.theme-button .theme-icon { + font-size: 1.1em; +} + +.theme-button .theme-name { + display: none; +} + +@media (min-width: 768px) { + .theme-button .theme-name { + display: inline; + } +} + +/* Dropdown variant */ +.theme-switcher-dropdown { + position: relative; + display: inline-block; +} + +.theme-dropdown-toggle { + display: flex; + align-items: center; + gap: var(--spacing-sm); + padding: var(--spacing-sm) var(--spacing-md); + background-color: var(--color-surface); + border: 1px solid var(--color-border); + border-radius: var(--radius-md); + cursor: pointer; + transition: all var(--transition-fast); + color: var(--color-text); + font-size: var(--font-md); +} + +.theme-dropdown-toggle:hover { + background-color: var(--color-surface-hover); + border-color: var(--color-primary); +} + +.theme-dropdown-toggle .theme-icon { + font-size: 1.2em; +} + +.theme-dropdown-toggle .theme-label { + font-weight: var(--font-medium); +} + +.theme-dropdown-toggle .dropdown-arrow { + font-size: 0.7em; + margin-left: var(--spacing-xs); + transition: transform var(--transition-fast); + color: var(--color-text-muted); +} + +.theme-dropdown-toggle[aria-expanded="true"] .dropdown-arrow { + transform: rotate(180deg); +} + +.theme-dropdown-backdrop { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: var(--z-dropdown); + background-color: transparent; +} + +.theme-dropdown-menu { + position: absolute; + top: calc(100% + var(--spacing-xs)); + right: 0; + min-width: 180px; + background-color: var(--color-background); + border: 1px solid var(--color-border); + border-radius: var(--radius-lg); + box-shadow: 0 4px 12px var(--color-shadow); + z-index: calc(var(--z-dropdown) + 1); + padding: var(--spacing-xs); + animation: dropdownSlide 0.2s ease-out; +} + +@keyframes dropdownSlide { + from { + opacity: 0; + transform: translateY(-10px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.theme-dropdown-item { + display: flex; + align-items: center; + gap: var(--spacing-sm); + width: 100%; + padding: var(--spacing-sm) var(--spacing-md); + background-color: transparent; + border: none; + border-radius: var(--radius-md); + cursor: pointer; + transition: all var(--transition-fast); + color: var(--color-text); + font-size: var(--font-md); + text-align: left; +} + +.theme-dropdown-item:hover { + background-color: var(--color-surface); +} + +.theme-dropdown-item.active { + background-color: var(--color-surface); + color: var(--color-primary); + font-weight: var(--font-medium); +} + +.theme-dropdown-item .theme-icon { + font-size: 1.2em; + width: 1.5em; + text-align: center; +} + +.theme-dropdown-item .theme-name { + flex: 1; +} + +.theme-dropdown-item .checkmark { + color: var(--color-success); + font-weight: var(--font-bold); +} + +/* Accessibility */ +.theme-switcher-compact:focus, +.theme-button:focus, +.theme-dropdown-toggle:focus, +.theme-dropdown-item:focus { + outline: 2px solid var(--color-primary); + outline-offset: 2px; +} + +/* Dark theme adjustments */ +[data-theme="dark"] .theme-dropdown-menu { + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5); +} + +/* Reduced motion */ +@media (prefers-reduced-motion: reduce) { + .theme-switcher-compact, + .theme-button, + .theme-dropdown-toggle, + .theme-dropdown-item, + .dropdown-arrow { + transition: none; + } + + .theme-dropdown-menu { + animation: none; + } + + .theme-switcher-compact:hover { + transform: none; + } +}
\ No newline at end of file diff --git a/front/src/styles/ThemeSwitcher.tsx b/front/src/styles/ThemeSwitcher.tsx new file mode 100644 index 0000000..425bed9 --- /dev/null +++ b/front/src/styles/ThemeSwitcher.tsx @@ -0,0 +1,131 @@ +import React, { useState } from "react"; +import { useTheme, type ThemeName } from "../styles/ThemeProvider"; +import "./ThemeSwitcher.css"; + +interface ThemeSwitcherProps { + variant?: "dropdown" | "buttons" | "compact"; + showLabel?: boolean; +} + +const themeIcons: Record<ThemeName, string> = { + light: "☀️", + dark: "🌙", + sepia: "📜", + noir: "⚫", + ocean: "🌊", + forest: "🌲", + gruvbox: "🍂", +}; + +const themeLabels: Record<ThemeName, string> = { + light: "Light", + dark: "Dark", + sepia: "Sepia", + noir: "Noir", + ocean: "Ocean", + forest: "Forest", + gruvbox: "Gruvbox", +}; + +export const ThemeSwitcher: React.FC<ThemeSwitcherProps> = ({ + variant = "dropdown", + showLabel = true, +}) => { + const { themeName, setTheme, availableThemes } = useTheme(); + const [isOpen, setIsOpen] = useState(false); + + const handleThemeChange = (theme: ThemeName) => { + setTheme(theme); + setIsOpen(false); + }; + + const cycleTheme = () => { + const currentIndex = availableThemes.indexOf(themeName); + const nextIndex = (currentIndex + 1) % availableThemes.length; + setTheme(availableThemes[nextIndex]); + }; + + if (variant === "compact") { + return ( + <button + className="theme-switcher-compact" + onClick={cycleTheme} + title={`Current theme: ${themeLabels[themeName]}. Click to switch.`} + aria-label="Switch theme" + > + <span className="theme-icon">{themeIcons[themeName]}</span> + {showLabel && ( + <span className="theme-label">{themeLabels[themeName]}</span> + )} + </button> + ); + } + + if (variant === "buttons") { + return ( + <div className="theme-switcher-buttons"> + {showLabel && <span className="theme-label">Theme:</span>} + <div className="theme-buttons-group"> + {availableThemes.map((theme) => ( + <button + key={theme} + className={`theme-button ${themeName === theme ? "active" : ""}`} + onClick={() => handleThemeChange(theme)} + title={themeLabels[theme]} + aria-label={`Switch to ${themeLabels[theme]} theme`} + aria-pressed={themeName === theme} + > + <span className="theme-icon">{themeIcons[theme]}</span> + {showLabel && ( + <span className="theme-name">{themeLabels[theme]}</span> + )} + </button> + ))} + </div> + </div> + ); + } + + // Default dropdown variant + return ( + <div className="theme-switcher-dropdown"> + <button + className="theme-dropdown-toggle" + onClick={() => setIsOpen(!isOpen)} + aria-haspopup="true" + aria-expanded={isOpen} + > + <span className="theme-icon">{themeIcons[themeName]}</span> + {showLabel && ( + <span className="theme-label">{themeLabels[themeName]}</span> + )} + <span className="dropdown-arrow">▼</span> + </button> + + {isOpen && ( + <> + <div + className="theme-dropdown-backdrop" + onClick={() => setIsOpen(false)} + aria-hidden="true" + /> + <div className="theme-dropdown-menu" role="menu"> + {availableThemes.map((theme) => ( + <button + key={theme} + className={`theme-dropdown-item ${themeName === theme ? "active" : ""}`} + onClick={() => handleThemeChange(theme)} + role="menuitem" + aria-selected={themeName === theme} + > + <span className="theme-icon">{themeIcons[theme]}</span> + <span className="theme-name">{themeLabels[theme]}</span> + {themeName === theme && <span className="checkmark">✓</span>} + </button> + ))} + </div> + </> + )} + </div> + ); +}; diff --git a/front/src/styles/styles.css b/front/src/styles/styles.css new file mode 100644 index 0000000..c2b05d6 --- /dev/null +++ b/front/src/styles/styles.css @@ -0,0 +1,438 @@ +/* assets */ +/* fonts */ +@font-face { + font-family: "Inter"; + src: url(/fonts/Inter/Inter-VariableFont_opsz,wght.ttf); + font-weight: 100 900; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: "Inter"; + src: url(/fonts/Inter/Inter-Italic-VariableFont_opsz,wght.ttf); + font-weight: 100 900; + font-style: italic; + font-display: swap; +} + +@font-face { + font-family: "Source Code Pro"; + src: url(/fonts/Source_Code_Pro/SourceCodePro-VariableFont_wght.ttf); + font-weight: 100 900; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: "Source Code Pro"; + src: url(/fonts/Source_Code_Pro/SourceCodePro-Italic-VariableFont_wght.ttf); + font-weight: 100 900; + font-style: italic; + font-display: swap; +} + +/* tailwindy */ + +.grow { + flex-grow: 1; +} + +button { + cursor: pointer; +} + +code { + font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", + monospace; +} + +t .red { + background-color: rgb(200, 0, 0, 0.9); +} + +.tc, +.ct { + text-align: center; +} + +.cb { + margin: auto; +} + +.xc { + position: absolute; + left: 50%; + transform: translateX(-50%); +} + +.hidden { + display: none; +} + +.x-center { + margin: auto; + text-align: center; + display: block; +} + +.flex { + display: flex; +} + +.f1 { + display: flex; + justify-content: space-between; + align-items: center; +} + +.flex-align { + display: flex; + gap: 1rem; + align-items: center; +} + +.noscroll { + overflow: hidden; +} + +.scroll-y { + overflow-y: scroll; +} + +.cp { + cursor: pointer; +} + +.m0 { + margin: 0; +} + +.mb { + margin: 0 0 1rem 0; +} + +.mt { + margin-top: 1rem; +} + +.mr { + margin-right: 0.5rem; +} + +.s-50 { + width: 50px; +} + +.s-100 { + width: 100px; +} + +.border { + border: 1px solid var(--text-color); +} + +/* styles */ + +/* common */ +html { + box-sizing: border-box; + color: var(--text-color); + background-color: var(--background-color); +} + +html, +body, +#root, +#mobile-ui { + height: 100%; + width: 100vw; + overflow: hidden; + /* no scrolling!!!*/ +} + +*, +*:before, +*:after { + box-sizing: inherit; +} + +body { + margin: 0; + font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', + 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', + sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + background-color: var(--color-background); + color: var(--color-text); + line-height: 1.6; + transition: background-color var(--transition-normal), color var(--transition-normal); +} + +/* Typography */ +h1, +h2, +h3, +h4, +h5, +h6 { + margin-bottom: var(--spacing-md); + font-weight: var(--font-semibold); + line-height: 1.2; + color: var(--color-text); +} + +#root { + margin: 1rem 2rem; + height: 100%; + overflow-y: auto; + font-family: "Inter"; + + + display: flex; + + & #left-menu { + margin-right: 1rem; + + #logo { + display: flex; + gap: 0.3rem; + + & img { + width: 48px; + height: 48px; + } + } + + & .opt { + cursor: pointer; + display: flex; + gap: 1rem; + margin: 1rem 0; + + & img { + width: 24px; + height: 24px; + } + } + } + + & main { + width: 726px; + margin: auto; + height: 100vh; + + & #top-tabs { + display: flex; + gap: 2rem; + justify-content: center; + + & div { + cursor: pointer; + } + + & .active { + font-weight: 700; + border-bottom: 3px solid var(--color-text); + } + } + + & #feed-proper { + margin-top: 1rem; + border: 1px solid grey; + border-radius: 0.75rem; + + & #composer { + padding: 10px; + display: flex; + gap: 0.5rem; + + & .sigil { + width: 48px; + height: 48px; + + & img { + width: inherit; + } + } + + & input { + background-color: transparent; + color: var(--color-text); + flex-grow: 1; + border: none; + outline: none; + } + } + } + + & .trill-post, + & .twatter-post { + border-top: 1px solid grey; + + & .left { + margin-right: 10px; + width: unset; + + & .sigil { + width: 48px; + height: 48px; + } + } + + & header { + align-items: center; + justify-content: left; + + & .author { + flex: unset; + gap: 0; + + & .name { + display: flex; + align-items: center; + + & .p { + font-family: "Source Code Pro"; + } + } + } + + & .date { + color: grey; + } + + } + + & footer { + justify-content: left; + margin: unset; + + & .icon { + margin: 0; + align-items: center; + gap: 0.2rem; + width: 64px; + + & img { + height: 18px; + } + + & .react-img { + height: 24px; + } + + & .react-icon { + font-size: 20px; + } + + & span { + margin-right: unset; + text-align: left; + font-size: 14px; + line-height: 1rem; + color: grey; + width: unset; + } + } + + & .menu-icon { + margin-left: auto; + } + } + } + + + & .user-contact { + & .contact-cover { + margin-bottom: -40px; + + & img { + width: 100%; + height: 100%; + object-fit: cover; + } + } + + & .contact-name { + display: flex; + align-items: center; + gap: 0.5rem; + } + + & .contact-username { + margin-top: 1rem; + font-family: "Source Code Pro"; + font-weight: 400; + } + + & button { + width: unset; + margin: unset; + height: unset; + } + } + } + + & button { + font-size: 0.9rem; + font-weight: 700; + line-height: 1rem; + border: none; + border-radius: 2rem; + padding: 0.5rem 2rem; + } + + & .sigil, + & .sigil svg { + border-radius: 0.5rem; + } +} + +#big-button { + position: absolute; + right: 2rem; + bottom: 2rem; + font-size: 1.5rem; + font-weight: bold; + cursor: pointer; + text-align: center; + line-height: 3rem; + width: 3rem; + height: 3rem; + border-radius: 50%; + z-index: 100; +} + +/* modal */ +#modal-background { + height: 100vh; + width: 100vw; + background-color: rgb(0, 0, 0, 0.9); + position: fixed; + top: 0; + left: 0; + z-index: 100; +} + +#modal { + position: fixed; + top: 50%; + left: 50%; + width: 80%; + z-index: 101; + transform: translate(-50%, -50%); + background-color: var(--background-color); + padding: 1rem; + max-height: 80%; +} + +.modal-buttons { + display: flex; + justify-content: space-around; +} + +::-webkit-scrollbar { + display: none; +}
\ No newline at end of file diff --git a/front/src/styles/trill.css b/front/src/styles/trill.css new file mode 100644 index 0000000..5687c7a --- /dev/null +++ b/front/src/styles/trill.css @@ -0,0 +1,612 @@ +#not-found { + margin: auto; + padding: 2rem; + text-align: center; +} + +#not-found button { + height: 1.5rem; + margin: auto; +} + +#timeline { + overflow-y: auto; + overflow-x: hidden; +} + +.timeline-post { + width: 100%; + border-top: 1px solid var(--text-color); +} + +.trill-post { + display: flex; + padding: 0.5rem; + /* min-height: 150px; */ +} + +.trill-post .author { + flex: 1 0 auto; +} + +.trill-reply-thread { + border-top: 1px solid var(--text-color); +} + +.trill-post:first-child { + border-top: none; +} + +.trill-post:last-child { + border-bottom: 1px solid var(--text-color); +} + +.trill-post .left { + width: 8%; + margin-right: 1rem; +} + +.trill-post .sigil { + height: 42px; + width: 42px; +} + +.trill-post .right { + width: 90%; +} + +.trill-post header { + display: flex; + justify-content: space-between; +} + +.trill-post header p { + margin: 0 0.3rem; +} + +.trill-post .nick { + font-weight: 700; +} + +.trill-post header .p { + font-family: "Courier New", Courier, monospace; + font-weight: 100; + font-size: 1rem; +} + +.trill-post .p-only { + margin: 0.7rem 0.3rem; + font-weight: 700; +} + +.trill-post .p { + /* margin-top: -5px; */ +} + +.trill-post a { + text-decoration: 0; + color: var(--text-color); +} + +.trill-post blockquote { + border-left: 2px solid grey; + margin-left: 0; + padding-left: 0.5rem; + opacity: 70%; +} + +.trill-post .body { + margin: 1rem; + margin-left: 0; +} + +.trill-post-body p span { + /* margin: 0 3px; */ +} + +.trill-post pre { + font-family: "Courier New", Courier, monospace; + background-color: rgb(200, 200, 200, 0.5); + padding: 0.2rem; + max-width: 90%; + border: 1px solid var(--text-color); + overflow: scroll; +} + +.trill-post .quote-in-post .body { + margin: 0; +} + +.quote-in-post svg { + margin-right: 0.5rem; +} + +.trill-post .body-text { + /* font-family: Arial, Helvetica, sans-serif; */ + margin: 0.3rem 0 1rem 0; + word-break: break-word; +} + +.trill-post .trill-post-paragraph { + margin-block-start: 1em; + margin-block-end: 1em; +} + +.trill-post .body-text a { + text-decoration: underline; +} + +.trill-post .token { + margin: 0 0.5rem; +} + +.trill-post .date { + float: right; +} + +.trill-post .nav { + display: flex; +} + +.trill-post .chevron { + width: 1.5rem; + height: 1.5rem; +} + +.body-media { + width: 100%; + max-height: 520px; + text-align: center; + /* images being inline */ +} + +.body-media img { + margin: 1px 3px; +} + +.body-img-1-of-1 { + max-width: 100%; + max-height: inherit; + margin: auto !important; +} + +.body-img-1-of-2 { + max-width: 48.5%; + max-height: inherit; +} + +.body-img-1-of-3 { + max-width: 48.5%; +} + +.body-img-1-of-4 { + max-width: 48.5%; +} + +.body-img-1-of-5 { + max-width: 31%; +} + +.body-img-1-of-6 { + max-width: 31%; +} + +.body-img-1-of-7 { + max-width: 31%; +} + +.body-img-1-of-8 { + max-width: 31%; +} + +.body-img-1-of-9 { + max-width: 31%; +} + +/* quotes */ + +.quote-in-post { + margin-top: 1rem; + padding: 0.5rem; + border: 1px solid grey; + border-radius: 0.5rem; + cursor: pointer; +} + +.quote-in-post header { + display: flex; +} + +.mention { + font-family: "Courier New", Courier, monospace; + font-weight: 700; +} + +.mention:hover { + cursor: pointer; + text-decoration: underline; +} + +.bad-quote { + border: 1px solid var(--text-color); + padding: 7px; + border-radius: 0.5rem; +} + +/* post-cards */ +.trill-post-card { + position: relative; + border-radius: 0.3rem; + /* margin: 1rem 0 0 -8%; */ + margin: 0.5rem 0; +} + +.trill-post-card-logo { + position: absolute; + width: 25px; + height: 25px; + top: -17px; + left: -17px; +} + +#post-menu { + position: absolute; + top: 0; + right: 50px; + z-index: 99; +} + +.deleted-post { + text-align: center; + border: 1px solid var(--text-color); + padding: 0.4rem; +} + +#post-menu p { + background-color: var(--background-color); + margin: 0; + padding: 0.5rem; + cursor: pointer; + border: 1px solid var(--text-color); + height: 40px; +} + +#post-menu p:hover { + /* background-color: var(--highlighted-grey); */ +} + +/* threads */ +.trill-reply-thread { + margin-top: 1rem; +} + +#replies>.trill-post:first-child { + border-top: 1px solid black; +} + +/* footer */ + +.footer-wrapper { + position: relative; + /* transform: rotate(0deg); */ + /* the dummy transform enforces position fixed inheritance */ +} + +.post-footer footer { + display: flex; + margin-left: -20px; + height: 24px; + justify-content: space-between; +} + +footer .icon { + cursor: pointer; + margin: 0 0.2rem; + display: flex; + /* min-width: 64px; */ +} + +footer #menu-icon { + width: 32px !important; + /* margin-left: 20px; */ +} + +.post-footer footer .icon img { + display: block; + width: 24px; + height: 24px; +} + +footer .icon span { + display: block; + width: 30px; + text-align: right; + padding-top: 0.2rem; + margin-right: 0.4rem; +} + +footer .icon span:hover { + text-decoration: underline; +} + +.react-icon { + font-size: 26px; + margin: -10px 0 0 0 !important; + padding: 0; + padding-top: 0 !important; +} + +#react-list { + display: flex; + flex-wrap: wrap; +} + +#react-list img { + margin: 3px; + width: 50px; + height: 50px; + cursor: pointer; + border: 1px solid transparent; +} + +#react-list span { + width: 50px; + height: 50px; + font-size: 38px; + margin: 3px; + cursor: pointer; + border: 1px solid transparent; +} + +#react-list span:hover, +#react-list img:hover { + border: 1px solid var(--text-color); +} + +#menu-background { + position: fixed; + top: 0; + left: 0; + opacity: 0; + height: 100vh; + width: 100vw; +} + +/* contact */ + +.contact-cover { + height: 150px; + max-width: 100vw; + margin-bottom: -50px; +} + +#contact-proper { + padding: 1rem; +} + +#contact-proper .row { + display: flex; +} + +.contact-avatar { + width: 6rem; + height: 6rem; +} + +.contact-name { + margin-top: 1rem; + margin-bottom: 0.5rem; + margin-left: 0.3rem; + font-weight: 700; + font-size: 1.1rem; +} + +.contact-username { + margin-top: -10px; +} + +#contact-proper .buttons { + margin-top: 2rem; + margin-left: auto; +} + +#contact-proper .buttons button { + width: 5rem; + margin-bottom: 5px; + height: 1.5rem; +} + +#contact-proper .p { + font-family: "Courier New", Courier, monospace; +} + +#contact-proper .p-only { + margin-top: 1rem; +} + +.bio-row { + display: flex; + align-items: center; +} + +.stats-row { + display: flex; + justify-content: center; +} + +.stats-icon { + margin: 0 2px; +} + +.stats-row p { + text-align: center; + font-size: 1.3rem; + margin: -5px 0 0 0; +} + +.stats-row img { + width: 32px; +} + +.locked-notice, +.suspended-notice { + text-align: center; +} + +.cover-placeholder { + height: 150px; + background-color: rgb(125, 125, 125, 0.5); +} + +#stats-modal .trill-post { + border-bottom: 1px solid var(--text-color) !important; +} + +#stats-modal { + height: 80vh; +} + +#stats-modal #engagement { + min-height: 40%; + max-height: 40%; + overflow-y: scroll; +} + +#stats-modal .trill-post { + max-height: 50%; + overflow-y: scroll; +} + +.btw { + display: flex; + justify-content: space-between; + align-items: center; +} + +#stats-modal .react-stat img { + width: 32px; + height: 32px; +} + +#stats-modal .react-stat react-icon { + width: 32px; + height: 32px; +} + +#stats-modal #engagement .nickname { + font-size: 1rem; +} + +#stats-modal #engagement .p { + font-size: 0.9rem; +} + +#stats-modal .tab h4 { + font-weight: 100; +} + +#stats-modal .tab.active-tab h4 { + font-weight: 700; +} + +/* .not-found { + border: 1px solid var(--text-color); + border-radius: 1rem; + padding: 0.5rem; +} */ + +/* refs */ +.reference {} + +/* polls */ +.trill-poll { + /* border: 1px solid var(--text-color); */ + border-radius: 1rem; + padding: 0.5rem; + position: relative; + background: linear-gradient(90deg, + rgba(255, 255, 168, 0.4) 0%, + /* Lighter yellow */ + rgba(255, 233, 150, 0.5) 52%, + /* Mid-tone gold */ + rgba(255, 209, 0, 0.4) 100% + /* Deeper gold */ + ); +} + +.trill-poll .poll-option { + height: 2rem; + align-items: center; + text-align: center; + border: 1px solid var(--text-color); + border-radius: 0.7rem; + margin: 1rem; + position: relative; + outline: 3px solid transparent; +} + +.trill-poll .my-vote:hover { + /* cursor:not-allowed */ +} + +.trill-poll .poll-option:hover { + opacity: 50%; + outline-color: var(--text-color); +} + +.trill-poll .poll-option p { + padding: 0 0.5rem; + margin: 0; + line-height: 2rem; +} + +.trill-poll .poll-option-stats { + height: 2rem; + position: relative; +} + +.trill-poll .poll-option-bar { + height: 100%; + position: absolute; + background-color: rgb(100, 100, 100, 0.3); + border-radius: 0.7rem; +} + +.trill-poll .my-vote { + border: 3px solid var(--text-color); + border-right: 4px solid var(--text-color); +} + +.trill-poll .bottom-row { + opacity: 60%; +} + +.youtube-thumbnail { + width: 70%; + margin: 0.7rem auto; +} + +.cursor-button { + width: 100%; + padding: 1rem; + border-top: 1px solid var(--text-color); +} + +.cursor-button button { + display: block; + margin: auto; + padding: 0.5rem; +} + +.rumor-quote img { + width: 50px; + margin-right: 1rem; +} + +#trill-thread { + flex-grow: 1; + height: 100%; + overflow-y: auto; + + +}
\ No newline at end of file |