mirror of
https://github.com/jkingsman/Remote-Terminal-for-MeshCore.git
synced 2026-06-30 15:01:12 +02:00
Shard up frontend variables
This commit is contained in:
@@ -112,7 +112,7 @@ export function ChannelInfoPane({
|
||||
>
|
||||
{isFavorite(favorites, 'channel', channel.key) ? (
|
||||
<>
|
||||
<span className="text-amber-400 text-lg">★</span>
|
||||
<span className="text-favorite text-lg">★</span>
|
||||
<span>Remove from favorites</span>
|
||||
</>
|
||||
) : (
|
||||
|
||||
@@ -142,7 +142,7 @@ export function ChatHeader({
|
||||
}
|
||||
>
|
||||
{isFavorite(favorites, conversation.type as 'channel' | 'contact', conversation.id) ? (
|
||||
<span className="text-amber-400">★</span>
|
||||
<span className="text-favorite">★</span>
|
||||
) : (
|
||||
<span className="text-muted-foreground">☆</span>
|
||||
)}
|
||||
|
||||
@@ -197,7 +197,7 @@ export function ContactInfoPane({
|
||||
>
|
||||
{isFavorite(favorites, 'contact', contact.public_key) ? (
|
||||
<>
|
||||
<span className="text-amber-400 text-lg">★</span>
|
||||
<span className="text-favorite text-lg">★</span>
|
||||
<span>Remove from favorites</span>
|
||||
</>
|
||||
) : (
|
||||
|
||||
@@ -548,7 +548,7 @@ export function CrackerPanel({
|
||||
Pending: <span className="text-foreground font-medium">{pendingCount}</span>
|
||||
</span>
|
||||
<span className="text-muted-foreground">
|
||||
Cracked: <span className="text-green-400 font-medium">{crackedCount}</span>
|
||||
Cracked: <span className="text-success font-medium">{crackedCount}</span>
|
||||
</span>
|
||||
<span className="text-muted-foreground">
|
||||
Failed: <span className="text-destructive font-medium">{failedCount}</span>
|
||||
@@ -613,9 +613,9 @@ export function CrackerPanel({
|
||||
{crackedRooms.map((room, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="text-sm bg-green-950/30 border border-green-900/50 rounded px-2 py-1"
|
||||
className="text-sm bg-success/10 border border-success/20 rounded px-2 py-1"
|
||||
>
|
||||
<span className="text-green-400 font-medium">#{room.roomName}</span>
|
||||
<span className="text-success font-medium">#{room.roomName}</span>
|
||||
<span className="text-muted-foreground ml-2 text-xs">
|
||||
"{room.message.slice(0, 50)}
|
||||
{room.message.length > 50 ? '...' : ''}"
|
||||
|
||||
@@ -186,9 +186,9 @@ export const MessageInput = forwardRef<MessageInputHandle, MessageInputProps>(fu
|
||||
className={cn(
|
||||
'tabular-nums',
|
||||
limitState === 'error' || limitState === 'danger'
|
||||
? 'text-red-400 font-medium'
|
||||
? 'text-destructive font-medium'
|
||||
: limitState === 'warning'
|
||||
? 'text-yellow-500'
|
||||
? 'text-warning'
|
||||
: 'text-muted-foreground'
|
||||
)}
|
||||
>
|
||||
@@ -196,7 +196,7 @@ export const MessageInput = forwardRef<MessageInputHandle, MessageInputProps>(fu
|
||||
{remaining < 0 && ` (${remaining})`}
|
||||
</span>
|
||||
{warningMessage && (
|
||||
<span className={cn(limitState === 'error' ? 'text-red-400' : 'text-yellow-500')}>
|
||||
<span className={cn(limitState === 'error' ? 'text-destructive' : 'text-warning')}>
|
||||
— {warningMessage}
|
||||
</span>
|
||||
)}
|
||||
@@ -209,9 +209,9 @@ export const MessageInput = forwardRef<MessageInputHandle, MessageInputProps>(fu
|
||||
className={cn(
|
||||
'tabular-nums',
|
||||
limitState === 'error' || limitState === 'danger'
|
||||
? 'text-red-400 font-medium'
|
||||
? 'text-destructive font-medium'
|
||||
: limitState === 'warning'
|
||||
? 'text-yellow-500'
|
||||
? 'text-warning'
|
||||
: 'text-muted-foreground'
|
||||
)}
|
||||
>
|
||||
@@ -220,7 +220,7 @@ export const MessageInput = forwardRef<MessageInputHandle, MessageInputProps>(fu
|
||||
</span>
|
||||
)}
|
||||
{warningMessage && (
|
||||
<span className={cn(limitState === 'error' ? 'text-red-400' : 'text-yellow-500')}>
|
||||
<span className={cn(limitState === 'error' ? 'text-destructive' : 'text-warning')}>
|
||||
— {warningMessage}
|
||||
</span>
|
||||
)}
|
||||
|
||||
@@ -360,7 +360,7 @@ function HopNode({ hop, hopNumber, prevLocation }: HopNodeProps) {
|
||||
<div className="text-sm font-semibold">
|
||||
<span className="text-foreground/80">Hop {hopNumber}:</span>{' '}
|
||||
<span className="text-primary font-mono">{hop.prefix}</span>
|
||||
{isAmbiguous && <span className="text-yellow-500 ml-1 font-normal">(ambiguous)</span>}
|
||||
{isAmbiguous && <span className="text-warning ml-1 font-normal">(ambiguous)</span>}
|
||||
</div>
|
||||
|
||||
{isUnknown ? (
|
||||
|
||||
@@ -149,9 +149,9 @@ function decodePacketSummary(
|
||||
function getRouteTypeColor(routeType: string): string {
|
||||
switch (routeType) {
|
||||
case 'Flood':
|
||||
return 'bg-blue-500/20 text-blue-400';
|
||||
return 'bg-info/20 text-info';
|
||||
case 'Direct':
|
||||
return 'bg-green-500/20 text-green-400';
|
||||
return 'bg-success/20 text-success';
|
||||
case 'Transport Flood':
|
||||
return 'bg-purple-500/20 text-purple-400';
|
||||
case 'Transport Direct':
|
||||
|
||||
@@ -95,7 +95,7 @@ export function RepeaterDashboard({
|
||||
size="sm"
|
||||
onClick={loadAll}
|
||||
disabled={anyLoading}
|
||||
className="text-xs border-green-400 text-green-400 hover:bg-green-400/10 hover:text-green-400"
|
||||
className="text-xs border-success text-success hover:bg-success/10 hover:text-success"
|
||||
>
|
||||
{anyLoading ? 'Loading...' : 'Load All'}
|
||||
</Button>
|
||||
@@ -115,7 +115,7 @@ export function RepeaterDashboard({
|
||||
aria-label={isFav ? 'Remove from favorites' : 'Add to favorites'}
|
||||
>
|
||||
{isFav ? (
|
||||
<span className="text-amber-400">★</span>
|
||||
<span className="text-favorite">★</span>
|
||||
) : (
|
||||
<span className="text-muted-foreground">☆</span>
|
||||
)}
|
||||
|
||||
@@ -411,8 +411,8 @@ export function Sidebar({
|
||||
className={cn(
|
||||
'text-[10px] font-semibold px-1.5 py-0.5 rounded-full min-w-[18px] text-center',
|
||||
row.isMention
|
||||
? 'bg-destructive text-destructive-foreground'
|
||||
: 'bg-primary/90 text-primary-foreground'
|
||||
? 'bg-badge-mention text-badge-mention-foreground'
|
||||
: 'bg-badge-unread/90 text-badge-unread-foreground'
|
||||
)}
|
||||
aria-label={`${row.unreadCount} unread message${row.unreadCount !== 1 ? 's' : ''}`}
|
||||
>
|
||||
|
||||
@@ -76,8 +76,8 @@ export function StatusBar({
|
||||
className={cn(
|
||||
'w-2 h-2 rounded-full transition-colors',
|
||||
connected
|
||||
? 'bg-primary shadow-[0_0_6px_hsl(var(--primary)/0.5)]'
|
||||
: 'bg-muted-foreground'
|
||||
? 'bg-status-connected shadow-[0_0_6px_hsl(var(--status-connected)/0.5)]'
|
||||
: 'bg-status-disconnected'
|
||||
)}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
@@ -109,7 +109,7 @@ export function StatusBar({
|
||||
<button
|
||||
onClick={handleReconnect}
|
||||
disabled={reconnecting}
|
||||
className="px-3 py-1 bg-amber-500/10 border border-amber-500/20 text-amber-400 rounded-md text-xs cursor-pointer hover:bg-amber-500/15 transition-colors disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
||||
className="px-3 py-1 bg-warning/10 border border-warning/20 text-warning rounded-md text-xs cursor-pointer hover:bg-warning/15 transition-colors disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
||||
>
|
||||
{reconnecting ? 'Reconnecting...' : 'Reconnect'}
|
||||
</button>
|
||||
|
||||
@@ -15,9 +15,9 @@ export function AclPane({
|
||||
}) {
|
||||
const permColor: Record<number, string> = {
|
||||
0: 'bg-muted text-muted-foreground',
|
||||
1: 'bg-blue-500/10 text-blue-500',
|
||||
2: 'bg-green-400/10 text-green-400',
|
||||
3: 'bg-amber-500/10 text-amber-500',
|
||||
1: 'bg-info/10 text-info',
|
||||
2: 'bg-success/10 text-success',
|
||||
3: 'bg-warning/10 text-warning',
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -39,7 +39,7 @@ export function ConsolePane({
|
||||
</div>
|
||||
<div
|
||||
ref={outputRef}
|
||||
className="h-48 overflow-y-auto p-3 font-mono text-xs bg-black/50 text-green-400 space-y-1"
|
||||
className="h-48 overflow-y-auto p-3 font-mono text-xs bg-console-bg/50 text-console space-y-1"
|
||||
aria-live="polite"
|
||||
aria-relevant="additions"
|
||||
>
|
||||
@@ -48,11 +48,11 @@ export function ConsolePane({
|
||||
)}
|
||||
{history.map((entry, i) =>
|
||||
entry.outgoing ? (
|
||||
<div key={i} className="text-green-300">
|
||||
<div key={i} className="text-console-command">
|
||||
> {entry.command}
|
||||
</div>
|
||||
) : (
|
||||
<div key={i} className="text-green-400/80 whitespace-pre-wrap">
|
||||
<div key={i} className="text-console/80 whitespace-pre-wrap">
|
||||
{entry.response}
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -101,7 +101,7 @@ export function NeighborsPane({
|
||||
const dist = n.distance;
|
||||
const snrStr = n.snr >= 0 ? `+${n.snr.toFixed(1)}` : n.snr.toFixed(1);
|
||||
const snrColor =
|
||||
n.snr >= 6 ? 'text-green-400' : n.snr >= 0 ? 'text-yellow-500' : 'text-red-400';
|
||||
n.snr >= 6 ? 'text-success' : n.snr >= 0 ? 'text-warning' : 'text-destructive';
|
||||
return (
|
||||
<tr key={i} className="border-t border-border/50">
|
||||
<td className="py-1">{n.name || n.pubkey_prefix}</td>
|
||||
|
||||
@@ -66,7 +66,7 @@ export function RadioSettingsPane({
|
||||
<span
|
||||
className={cn(
|
||||
'ml-2 text-xs',
|
||||
clockDrift.isLarge ? 'text-red-400' : 'text-muted-foreground'
|
||||
clockDrift.isLarge ? 'text-destructive' : 'text-muted-foreground'
|
||||
)}
|
||||
>
|
||||
(drift: {clockDrift.text})
|
||||
@@ -88,7 +88,7 @@ export function RadioSettingsPane({
|
||||
'p-1 rounded transition-colors disabled:opacity-50',
|
||||
disabled || advertState.loading
|
||||
? 'text-muted-foreground'
|
||||
: 'text-green-500 hover:bg-accent hover:text-green-400'
|
||||
: 'text-success hover:bg-accent hover:text-success'
|
||||
)}
|
||||
title="Refresh Advert Intervals"
|
||||
>
|
||||
|
||||
@@ -112,7 +112,7 @@ export function RepeaterPane({
|
||||
'p-1 rounded transition-colors disabled:opacity-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',
|
||||
disabled || state.loading
|
||||
? 'text-muted-foreground'
|
||||
: 'text-green-500 hover:bg-accent hover:text-green-400'
|
||||
: 'text-success hover:bg-accent hover:text-success'
|
||||
)}
|
||||
title="Refresh"
|
||||
aria-label={`Refresh ${title}`}
|
||||
|
||||
@@ -151,23 +151,23 @@ export function SettingsBotSection({
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
<div className="p-3 bg-red-500/10 border border-red-500/30 rounded-md">
|
||||
<p className="text-sm text-red-400">
|
||||
<div className="p-3 bg-destructive/10 border border-destructive/30 rounded-md">
|
||||
<p className="text-sm text-destructive">
|
||||
<strong>Experimental:</strong> This is an alpha feature and introduces automated message
|
||||
sending to your radio; unexpected behavior may occur. Use with caution, and please report
|
||||
any bugs!
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="p-3 bg-yellow-500/10 border border-yellow-500/30 rounded-md">
|
||||
<p className="text-sm text-yellow-500">
|
||||
<div className="p-3 bg-warning/10 border border-warning/30 rounded-md">
|
||||
<p className="text-sm text-warning">
|
||||
<strong>Security Warning:</strong> This feature executes arbitrary Python code on the
|
||||
server. Only run trusted code, and be cautious of arbitrary usage of message parameters.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="p-3 bg-yellow-500/10 border border-yellow-500/30 rounded-md">
|
||||
<p className="text-sm text-yellow-500">
|
||||
<div className="p-3 bg-warning/10 border border-warning/30 rounded-md">
|
||||
<p className="text-sm text-warning">
|
||||
<strong>Don't wreck the mesh!</strong> Bots process ALL messages, including their
|
||||
own. Be careful of creating infinite loops!
|
||||
</p>
|
||||
@@ -286,7 +286,7 @@ export function SettingsBotSection({
|
||||
</div>
|
||||
<Suspense
|
||||
fallback={
|
||||
<div className="h-64 md:h-96 rounded-md border border-input bg-[#282c34] flex items-center justify-center text-muted-foreground">
|
||||
<div className="h-64 md:h-96 rounded-md border border-input bg-code-editor-bg flex items-center justify-center text-muted-foreground">
|
||||
Loading editor...
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -82,14 +82,14 @@ export function SettingsConnectivitySection({
|
||||
<Label>Connection</Label>
|
||||
{health?.connection_info ? (
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-2 h-2 rounded-full bg-green-500" />
|
||||
<div className="w-2 h-2 rounded-full bg-status-connected" />
|
||||
<code className="px-2 py-1 bg-muted rounded text-foreground text-sm">
|
||||
{health.connection_info}
|
||||
</code>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex items-center gap-2 text-muted-foreground">
|
||||
<div className="w-2 h-2 rounded-full bg-gray-500" />
|
||||
<div className="w-2 h-2 rounded-full bg-status-disconnected" />
|
||||
<span>Not connected</span>
|
||||
</div>
|
||||
)}
|
||||
@@ -123,7 +123,7 @@ export function SettingsConnectivitySection({
|
||||
variant="outline"
|
||||
onClick={handleReboot}
|
||||
disabled={rebooting || busy}
|
||||
className="w-full border-red-500/50 text-red-400 hover:bg-red-500/10"
|
||||
className="w-full border-destructive/50 text-destructive hover:bg-destructive/10"
|
||||
>
|
||||
{rebooting ? 'Rebooting...' : 'Reboot Radio'}
|
||||
</Button>
|
||||
|
||||
@@ -171,7 +171,7 @@ export function SettingsDatabaseSection({
|
||||
variant="outline"
|
||||
onClick={handleCleanup}
|
||||
disabled={cleaning}
|
||||
className="border-red-500/50 text-red-400 hover:bg-red-500/10"
|
||||
className="border-destructive/50 text-destructive hover:bg-destructive/10"
|
||||
>
|
||||
{cleaning ? 'Deleting...' : 'Permanently Delete'}
|
||||
</Button>
|
||||
@@ -194,7 +194,7 @@ export function SettingsDatabaseSection({
|
||||
variant="outline"
|
||||
onClick={handlePurgeDecryptedRawPackets}
|
||||
disabled={purgingDecryptedRaw}
|
||||
className="w-full border-yellow-500/50 text-yellow-400 hover:bg-yellow-500/10"
|
||||
className="w-full border-warning/50 text-warning hover:bg-warning/10"
|
||||
>
|
||||
{purgingDecryptedRaw ? 'Purging Archival Raw Packets...' : 'Purge Archival Raw Packets'}
|
||||
</Button>
|
||||
|
||||
@@ -175,7 +175,7 @@ export function SettingsIdentitySection({
|
||||
<Button
|
||||
onClick={handleAdvertise}
|
||||
disabled={advertising || !health?.radio_connected}
|
||||
className="w-full bg-yellow-600 hover:bg-yellow-700 text-white"
|
||||
className="w-full bg-warning hover:bg-warning/90 text-warning-foreground"
|
||||
>
|
||||
{advertising ? 'Sending...' : 'Send Advertisement'}
|
||||
</Button>
|
||||
|
||||
@@ -90,21 +90,21 @@ export function SettingsMqttSection({
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
<div className="rounded-md border border-yellow-600/50 bg-yellow-950/30 px-4 py-3 text-sm text-yellow-200">
|
||||
<div className="rounded-md border border-warning/50 bg-warning/10 px-4 py-3 text-sm text-warning">
|
||||
MQTT support is an experimental feature in open beta. All publishing uses QoS 0
|
||||
(at-most-once delivery). Please report any bugs on the{' '}
|
||||
<a
|
||||
href="https://github.com/jkingsman/Remote-Terminal-for-MeshCore/issues"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="underline hover:text-yellow-100"
|
||||
className="underline hover:text-warning-foreground"
|
||||
>
|
||||
GitHub issues page
|
||||
</a>
|
||||
.
|
||||
</div>
|
||||
|
||||
<div className="rounded-md border border-blue-600/50 bg-blue-950/30 px-4 py-3 text-sm text-blue-200">
|
||||
<div className="rounded-md border border-info/50 bg-info/10 px-4 py-3 text-sm text-info">
|
||||
Outgoing messages (DMs and group messages) will be reported to private MQTT brokers in
|
||||
decrypted/plaintext form. The raw outgoing packets will NOT be reported to any MQTT broker,
|
||||
private or community. This means that{' '}
|
||||
@@ -138,7 +138,7 @@ export function SettingsMqttSection({
|
||||
className={cn(
|
||||
'w-2 h-2 rounded-full transition-colors',
|
||||
health?.mqtt_status === 'connected'
|
||||
? 'bg-primary shadow-[0_0_6px_hsl(var(--primary)/0.5)]'
|
||||
? 'bg-status-connected shadow-[0_0_6px_hsl(var(--status-connected)/0.5)]'
|
||||
: 'bg-muted-foreground'
|
||||
)}
|
||||
/>
|
||||
@@ -323,7 +323,7 @@ export function SettingsMqttSection({
|
||||
className={cn(
|
||||
'w-2 h-2 rounded-full transition-colors',
|
||||
health?.community_mqtt_status === 'connected'
|
||||
? 'bg-primary shadow-[0_0_6px_hsl(var(--primary)/0.5)]'
|
||||
? 'bg-status-connected shadow-[0_0_6px_hsl(var(--status-connected)/0.5)]'
|
||||
: 'bg-muted-foreground'
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -88,12 +88,12 @@ export function SettingsStatisticsSection({ className }: { className?: string })
|
||||
<span className="font-medium">{stats.total_packets}</span>
|
||||
</div>
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-sm text-green-400">Decrypted</span>
|
||||
<span className="font-medium text-green-400">{stats.decrypted_packets}</span>
|
||||
<span className="text-sm text-success">Decrypted</span>
|
||||
<span className="font-medium text-success">{stats.decrypted_packets}</span>
|
||||
</div>
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-sm text-yellow-500">Undecrypted</span>
|
||||
<span className="font-medium text-yellow-500">{stats.undecrypted_packets}</span>
|
||||
<span className="text-sm text-warning">Undecrypted</span>
|
||||
<span className="font-medium text-warning">{stats.undecrypted_packets}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -21,7 +21,7 @@ const DialogOverlay = React.forwardRef<
|
||||
<DialogPrimitive.Overlay
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
|
||||
'fixed inset-0 z-50 bg-overlay/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -21,7 +21,7 @@ const SheetOverlay = React.forwardRef<
|
||||
>(({ className, ...props }, ref) => (
|
||||
<SheetPrimitive.Overlay
|
||||
className={cn(
|
||||
'fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
|
||||
'fixed inset-0 z-50 bg-overlay/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -16,7 +16,7 @@ const Toaster = ({ ...props }: ToasterProps) => {
|
||||
cancelButton: 'group-[.toast]:bg-muted group-[.toast]:text-muted-foreground',
|
||||
// Muted error style - dark red-tinted background with readable text
|
||||
error:
|
||||
'group-[.toaster]:bg-[#2a1a1a] group-[.toaster]:text-[#e8a0a0] group-[.toaster]:border-[#4a2a2a] [&_[data-description]]:text-[#e8b0b0]',
|
||||
'group-[.toaster]:bg-toast-error group-[.toaster]:text-toast-error-foreground group-[.toaster]:border-toast-error-border [&_[data-description]]:text-toast-error-foreground',
|
||||
},
|
||||
}}
|
||||
{...props}
|
||||
|
||||
+50
-9
@@ -28,6 +28,52 @@
|
||||
/* Semantic colors for specific contexts */
|
||||
--msg-outgoing: 152 30% 14%;
|
||||
--msg-incoming: 224 12% 15%;
|
||||
|
||||
/* Status indicator pips */
|
||||
--status-connected: 142 71% 45%;
|
||||
--status-disconnected: 220 9% 46%;
|
||||
|
||||
/* Semantic feedback colors */
|
||||
--warning: 38 92% 50%;
|
||||
--warning-foreground: 0 0% 100%;
|
||||
--success: 142 71% 45%;
|
||||
--success-foreground: 0 0% 100%;
|
||||
--info: 217 91% 60%;
|
||||
--info-foreground: 0 0% 100%;
|
||||
|
||||
/* Favorites */
|
||||
--favorite: 43 96% 56%;
|
||||
|
||||
/* Console / terminal */
|
||||
--console: 142 69% 58%;
|
||||
--console-command: 142 76% 73%;
|
||||
--console-bg: 0 0% 0%;
|
||||
|
||||
/* Unread badges */
|
||||
--badge-unread: var(--primary);
|
||||
--badge-unread-foreground: var(--primary-foreground);
|
||||
--badge-mention: var(--destructive);
|
||||
--badge-mention-foreground: var(--destructive-foreground);
|
||||
|
||||
/* Error toast */
|
||||
--toast-error: 0 30% 14%;
|
||||
--toast-error-foreground: 0 56% 77%;
|
||||
--toast-error-border: 0 27% 23%;
|
||||
|
||||
/* Code editor */
|
||||
--code-editor-bg: 220 13% 18%;
|
||||
|
||||
/* Overlay / backdrop */
|
||||
--overlay: 0 0% 0%;
|
||||
|
||||
/* Typography */
|
||||
--font-sans: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
--font-mono:
|
||||
ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, 'Liberation Mono', monospace;
|
||||
|
||||
/* Scrollbar */
|
||||
--scrollbar: 224 11% 22%;
|
||||
--scrollbar-hover: 224 11% 28%;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,12 +83,7 @@
|
||||
}
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
font-family:
|
||||
system-ui,
|
||||
-apple-system,
|
||||
BlinkMacSystemFont,
|
||||
'Segoe UI',
|
||||
sans-serif;
|
||||
font-family: var(--font-sans);
|
||||
font-size: 14px;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
@@ -58,17 +99,17 @@
|
||||
background: transparent;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: hsl(224 11% 22%);
|
||||
background: hsl(var(--scrollbar));
|
||||
border-radius: 3px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: hsl(224 11% 28%);
|
||||
background: hsl(var(--scrollbar-hover));
|
||||
}
|
||||
|
||||
/* Firefox scrollbar */
|
||||
* {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: hsl(224 11% 22%) transparent;
|
||||
scrollbar-color: hsl(var(--scrollbar)) transparent;
|
||||
}
|
||||
|
||||
/* Message highlight animation for jump-to-message */
|
||||
|
||||
@@ -43,6 +43,43 @@ export default {
|
||||
},
|
||||
"msg-outgoing": "hsl(var(--msg-outgoing))",
|
||||
"msg-incoming": "hsl(var(--msg-incoming))",
|
||||
"status-connected": "hsl(var(--status-connected))",
|
||||
"status-disconnected": "hsl(var(--status-disconnected))",
|
||||
warning: {
|
||||
DEFAULT: "hsl(var(--warning))",
|
||||
foreground: "hsl(var(--warning-foreground))",
|
||||
},
|
||||
success: {
|
||||
DEFAULT: "hsl(var(--success))",
|
||||
foreground: "hsl(var(--success-foreground))",
|
||||
},
|
||||
info: {
|
||||
DEFAULT: "hsl(var(--info))",
|
||||
foreground: "hsl(var(--info-foreground))",
|
||||
},
|
||||
favorite: "hsl(var(--favorite))",
|
||||
console: "hsl(var(--console))",
|
||||
"console-command": "hsl(var(--console-command))",
|
||||
"console-bg": "hsl(var(--console-bg))",
|
||||
"code-editor-bg": "hsl(var(--code-editor-bg))",
|
||||
overlay: "hsl(var(--overlay))",
|
||||
"badge-unread": {
|
||||
DEFAULT: "hsl(var(--badge-unread))",
|
||||
foreground: "hsl(var(--badge-unread-foreground))",
|
||||
},
|
||||
"badge-mention": {
|
||||
DEFAULT: "hsl(var(--badge-mention))",
|
||||
foreground: "hsl(var(--badge-mention-foreground))",
|
||||
},
|
||||
"toast-error": {
|
||||
DEFAULT: "hsl(var(--toast-error))",
|
||||
foreground: "hsl(var(--toast-error-foreground))",
|
||||
border: "hsl(var(--toast-error-border))",
|
||||
},
|
||||
},
|
||||
fontFamily: {
|
||||
sans: ["var(--font-sans)"],
|
||||
mono: ["var(--font-mono)"],
|
||||
},
|
||||
borderRadius: {
|
||||
lg: "var(--radius)",
|
||||
|
||||
Reference in New Issue
Block a user