560 lines
14 KiB
CSS
560 lines
14 KiB
CSS
@import url('https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=DM+Mono:wght@400;500&family=Geist:wght@300;400;500;600&display=swap');
|
|
|
|
/* See the Tailwind configuration guide for advanced usage
|
|
https://tailwindcss.com/docs/configuration */
|
|
|
|
@import "tailwindcss" source(none);
|
|
@source "../../deps/ash_authentication_phoenix";
|
|
@source "../css";
|
|
@source "../js";
|
|
@source "../../lib/mixer_web";
|
|
|
|
/* A Tailwind plugin that makes "hero-#{ICON}" classes available.
|
|
The heroicons installation itself is managed by your mix.exs */
|
|
@plugin "../vendor/heroicons";
|
|
|
|
/* daisyUI Tailwind Plugin. You can update this file by fetching the latest version with:
|
|
curl -sLO https://github.com/saadeghi/daisyui/releases/latest/download/daisyui.js
|
|
Make sure to look at the daisyUI changelog: https://daisyui.com/docs/changelog/ */
|
|
@plugin "../vendor/daisyui" {
|
|
themes: false;
|
|
}
|
|
|
|
/* daisyUI theme plugin. You can update this file by fetching the latest version with:
|
|
curl -sLO https://github.com/saadeghi/daisyui/releases/latest/download/daisyui-theme.js
|
|
We ship with two themes, a light one inspired on Phoenix colors and a dark one inspired
|
|
on Elixir colors. Build your own at: https://daisyui.com/theme-generator/ */
|
|
@plugin "../vendor/daisyui-theme" {
|
|
name: "dark";
|
|
default: true;
|
|
prefersdark: true;
|
|
color-scheme: "dark";
|
|
--color-base-100: oklch(5% 0.005 270);
|
|
--color-base-200: oklch(8% 0.005 270);
|
|
--color-base-300: oklch(13% 0.008 270);
|
|
--color-base-content: oklch(93% 0.006 270);
|
|
--color-primary: oklch(58% 0.21 278);
|
|
--color-primary-content: oklch(98% 0.01 278);
|
|
--color-secondary: oklch(52% 0.18 278);
|
|
--color-secondary-content: oklch(98% 0.01 278);
|
|
--color-accent: oklch(68% 0.17 278);
|
|
--color-accent-content: oklch(98% 0.01 278);
|
|
--color-neutral: oklch(20% 0.012 270);
|
|
--color-neutral-content: oklch(93% 0.006 270);
|
|
--color-info: oklch(58% 0.158 241.966);
|
|
--color-info-content: oklch(97% 0.013 236.62);
|
|
--color-success: oklch(60% 0.118 184.704);
|
|
--color-success-content: oklch(98% 0.014 180.72);
|
|
--color-warning: oklch(66% 0.179 58.318);
|
|
--color-warning-content: oklch(98% 0.022 95.277);
|
|
--color-error: oklch(58% 0.253 17.585);
|
|
--color-error-content: oklch(96% 0.015 12.422);
|
|
--radius-selector: 0.5rem;
|
|
--radius-field: 0.5rem;
|
|
--radius-box: 0.75rem;
|
|
--size-selector: 0.21875rem;
|
|
--size-field: 0.21875rem;
|
|
--border: 1px;
|
|
--depth: 0;
|
|
--noise: 0;
|
|
}
|
|
|
|
@plugin "../vendor/daisyui-theme" {
|
|
name: "light";
|
|
default: false;
|
|
prefersdark: false;
|
|
color-scheme: "light";
|
|
--color-base-100: oklch(97% 0.003 270);
|
|
--color-base-200: oklch(93% 0.005 270);
|
|
--color-base-300: oklch(88% 0.007 270);
|
|
--color-base-content: oklch(12% 0.008 270);
|
|
--color-primary: oklch(58% 0.21 278);
|
|
--color-primary-content: oklch(98% 0.01 278);
|
|
--color-secondary: oklch(52% 0.18 278);
|
|
--color-secondary-content: oklch(98% 0.01 278);
|
|
--color-accent: oklch(68% 0.17 278);
|
|
--color-accent-content: oklch(98% 0.01 278);
|
|
--color-neutral: oklch(88% 0.007 270);
|
|
--color-neutral-content: oklch(12% 0.008 270);
|
|
--color-info: oklch(62% 0.214 259.815);
|
|
--color-info-content: oklch(97% 0.014 254.604);
|
|
--color-success: oklch(70% 0.14 182.503);
|
|
--color-success-content: oklch(98% 0.014 180.72);
|
|
--color-warning: oklch(66% 0.179 58.318);
|
|
--color-warning-content: oklch(98% 0.022 95.277);
|
|
--color-error: oklch(58% 0.253 17.585);
|
|
--color-error-content: oklch(96% 0.015 12.422);
|
|
--radius-selector: 0.5rem;
|
|
--radius-field: 0.5rem;
|
|
--radius-box: 0.75rem;
|
|
--size-selector: 0.21875rem;
|
|
--size-field: 0.21875rem;
|
|
--border: 1px;
|
|
--depth: 0;
|
|
--noise: 0;
|
|
}
|
|
|
|
/* Add variants based on LiveView classes */
|
|
@custom-variant phx-click-loading (.phx-click-loading&, .phx-click-loading &);
|
|
@custom-variant phx-submit-loading (.phx-submit-loading&, .phx-submit-loading &);
|
|
@custom-variant phx-change-loading (.phx-change-loading&, .phx-change-loading &);
|
|
|
|
/* Use the data attribute for dark mode */
|
|
@custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *));
|
|
|
|
/* Make LiveView wrapper divs transparent for layout */
|
|
[data-phx-session], [data-phx-teleported-src] { display: contents }
|
|
|
|
/* ── Global base ── */
|
|
html, body {
|
|
font-family: 'Geist', system-ui, sans-serif;
|
|
}
|
|
|
|
/* ── Mixer design tokens — mapped to daisyUI so they track the active theme ── */
|
|
:root {
|
|
--mx-bg: var(--color-base-100);
|
|
--mx-surface: var(--color-base-200);
|
|
--mx-surface2: var(--color-base-300);
|
|
--mx-fg: var(--color-base-content);
|
|
--mx-accent: var(--color-primary);
|
|
--mx-accent2: var(--color-accent);
|
|
--mx-red: #ef4444;
|
|
--mx-green: #22c55e;
|
|
--mx-radius: 12px;
|
|
--mx-radius-sm: 8px;
|
|
}
|
|
|
|
[data-theme=dark] {
|
|
--mx-fg2: #9090a8;
|
|
--mx-muted: #5a5a72;
|
|
--mx-border: #1e1e26;
|
|
--mx-border2: #2a2a36;
|
|
}
|
|
|
|
[data-theme=light] {
|
|
--mx-fg2: #6060a0;
|
|
--mx-muted: #9090b8;
|
|
--mx-border: #d8d8e8;
|
|
--mx-border2: #c0c0d8;
|
|
}
|
|
|
|
/* ── Mixer app shell ── */
|
|
#app {
|
|
min-height: 100vh;
|
|
}
|
|
|
|
/* ── Layout ── */
|
|
.mx-root {
|
|
display: grid;
|
|
grid-template-columns: 240px 1fr 280px;
|
|
min-height: 100vh;
|
|
max-width: 1200px;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
@media (max-width: 960px) {
|
|
.mx-root { grid-template-columns: 64px 1fr; }
|
|
.mx-rightbar { display: none; }
|
|
}
|
|
@media (max-width: 640px) {
|
|
.mx-root { grid-template-columns: 1fr; }
|
|
.mx-sidebar { display: none; }
|
|
}
|
|
|
|
/* ── Sidebar ── */
|
|
.mx-sidebar {
|
|
position: sticky;
|
|
top: 0;
|
|
height: 100vh;
|
|
padding: 1.5rem 1rem;
|
|
display: flex;
|
|
flex-direction: column;
|
|
border-right: 1px solid var(--mx-border);
|
|
}
|
|
|
|
.mx-logo {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.625rem;
|
|
padding: 0.25rem 0.5rem;
|
|
margin-bottom: 2rem;
|
|
}
|
|
|
|
.mx-logo-icon {
|
|
font-size: 1.4rem;
|
|
color: var(--mx-accent2);
|
|
line-height: 1;
|
|
}
|
|
|
|
.mx-logo-text {
|
|
font-family: 'Instrument Serif', Georgia, serif;
|
|
font-size: 1.5rem;
|
|
font-style: italic;
|
|
color: var(--mx-fg);
|
|
letter-spacing: -0.02em;
|
|
}
|
|
|
|
.mx-nav { display: flex; flex-direction: column; gap: 0.25rem; }
|
|
|
|
.mx-nav-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.75rem;
|
|
padding: 0.625rem 0.75rem;
|
|
border-radius: var(--mx-radius-sm);
|
|
text-decoration: none;
|
|
color: var(--mx-fg2);
|
|
font-size: 0.9375rem;
|
|
font-weight: 500;
|
|
transition: color 0.15s, background 0.15s;
|
|
}
|
|
|
|
.mx-nav-item:hover { color: var(--mx-fg); background: var(--mx-surface2); }
|
|
.mx-nav-active { color: var(--mx-fg) !important; }
|
|
|
|
.mx-sidebar-footer {
|
|
margin-top: auto;
|
|
padding: 0.5rem;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
.mx-version {
|
|
font-family: 'DM Mono', monospace;
|
|
font-size: 0.7rem;
|
|
color: var(--mx-muted);
|
|
}
|
|
|
|
.mx-auth-link {
|
|
font-size: 0.75rem;
|
|
color: var(--mx-accent2);
|
|
text-decoration: none;
|
|
transition: color 0.15s;
|
|
}
|
|
.mx-auth-link:hover { color: var(--mx-fg); }
|
|
|
|
/* ── Main ── */
|
|
.mx-main {
|
|
border-right: 1px solid var(--mx-border);
|
|
min-height: 100vh;
|
|
}
|
|
|
|
.mx-header {
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 10;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 1rem 1.25rem;
|
|
background: color-mix(in oklch, var(--mx-bg) 85%, transparent);
|
|
backdrop-filter: blur(12px);
|
|
border-bottom: 1px solid var(--mx-border);
|
|
}
|
|
|
|
.mx-header-title {
|
|
font-family: 'Instrument Serif', Georgia, serif;
|
|
font-size: 1.25rem;
|
|
font-style: italic;
|
|
font-weight: 400;
|
|
color: var(--mx-fg);
|
|
letter-spacing: -0.02em;
|
|
}
|
|
|
|
.mx-refresh-btn {
|
|
background: none;
|
|
border: 1px solid var(--mx-border2);
|
|
color: var(--mx-fg2);
|
|
width: 32px;
|
|
height: 32px;
|
|
border-radius: 50%;
|
|
cursor: pointer;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
transition: color 0.15s, border-color 0.15s;
|
|
}
|
|
.mx-refresh-btn:hover { color: var(--mx-fg); border-color: var(--mx-accent); }
|
|
|
|
.mx-divider { height: 1px; background: var(--mx-border); }
|
|
|
|
/* ── Compose ── */
|
|
.mx-compose-wrapper { padding: 1rem 1.25rem; border-bottom: 1px solid var(--mx-border); }
|
|
|
|
.mx-compose {
|
|
display: flex;
|
|
gap: 0.75rem;
|
|
}
|
|
|
|
.mx-compose-avatar, .mx-tweet-avatar {
|
|
width: 38px;
|
|
height: 38px;
|
|
border-radius: 50%;
|
|
background: linear-gradient(135deg, var(--mx-accent) 0%, var(--mx-accent2) 100%);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 0.8rem;
|
|
font-weight: 600;
|
|
color: white;
|
|
flex-shrink: 0;
|
|
user-select: none;
|
|
}
|
|
|
|
.mx-compose-body { flex: 1; }
|
|
|
|
.mx-compose-textarea, .mx-edit-textarea {
|
|
width: 100%;
|
|
background: transparent;
|
|
border: none;
|
|
outline: none;
|
|
color: var(--mx-fg);
|
|
font-family: 'Geist', system-ui, sans-serif;
|
|
font-size: 1rem;
|
|
resize: none;
|
|
overflow: hidden;
|
|
line-height: 1.55;
|
|
padding: 0.375rem 0;
|
|
}
|
|
|
|
.mx-compose-textarea::placeholder { color: var(--mx-muted); }
|
|
|
|
.mx-compose-footer {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
margin-top: 0.5rem;
|
|
padding-top: 0.5rem;
|
|
border-top: 1px solid var(--mx-border);
|
|
}
|
|
|
|
.mx-compose-hint { font-size: 0.7rem; color: var(--mx-muted); font-family: 'DM Mono', monospace; }
|
|
|
|
.mx-compose-actions { display: flex; align-items: center; gap: 0.75rem; }
|
|
|
|
.mx-compose-error {
|
|
font-size: 0.75rem;
|
|
color: var(--mx-red);
|
|
margin-top: 0.25rem;
|
|
}
|
|
|
|
.mx-signin-cta {
|
|
padding: 1.25rem;
|
|
text-align: center;
|
|
border-bottom: 1px solid var(--mx-border);
|
|
}
|
|
|
|
.mx-signin-cta p {
|
|
font-size: 0.875rem;
|
|
color: var(--mx-fg2);
|
|
margin-bottom: 0.75rem;
|
|
}
|
|
|
|
.mx-btn-post, .mx-btn-save {
|
|
background: var(--mx-accent);
|
|
color: white;
|
|
border: none;
|
|
border-radius: 99px;
|
|
padding: 0.375rem 1rem;
|
|
font-size: 0.8125rem;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
transition: background 0.15s, opacity 0.15s;
|
|
font-family: inherit;
|
|
text-decoration: none;
|
|
}
|
|
.mx-btn-post:hover, .mx-btn-save:hover { background: var(--mx-accent2); }
|
|
.mx-btn-post:disabled, .mx-btn-save:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
|
|
.mx-btn-cancel {
|
|
background: none;
|
|
border: 1px solid var(--mx-border2);
|
|
color: var(--mx-fg2);
|
|
border-radius: 99px;
|
|
padding: 0.375rem 0.875rem;
|
|
font-size: 0.8125rem;
|
|
cursor: pointer;
|
|
transition: color 0.15s, border-color 0.15s;
|
|
font-family: inherit;
|
|
}
|
|
.mx-btn-cancel:hover { color: var(--mx-fg); border-color: var(--mx-fg2); }
|
|
|
|
/* ── Tweet Card ── */
|
|
.mx-tweet {
|
|
display: flex;
|
|
gap: 0.75rem;
|
|
padding: 1rem 1.25rem;
|
|
border-bottom: 1px solid var(--mx-border);
|
|
transition: background 0.1s;
|
|
animation: mx-fade-in 0.2s ease;
|
|
}
|
|
.mx-tweet:hover { background: color-mix(in oklch, var(--mx-fg) 2%, transparent); }
|
|
|
|
@keyframes mx-fade-in {
|
|
from { opacity: 0; transform: translateY(4px); }
|
|
to { opacity: 1; transform: translateY(0); }
|
|
}
|
|
|
|
.mx-tweet-body { flex: 1; min-width: 0; }
|
|
|
|
.mx-tweet-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.375rem;
|
|
margin-bottom: 0.375rem;
|
|
}
|
|
|
|
.mx-tweet-handle {
|
|
font-size: 0.875rem;
|
|
font-weight: 600;
|
|
color: var(--mx-fg);
|
|
}
|
|
|
|
.mx-tweet-dot, .mx-tweet-time {
|
|
font-size: 0.8rem;
|
|
color: var(--mx-muted);
|
|
}
|
|
|
|
.mx-tweet-actions {
|
|
margin-left: auto;
|
|
display: flex;
|
|
gap: 0.125rem;
|
|
opacity: 0;
|
|
transition: opacity 0.15s;
|
|
}
|
|
.mx-tweet:hover .mx-tweet-actions { opacity: 1; }
|
|
|
|
.mx-action-btn {
|
|
background: none;
|
|
border: none;
|
|
color: var(--mx-muted);
|
|
cursor: pointer;
|
|
width: 28px;
|
|
height: 28px;
|
|
border-radius: 50%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
transition: color 0.15s, background 0.15s;
|
|
}
|
|
.mx-action-btn:hover { color: var(--mx-fg); background: var(--mx-surface2); }
|
|
.mx-action-delete:hover { color: var(--mx-red); background: color-mix(in oklch, var(--mx-red) 10%, transparent); }
|
|
.mx-action-confirm { color: var(--mx-red) !important; background: color-mix(in oklch, var(--mx-red) 15%, transparent) !important; }
|
|
|
|
.mx-tweet-text {
|
|
font-size: 0.9375rem;
|
|
line-height: 1.6;
|
|
color: var(--mx-fg);
|
|
white-space: pre-wrap;
|
|
word-break: break-word;
|
|
}
|
|
|
|
/* ── Edit ── */
|
|
.mx-edit-area { margin-top: 0.25rem; }
|
|
|
|
.mx-edit-textarea {
|
|
border: 1px solid var(--mx-border2);
|
|
border-radius: var(--mx-radius-sm);
|
|
padding: 0.5rem 0.75rem;
|
|
background: var(--mx-surface2);
|
|
width: 100%;
|
|
overflow: auto;
|
|
}
|
|
.mx-edit-textarea:focus { border-color: var(--mx-accent); outline: none; }
|
|
|
|
.mx-edit-footer {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
gap: 0.5rem;
|
|
margin-top: 0.5rem;
|
|
}
|
|
|
|
/* ── Empty state ── */
|
|
.mx-empty {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
padding: 4rem 2rem;
|
|
text-align: center;
|
|
}
|
|
|
|
.mx-empty-icon {
|
|
font-size: 2.5rem;
|
|
color: var(--mx-muted);
|
|
margin-bottom: 1rem;
|
|
opacity: 0.5;
|
|
}
|
|
|
|
.mx-empty-title {
|
|
font-family: 'Instrument Serif', serif;
|
|
font-style: italic;
|
|
font-size: 1.25rem;
|
|
color: var(--mx-fg2);
|
|
margin-bottom: 0.375rem;
|
|
}
|
|
|
|
.mx-empty-sub { font-size: 0.875rem; color: var(--mx-muted); }
|
|
|
|
/* ── Spinner ── */
|
|
.mx-spinner {
|
|
width: 22px;
|
|
height: 22px;
|
|
border: 2px solid var(--mx-border2);
|
|
border-top-color: var(--mx-accent);
|
|
border-radius: 50%;
|
|
animation: mx-spin 0.7s linear infinite;
|
|
}
|
|
@keyframes mx-spin { to { transform: rotate(360deg); } }
|
|
|
|
/* ── Error banner ── */
|
|
.mx-error-banner {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
margin: 1rem 1.25rem;
|
|
padding: 0.75rem 1rem;
|
|
background: color-mix(in oklch, var(--mx-red) 8%, transparent);
|
|
border: 1px solid color-mix(in oklch, var(--mx-red) 25%, transparent);
|
|
border-radius: var(--mx-radius-sm);
|
|
color: color-mix(in oklch, var(--mx-red) 70%, white);
|
|
font-size: 0.875rem;
|
|
}
|
|
.mx-error-icon { font-size: 1rem; }
|
|
|
|
/* ── Right bar ── */
|
|
.mx-rightbar { padding: 1.25rem; }
|
|
|
|
.mx-info-card {
|
|
background: var(--mx-surface);
|
|
border: 1px solid var(--mx-border);
|
|
border-radius: var(--mx-radius);
|
|
padding: 1rem;
|
|
}
|
|
|
|
.mx-info-title {
|
|
font-size: 0.875rem;
|
|
font-weight: 600;
|
|
color: var(--mx-fg);
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
.mx-info-body {
|
|
font-size: 0.8125rem;
|
|
color: var(--mx-fg2);
|
|
line-height: 1.5;
|
|
margin-bottom: 0.875rem;
|
|
}
|
|
|
|
.mx-stack { display: flex; flex-wrap: wrap; gap: 0.375rem; }
|
|
|
|
.mx-tag {
|
|
font-family: 'DM Mono', monospace;
|
|
font-size: 0.65rem;
|
|
padding: 0.25rem 0.5rem;
|
|
border-radius: 4px;
|
|
background: var(--mx-surface2);
|
|
border: 1px solid var(--mx-border2);
|
|
color: var(--mx-accent2);
|
|
}
|