diff --git a/.gitignore b/.gitignore index a5235ddc..e6f97cd1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ user*/ /dist /release +/release-satellite dist-electron/ backup_04.zip diff --git a/libs/castmate-core/package.json b/libs/castmate-core/package.json index a6be17a0..9f72f1ce 100644 --- a/libs/castmate-core/package.json +++ b/libs/castmate-core/package.json @@ -15,6 +15,7 @@ "devDependencies": { "@electron/rebuild": "^3.6.0", "@types/better-sqlite3": "^7.6.11", + "@types/cors": "^2.8.17", "@types/express": "^4.17.21", "@types/http-proxy": "^1.17.14", "@types/lodash": "^4.14.192", @@ -32,6 +33,7 @@ "better-sqlite3": "^11.1.2", "castmate-schema": "workspace:^", "chokidar": "^3.5.3", + "cors": "^2.8.5", "electron": "29.4.5", "electron-updater": "6.1.8", "express": "^4.18.2", diff --git a/libs/castmate-core/src/index.ts b/libs/castmate-core/src/index.ts index 140adb4a..69526f22 100644 --- a/libs/castmate-core/src/index.ts +++ b/libs/castmate-core/src/index.ts @@ -53,3 +53,7 @@ export * from "./info/info-manager" export * from "./util/time-utils" export * from "./viewer-data/viewer-data" + +export * from "./satellite/satellite-service" +export * from "./satellite/satellite-resource" +export * from "./satellite/satellite-media" diff --git a/libs/castmate-core/src/io/file-system.ts b/libs/castmate-core/src/io/file-system.ts index 417936fe..7d946ee0 100644 --- a/libs/castmate-core/src/io/file-system.ts +++ b/libs/castmate-core/src/io/file-system.ts @@ -67,6 +67,10 @@ export async function writeSecretYAML(data: T, ...paths: string[]) { } export async function initializeFileSystem() { + ipcMain.handle(`filesystem_getUserFolder`, () => { + return activeProjectDirectory + }) + ipcMain.handle(`filesystem_getFolderInput`, async (event: IpcMainInvokeEvent, existing: string | undefined) => { const window = BrowserWindow.fromWebContents(event.sender) diff --git a/libs/castmate-core/src/media/media-manager.ts b/libs/castmate-core/src/media/media-manager.ts index 2f7f04c0..9946f4a2 100644 --- a/libs/castmate-core/src/media/media-manager.ts +++ b/libs/castmate-core/src/media/media-manager.ts @@ -103,6 +103,26 @@ export const MediaManager = Service( await this.copyMedia(localPath, mediaPath) }) + defineIPCFunc("media", "validateRemoteMediaPath", async (mediaPath: string) => { + try { + const realFile = await fs.realpath(mediaPath) + + const tempFolder = await fs.realpath(app.getPath("temp")) + const mediaFolder = await fs.realpath(resolveProjectPath("./media")) + + if (realFile.indexOf(tempFolder) == 0) { + return realFile + } + if (realFile.indexOf(mediaFolder) == 0) { + return realFile + } + return undefined + } catch (err) { + //Special case, could be TTS generated file in the temp path + return undefined + } + }) + const router = express.Router() router.use(express.static(mediaPath)) WebService.getInstance().addRootRouter("/media/default", router) diff --git a/libs/castmate-core/src/plugins/plugin.ts b/libs/castmate-core/src/plugins/plugin.ts index 6fb7b4d5..e34c98b0 100644 --- a/libs/castmate-core/src/plugins/plugin.ts +++ b/libs/castmate-core/src/plugins/plugin.ts @@ -63,6 +63,27 @@ export function definePlugin(spec: PluginSpec, initter: () => void) { ) } +interface SatellitePluginSpec { + id: string + name: string + description?: string + icon?: string + color?: Color + version?: SemanticVersion +} + +export function defineSatellitePlugin(spec: SatellitePluginSpec, initter: () => void) { + return new Plugin( + { + icon: "mdi mdi-puzzle", + color: "#fefefe", + version: "0.0.0", + ...spec, + }, + initter + ) +} + export function defineRendererCallable any>(name: string, func: T) { if (!initingPlugin) throw new Error() diff --git a/libs/castmate-core/src/pubsub/pubsub-service.ts b/libs/castmate-core/src/pubsub/pubsub-service.ts index a6008220..ebe47580 100644 --- a/libs/castmate-core/src/pubsub/pubsub-service.ts +++ b/libs/castmate-core/src/pubsub/pubsub-service.ts @@ -10,8 +10,7 @@ import { ReactiveEffect, autoRerun } from "../reactivity/reactivity" const logger = usePluginLogger("pubsub") -const baseURL = "https://api.spellcast.gg/" - +const baseURL = import.meta.env.VITE_CASTMATE_URL /** * PubSubManager connects to the azure-pubsub allowing realtime events from the cloud. */ @@ -28,7 +27,7 @@ export const PubSubManager = Service( private onConnect = new EventList() private onBeforeDisconnect = new EventList() - constructor() {} + constructor(private mode: "satellite" | "castmate") {} setToken(token: string | undefined) { logger.log("Cloud PubSub Received Auth Token") @@ -93,7 +92,9 @@ export const PubSubManager = Service( logger.log("Starting Cloud PubSub Connection") this.connecting = true - const negotiationResp = await axios.get("/pubsub/negotiate", { + const negotiationUrl = this.mode == "castmate" ? "/pubsub/negotiate" : "/pubsub/satellite/negotiate" + + const negotiationResp = await axios.get(negotiationUrl, { baseURL, headers: { Authorization: `Bearer ${this.token}`, @@ -170,6 +171,7 @@ export const PubSubManager = Service( } private checkEvents() { + logger.log("Checking Pubsbu Events") if (this.onMessage.handlerCount == 0) { this.stop() } else { diff --git a/libs/castmate-core/src/resources/resource-registry.ts b/libs/castmate-core/src/resources/resource-registry.ts index 8f569761..18dbb0da 100644 --- a/libs/castmate-core/src/resources/resource-registry.ts +++ b/libs/castmate-core/src/resources/resource-registry.ts @@ -8,6 +8,7 @@ interface ResourceEntry { constructor: ResourceConstructor storage: ResourceStorage ipcFuncs: string[] + satelliteFuncs: string[] } export async function createResource(constructor: ResourceConstructor, ...args: any[]) { @@ -128,6 +129,7 @@ export const ResourceRegistry = Service( constructor, storage: constructor.storage, ipcFuncs: [], + satelliteFuncs: [] }) rendererAddResourceType(constructor.storage.name) @@ -155,6 +157,12 @@ export const ResourceRegistry = Service( resourceType.ipcFuncs.push(name as string) } + exposeSatelliteFunction(constructor: ResourceConstructor, name: keyof T) { + const resourceType = this.getResourceType(constructor.storage.name) + if (!resourceType) return + resourceType.satelliteFuncs.push(name as string) + } + getResourceType(typeName: string) { return this.resourceTypes.find((rt) => rt.typeName == typeName) as ResourceEntry } diff --git a/libs/castmate-core/src/satellite/satellite-media.ts b/libs/castmate-core/src/satellite/satellite-media.ts new file mode 100644 index 00000000..98fe88e8 --- /dev/null +++ b/libs/castmate-core/src/satellite/satellite-media.ts @@ -0,0 +1,76 @@ +import { Service } from "../util/service" +import { createDelayedResolver, DelayedResolver, hashString } from "castmate-schema" +import path from "path" +import { ensureDirectory, resolveProjectPath } from "../io/file-system" +import fs from "fs" +import { defineCallableIPC, defineIPCFunc } from "../util/electron" +import { usePluginLogger } from "../logging/logging" +import { SatelliteService } from "./satellite-service" +import { app } from "electron" + +function createCacheName(remoteId: string, mediaFile: string) { + const ext = path.extname(mediaFile) + const hash = hashString(`${remoteId}${mediaFile}`) + + return `media_${hash}${ext}` +} + +const rendererStartMediaRequest = defineCallableIPC<(mediaFile: string, cacheName: string, cacheFile: string) => any>( + "satellite", + "startMediaRequest" +) + +const logger = usePluginLogger("media-cache") + +export const SatelliteMedia = Service( + class { + private pendingRequests = new Map< + string, + { + resolver: DelayedResolver + } + >() + + constructor() {} + + async initialize() { + //await ensureDirectory(resolveProjectPath("mediaCache")) + + defineIPCFunc("satellite", "mediaRequestDone", (mediaFile: string, cacheName: string) => { + const request = this.pendingRequests.get(mediaFile) + if (!request) return + + const cachedFile = path.join(app.getPath("temp"), cacheName) + + if (!fs.existsSync(cachedFile)) request.resolver.reject(new Error("Media Failed Request")) + + request.resolver.resolve(cachedFile) + }) + } + + async getMediaFile(mediaFile: string) { + const connectionId = SatelliteService.getInstance().getCastMateConnection() + if (!connectionId) throw new Error("Not Connected") + const remoteId = SatelliteService.getInstance().getConnection(connectionId)?.remoteId + if (!remoteId) throw new Error("Not Connected") + + const cacheName = createCacheName(remoteId, mediaFile) + + const cachedFile = path.join(app.getPath("temp"), cacheName) + + if (fs.existsSync(cachedFile)) { + return cachedFile + } else { + logger.log("Media missing from cache, requesting...") + const resolver = createDelayedResolver() + this.pendingRequests.set(mediaFile, { + resolver, + }) + + rendererStartMediaRequest(mediaFile, cacheName, cachedFile) + + return await resolver.promise + } + } + } +) diff --git a/libs/castmate-core/src/satellite/satellite-resource.ts b/libs/castmate-core/src/satellite/satellite-resource.ts new file mode 100644 index 00000000..59928d61 --- /dev/null +++ b/libs/castmate-core/src/satellite/satellite-resource.ts @@ -0,0 +1,290 @@ +import { isAsyncFunction } from "util/types" +import { + Resource, + ResourceBase, + ResourceConstructor, + ResourceStorage, + ResourceStorageBase, +} from "../resources/resource" +import { SatelliteService } from "./satellite-service" +import { Service } from "../util/service" +import { nanoid } from "nanoid/non-secure" +import _pushUnique from "lodash/" +import { onLoad, onUnload } from "../plugins/plugin" +import { defineCallableIPC, defineIPCFunc } from "../util/electron" +import { ResourceRegistry } from "../resources/resource-registry" +import { usePluginLogger } from "../logging/logging" + +class TestResource extends Resource<{ blah: string }> { + static storage = new ResourceStorage("TestResource") + + async foo(bar: string) { + return 10 + } + + async blah() {} +} + +type KeysMatching = { [K in keyof T]-?: T[K] extends V ? K : never }[keyof T] + +type SatelliteResourceFunctionKeys> = KeysMatching< + Omit>, + (...args: any[]) => Promise +> + +export const SatelliteResourceSymbol = Symbol() + +export type SatelliteResourceConstructor = ResourceConstructor & { [SatelliteResourceSymbol]: any } + +interface RemoteSatelliteResourceSlot { + id: string + resourceType: string + resource: Resource + connections: Set + name: string +} + +interface SatelliteResourceSlotBinding { + id: string + resourceType: string + resource?: T + name: string +} + +//Local to Satellite redirects to actual Resource +interface SatelliteResourceSlotHandler { + satelliteConstructor: SatelliteResourceConstructor + rpcs: { + [rpcName: string]: (resource: T, ...args: any[]) => Promise + } +} + +const logger = usePluginLogger("satellite") + +export const SatelliteResources = Service( + class { + //Remote Satellite Resources represented in CastMate + private remoteSlots = new Map() + private slotHandlers = new Map() + private slotBindings = new Map() + + constructor(private mode: "castmate" | "satellite") { + if (mode == "castmate") { + SatelliteService.getInstance().registerRPC( + "satellite_resourceBind", + (connection: string, slotId: string) => { + logger.log("Remote Slot", slotId, "Bound on Connection", connection) + this.remoteSlots.get(slotId)?.connections.add(connection) + } + ) + + SatelliteService.getInstance().registerRPC( + "satellite_resourceUnbind", + (connection: string, slotId: string) => { + logger.log("Remote Slot", slotId, "Unbound on Connection", connection) + this.remoteSlots.get(slotId)?.connections.delete(connection) + } + ) + + SatelliteService.getInstance().onDisconnected.register((satelliteId) => { + for (const slot of this.remoteSlots.values()) { + slot.connections.delete(satelliteId) + } + }) + } else { + SatelliteService.getInstance().registerRPC( + "satellite_resourceRPC", + async (connection: string, slotId: string, name: string, ...args: any[]) => { + const binding = this.slotBindings.get(slotId) + if (!binding) return + const handler = this.slotHandlers.get(binding.resourceType) + if (!handler) return + if (!binding.resource) return + + logger.log("Received Satellite Resource RPC", slotId, name, ...args) + logger.log(" Calling On", binding.resource.config.name, binding.resource.id) + return await handler.rpcs[name](binding.resource, ...args) + } + ) + + defineIPCFunc("satellite", "createSlotBinding", (slotId: string, type: string, name: string) => { + this.createSlotBinding(slotId, type, name) + }) + + defineIPCFunc("satellite", "deleteSlotBinding", (slotId: string) => { + this.deleteSlotBinding(slotId) + }) + + defineIPCFunc( + "satellite", + "bindResourceSlot", + async (slotId: string, resourceId: string | undefined) => { + const slot = this.slotBindings.get(slotId) + + if (!slot) throw new Error("Unknown Slot!") + + const resourceType = ResourceRegistry.getInstance().getResourceType(slot.resourceType) + + if (resourceId) { + const resource = resourceType.storage.getById(resourceId) + + if (!resource) return + + await this.bindResourceSlot(slotId, resource) + } else { + await this.unbindResourceSlot(slotId) + } + } + ) + } + + defineIPCFunc("satellite", "getSatelliteResourceSlotHandlerTypes", async () => { + return [...this.slotHandlers.values()].map((sh) => { + return sh.satelliteConstructor.storage.name + }) + }) + } + + getResourceSlot(id: string) { + return this.remoteSlots.get(id) + } + + async enforceRemoteSlotName(slotId: string, name: string) { + const slot = this.remoteSlots.get(slotId) + if (!slot) return + if (slot.name == name) return + + slot.name = name + await slot.resource.applyConfig({ name }) + } + + async createRemoteResourceSlot(id: string, resourceType: string, name: string) { + if (this.mode != "castmate") throw new Error("This is CastMate side only") + const handler = this.getSlotHandler(resourceType) + + if (!handler) throw new Error("Creating Remote Slot for unknown Remote Resource") + + logger.log("Create Remote Slot", id, resourceType, name) + + const resource = new handler.satelliteConstructor() + resource._id = id + resource._config.name = name + + this.remoteSlots.set(id, { + id, + resource, + resourceType, + connections: new Set(), + name, + }) + + await handler.satelliteConstructor.storage.inject(resource) + + return id + } + + async deleteRemoteResourceSlot(id: string) { + if (this.mode != "castmate") throw new Error("This is CastMate side only") + + const slot = this.remoteSlots.get(id) + if (!slot) return + + logger.log("Delete Remote Slot", id, slot.resourceType, slot.name) + + const handler = this.getSlotHandler(slot.resourceType) + + await handler?.satelliteConstructor.storage.remove(id) + + this.remoteSlots.delete(id) + } + + async callResourceRPC(slotId: string, name: string, ...args: any[]) { + if (this.mode != "castmate") throw new Error("This is CastMate side only") + + const slot = this.remoteSlots.get(slotId) + if (!slot) return + + const promises = [...slot.connections].map((c) => + SatelliteService.getInstance().callSatelliteRPC(c, "satellite_resourceRPC", slotId, name, ...args) + ) + + const result = await Promise.allSettled(promises) + } + + registerSlotHandler( + constructor: T, + handler: SatelliteResourceSlotHandler> + ) { + this.slotHandlers.set(constructor.storage.name, handler) + } + + unregisterSlotHandler(constructor: T) { + this.slotHandlers.delete(constructor.storage.name) + } + + getSlotHandler(typeName: string) { + return this.slotHandlers.get(typeName) + } + + createSlotBinding(slotId: string, type: string, name: string) { + logger.log("Slot Binding Created", slotId, type, name) + this.slotBindings.set(slotId, { + id: slotId, + resourceType: type, + name, + }) + } + + deleteSlotBinding(slotId: string) { + logger.log("Slot Deleted", slotId) + this.slotBindings.delete(slotId) + } + + async bindResourceSlot(slotId: string, resource: T) { + if (this.mode != "satellite") throw new Error("This is satellite only") + + const slot = this.slotBindings.get(slotId) + + if (!slot) return + + slot.resource = resource + + const connnectionId = SatelliteService.getInstance().getCastMateConnection() + + if (connnectionId) { + logger.log("Binding", resource.config.name, resource.id, "to slot", slot.id, slot.name) + await SatelliteService.getInstance().callSatelliteRPC(connnectionId, "satellite_resourceBind", slotId) + } + } + + async unbindResourceSlot(slotId: string) { + if (this.mode != "satellite") throw new Error("This is satellite only") + + const slot = this.slotBindings.get(slotId) + + if (!slot) return + + slot.resource = undefined + + const connnectionId = SatelliteService.getInstance().getCastMateConnection() + + if (connnectionId) { + logger.log("Unbinding", slot.id, slot.name) + await SatelliteService.getInstance().callSatelliteRPC(connnectionId, "satellite_resourceUnbind", slotId) + } + } + } +) + +export function defineSatelliteResourceSlotHandler( + constructor: T, + handler: SatelliteResourceSlotHandler> +) { + onLoad(() => { + SatelliteResources.getInstance().registerSlotHandler(constructor, handler) + }) + + onUnload(() => { + SatelliteResources.getInstance().unregisterSlotHandler(constructor) + }) +} diff --git a/libs/castmate-core/src/satellite/satellite-service.ts b/libs/castmate-core/src/satellite/satellite-service.ts new file mode 100644 index 00000000..7c6e0b25 --- /dev/null +++ b/libs/castmate-core/src/satellite/satellite-service.ts @@ -0,0 +1,221 @@ +import { + SatelliteConnectionICECandidate, + SatelliteConnectionInfo, + SatelliteConnectionOption, + SatelliteConnectionRequest, + SatelliteConnectionResponse, + SatelliteConnectionService, +} from "castmate-schema" +import { defineCallableIPC, defineIPCFunc } from "../util/electron" +import { Service } from "../util/service" +import { PubSubManager } from "../pubsub/pubsub-service" +import { usePluginLogger } from "../logging/logging" +import { RPCHandler, RPCMessage } from "castmate-ws-rpc" +import { onLoad, onUnload } from "../plugins/plugin" +import { EventList } from "../util/events" +import { SatelliteResourceConstructor } from "./satellite-resource" +import { nanoid } from "nanoid/non-secure" +import { Resource } from "../resources/resource" + +//WebRTC connections are maintained out of the renderer process since no good node-webrtc libs exist + +const rendererSatelliteConnectionIceCandidate = defineCallableIPC<(candidate: SatelliteConnectionICECandidate) => any>( + "satellite", + "satelliteConnectionIceCandidate" +) +const rendererSatelliteConnectionRequest = defineCallableIPC<(request: SatelliteConnectionRequest) => any>( + "satellite", + "satelliteConnectionRequest" +) +const rendererSatelliteConnectionResponse = defineCallableIPC<(response: SatelliteConnectionResponse) => any>( + "satellite", + "satelliteConnectionResponse" +) + +const rendererSatelliteSetRTCOptions = defineCallableIPC<(response: SatelliteConnectionOption[]) => any>( + "satellite", + "setRTCConnectionOptions" +) + +const rendererSendRTCMessage = defineCallableIPC<(id: string, data: string) => any>("satellite", "sendRTCMessage") + +interface RendererRTCConnection { + id: string + + remoteService: SatelliteConnectionService + remoteId: string + type: string + typeId: string + + state: "connecting" | "connected" | "disconnected" +} + +const logger = usePluginLogger("satellite") +export const SatelliteService = Service( + class { + onConnection = new EventList<(satelliteId: string) => any>() + onDisconnected = new EventList<(satelliteId: string) => any>() + + private pubsubListening = false + + private pubsubMessageHandler: (plugin: string, event: string, data: object) => any + + private rtcConnections = new Map() + + getConnection(id: string) { + return this.rtcConnections.get(id) + } + + getCastMateConnection() { + if (this.mode == "castmate") throw new Error("This is for satellite only") + const connection = this.rtcConnections.keys().next() + return connection.done ? undefined : connection.value + } + + private rpcHandler = new RPCHandler() + + startListening() { + if (this.pubsubListening) return + logger.log("Starting Satellite Listening") + this.pubsubListening = true + + PubSubManager.getInstance().registerOnMessage(this.pubsubMessageHandler) + } + + stopListening() { + if (!this.pubsubListening) return + this.pubsubListening = false + + PubSubManager.getInstance().unregisterOnMessage(this.pubsubMessageHandler) + } + + async setRTCConnectionOptions(options: SatelliteConnectionOption[]) { + rendererSatelliteSetRTCOptions(options) + } + + constructor(private mode: "satellite" | "castmate") { + defineIPCFunc("satellite", "satelliteConnectionRequest", async (request: SatelliteConnectionRequest) => { + await PubSubManager.getInstance().send("satellite", "satelliteConnectionRequest", request) + }) + + defineIPCFunc("satellite", "satelliteConnectionResponse", async (response: SatelliteConnectionResponse) => { + await PubSubManager.getInstance().send("satellite", "satelliteConnectionResponse", response) + }) + + defineIPCFunc( + "satellite", + "satelliteConnectionIceCandidate", + async (candidate: SatelliteConnectionICECandidate) => { + await PubSubManager.getInstance().send("satellite", "satelliteConnectionIceCandidate", candidate) + } + ) + + this.pubsubMessageHandler = async (plugin, event, data) => { + if (plugin != "satellite") return + + if (event == "satelliteConnectionIceCandidate") { + rendererSatelliteConnectionIceCandidate(data as SatelliteConnectionICECandidate) + } else if (event == "satelliteConnectionRequest") { + if (this.mode == "satellite") return + rendererSatelliteConnectionRequest(data as SatelliteConnectionRequest) + } else if (event == "satelliteConnectionResponse") { + if (this.mode == "castmate") return + rendererSatelliteConnectionResponse(data as SatelliteConnectionResponse) + } + } + + defineIPCFunc("satellite", "onConnectionCreated", (connectionInfo: SatelliteConnectionInfo) => { + this.rtcConnections.set(connectionInfo.id, { ...connectionInfo, state: "connecting" }) + }) + + defineIPCFunc( + "satellite", + "onConnectionStateChange", + async (id: string, state: "connected" | "connecting" | "disconnected") => { + const connection = this.rtcConnections.get(id) + if (!connection) return + + const newlyConnected = state == "connected" && connection.state == "connecting" + connection.state = state + + if (newlyConnected) { + await this.onConnection.run(connection.id) + } + } + ) + + defineIPCFunc("satellite", "onConnectionDeleted", async (id: string) => { + if (this.rtcConnections.has(id)) { + await this.onDisconnected.run(id) + this.rtcConnections.delete(id) + } + }) + + defineIPCFunc("satellite", "onControlMessage", (id: string, data: object) => { + //TODO + try { + const connection = this.rtcConnections.get(id) + if (!connection) return + + this.rpcHandler.handleMessage( + data as RPCMessage, + (msg) => rendererSendRTCMessage(id, JSON.stringify(msg)), + id + ) + } catch (err) { + logger.error("CONTROL MESSAGE ERROR", err) + } + }) + } + + async callSatelliteRPC any>(id: string, name: string, ...args: Parameters) { + const connection = this.rtcConnections.get(id) + + if (!connection) return + + return (await this.rpcHandler.call( + name, + (msg) => rendererSendRTCMessage(id, JSON.stringify(msg)), + ...args + )) as ReturnType + } + + registerRPC any>(name: string, func: T) { + this.rpcHandler.handle(name, func) + } + + unregisterRPC(name: string) { + this.rpcHandler.unhandle(name) + } + } +) + +export function onSatelliteConnection(func: (satelliteId: string) => any) { + onLoad(() => { + SatelliteService.getInstance().onConnection.register(func) + }) + + onUnload(() => { + SatelliteService.getInstance().onConnection.unregister(func) + }) +} + +export function onSatelliteDisconnect(func: (satelliteId: string) => any) { + onLoad(() => { + SatelliteService.getInstance().onDisconnected.register(func) + }) + + onUnload(() => { + SatelliteService.getInstance().onDisconnected.unregister(func) + }) +} + +export function onSatelliteRPC any>(name: string, func: T) { + onLoad(() => { + SatelliteService.getInstance().registerRPC(name, func) + }) + + onUnload(() => { + SatelliteService.getInstance().unregisterRPC(name) + }) +} diff --git a/libs/castmate-core/src/system.ts b/libs/castmate-core/src/system.ts index 5a534e36..fb67e62c 100644 --- a/libs/castmate-core/src/system.ts +++ b/libs/castmate-core/src/system.ts @@ -21,6 +21,9 @@ import path from "path" import { InfoService } from "./info/info-manager" import { AnalyticsService } from "./analytics/analytics-manager" import { ViewerData } from "./viewer-data/viewer-data" +import { SatelliteService } from "./satellite/satellite-service" +import { SatelliteResources } from "./satellite/satellite-resource" +import { SatelliteMedia } from "./satellite/satellite-media" /* //This shit is dynamic and vite hates it. @@ -43,19 +46,21 @@ let setupComplete = false defineIPCFunc("castmate", "isSetupFinished", () => setupComplete) defineIPCFunc("castmate", "isInitialSetupFinished", () => initialSetupComplete) -export async function setupCastMateDirectories() { +export async function setupCastMateDirectories(userOverride?: string) { const unpackaged = !app.isPackaged const portable = process.env.PORTABLE_EXECUTABLE_FILE != null || process.argv.includes("--portable") - let directory = path.join(app.getPath("userData"), "user") + const userFolderName = userOverride ?? "user" + + let directory = path.join(app.getPath("userData"), userFolderName) const needsSession = unpackaged || portable if (portable) { directory = process.env.PORTABLE_EXECUTABLE_DIR - ? path.resolve(process.env.PORTABLE_EXECUTABLE_DIR, "user") - : "./user" + ? path.resolve(process.env.PORTABLE_EXECUTABLE_DIR, userFolderName) + : `./${userFolderName}` } else if (unpackaged) { - directory = "../../user" + directory = `../../${userFolderName}` } await setProjectDirectory(directory) @@ -87,7 +92,9 @@ export async function initializeCastMate() { PluginManager.initialize() setupMedia() ResourceRegistry.initialize() - PubSubManager.initialize() + PubSubManager.initialize("castmate") + SatelliteService.initialize("castmate") + SatelliteResources.initialize("castmate") SequenceResolvers.initialize() EmoteCache.initialize() setupStreamPlans() @@ -120,3 +127,51 @@ export async function finializeCastMateSetup() { setupComplete = true notifyRendererSetupFinished() } + +export async function initializeCastMateSatellite() { + globalLogger.log("Initing Castmate Satellite") + AnalyticsService.initialize() + await AnalyticsService.getInstance().initialize() + await ensureDirectory(resolveProjectPath("settings")) + await ensureDirectory(resolveProjectPath("secrets")) + await ensureDirectory(resolveProjectPath("state")) + await initializeFileSystem() + //InfoService.initialize() + //await InfoService.getInstance().checkInfo() + GenericLoginService.initialize() + //WebService.initialize() + PluginManager.initialize() + //setupMedia() + ResourceRegistry.initialize() + PubSubManager.initialize("satellite") + SatelliteService.initialize("satellite") + SatelliteResources.initialize("satellite") + SatelliteService.getInstance().startListening() + SatelliteMedia.initialize() + await SatelliteMedia.getInstance().initialize() + //SequenceResolvers.initialize() + //EmoteCache.initialize() + //setupStreamPlans() + //ViewerData.initialize() + //await ViewerData.getInstance().initialize() + + //How do we load plugins??? + //await loadPlugin("twitch") + + initialSetupComplete = true + notifyRendererInitialSetupFinished() +} + +export async function finializeCastMateSatelliteSetup() { + globalLogger.log("Finalizing Init") + //await setupProfiles() + //await finishSettingUpStreamPlans() + //await ActionQueue.initialize() + //ActionQueueManager.initialize() + //ProfileManager.initialize() + //await ProfileManager.getInstance().finishSetup() + //await EmoteCache.getInstance().initialize() + globalLogger.log("CastMate Init Complete") + setupComplete = true + notifyRendererSetupFinished() +} diff --git a/libs/castmate-core/src/templates/template.ts b/libs/castmate-core/src/templates/template.ts index bdedeabb..54bd37bb 100644 --- a/libs/castmate-core/src/templates/template.ts +++ b/libs/castmate-core/src/templates/template.ts @@ -1,4 +1,4 @@ -import { globalLogger } from "../logging/logging" +import { globalLogger, usePluginLogger } from "../logging/logging" import { isResourceConstructor } from "../resources/resource" import { isArray, isBoolean, isNumber, isObject, isString } from "../util/type-helpers" import { @@ -22,6 +22,7 @@ import { TemplateTypeByConstructor, Toggle, getTemplateRegionString, + getTimeRemaining, getTypeByConstructor, isTimer, isTimerStarted, @@ -32,6 +33,8 @@ import escapeRegExp from "lodash/escapeRegExp" const AsyncFunction = Object.getPrototypeOf(async function () {}).constructor +const logger = usePluginLogger("template") + export async function evaluateTemplate(template: string, data: object) { let contextObjs = { ...data } @@ -371,6 +374,8 @@ async function getRemoteTemplateIntermediate(data: any) { return undefined } + logger.log("") + return successfulSerializers[0].value } @@ -387,7 +392,7 @@ registerRemoteDataSerializer(async (data) => { return { type: "Timer", data: { - remainingTime: data.remainingTime, + remainingTime: getTimeRemaining(data), }, } } diff --git a/libs/castmate-core/src/util/service.ts b/libs/castmate-core/src/util/service.ts index d327a2ea..c2c9ac00 100644 --- a/libs/castmate-core/src/util/service.ts +++ b/libs/castmate-core/src/util/service.ts @@ -2,12 +2,12 @@ export function Service any>(con return class Service extends constructor { private static _instance: InstanceType - static initialize(): InstanceType { + static initialize(...args: ConstructorParameters): InstanceType { if (this._instance) { throw new Error("Service already inited") } - this._instance = new constructor() + this._instance = new constructor(...args) return this._instance } diff --git a/libs/castmate-core/src/webserver/internal-webserver.ts b/libs/castmate-core/src/webserver/internal-webserver.ts index 8b87e494..8873b226 100644 --- a/libs/castmate-core/src/webserver/internal-webserver.ts +++ b/libs/castmate-core/src/webserver/internal-webserver.ts @@ -11,6 +11,7 @@ import { RPCHandler, RPCMessage } from "castmate-ws-rpc" import { filterPromiseAll } from "castmate-schema" import HttpProxy from "http-proxy" import os from "os" +import cors from "cors" function closeHttpServer(httpServer: http.Server | undefined) { return new Promise((resolve, reject) => { @@ -62,6 +63,7 @@ export const WebService = Service( this.app = express() this.routes = express.Router() + this.routes.use(cors()) this.routes.use(express.urlencoded({ extended: false })) this.routes.use(express.json()) diff --git a/libs/castmate-dashboard-core/package.json b/libs/castmate-dashboard-core/package.json new file mode 100644 index 00000000..7514767b --- /dev/null +++ b/libs/castmate-dashboard-core/package.json @@ -0,0 +1,31 @@ +{ + "name": "castmate-dashboard-core", + "private": true, + "version": "0.0.1", + "type": "module", + "main": "src/dashboard-core-main.ts", + "devMain": "src/dashboard-core-main.ts", + "types": "./dist/types/dashboard-core-main.d.ts", + "scripts": { + "dev": "vite", + "build": "vue-tsc && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@vueuse/core": "*", + "castmate-plugin-dashboards-shared": "workspace:^", + "castmate-schema": "workspace:^", + "chromatism2": "*", + "nanoid": "^5.0.7", + "pinia": "^2.1.7", + "primevue": "3.53.0", + "vue": "^3.4.23" + }, + "devDependencies": { + "@vitejs/plugin-vue": "4.6.2", + "ts-toolbelt": "*", + "typescript": "*", + "vite": "^5.2.9", + "vue-tsc": "*" + } +} diff --git a/libs/castmate-dashboard-core/src/dashboard-bridge.ts b/libs/castmate-dashboard-core/src/dashboard-bridge.ts new file mode 100644 index 00000000..13360910 --- /dev/null +++ b/libs/castmate-dashboard-core/src/dashboard-bridge.ts @@ -0,0 +1,104 @@ +import { + ComputedRef, + MaybeRefOrGetter, + computed, + inject, + onBeforeUnmount, + onMounted, + ref, + toValue, + watch, + watchEffect, +} from "vue" +import { DashboardConfig, DashboardWidget } from "castmate-plugin-dashboards-shared" + +export interface CastMateBridgeImplementation { + acquireState(plugin: string, state: string): void + releaseState(plugin: string, state: string): void + state: { readonly value: Record> } + config: { readonly value: DashboardWidget } + registerRPC(id: string, func: (...args: any[]) => any): void + unregisterRPC(id: string): void + registerMessage(id: string, func: (...args: any[]) => any): void + unregisterMessage(id: string, func: (...args: any[]) => any): void + + callRPC(id: string, ...args: any[]): Promise +} + +export function useCastMateBridge(): CastMateBridgeImplementation { + return inject("castmate-bridge", { + acquireState(plugin, state) {}, + releaseState(plugin, state) {}, + state: { value: {} }, + config: computed(() => ({ + id: "error", + plugin: "error", + widget: "error", + name: "error", + size: { width: 0, height: 0 }, + position: { x: 0, y: 0 }, + config: {}, + visible: false, + locked: false, + })), + registerRPC(id, func) {}, + unregisterRPC(id) {}, + registerMessage(id, func) {}, + unregisterMessage(id) {}, + async callRPC(id, ...args) {}, + }) +} + +export function useCastMateState( + plugin: MaybeRefOrGetter, + state: MaybeRefOrGetter +): ComputedRef { + const bridge = useCastMateBridge() + + onMounted(() => { + //Acquire + watch( + () => ({ + p: toValue(plugin), + s: toValue(state), + }), + (newConfig, oldConfig) => { + if (oldConfig) { + bridge.releaseState(oldConfig.p, oldConfig.s) + } + + bridge.acquireState(newConfig.p, newConfig.s) + }, + { immediate: true, deep: true } + ) + }) + + onBeforeUnmount(() => { + bridge.releaseState(toValue(plugin), toValue(state)) + }) + + return computed(() => { + return bridge.state.value[toValue(plugin)]?.[toValue(state)] as T + }) +} + +export function handleDashboardRPC(id: string, func: (...args: any[]) => any) { + const bridge = useCastMateBridge() + + onMounted(() => { + bridge.registerRPC(id, func) + }) + + onBeforeUnmount(() => { + bridge.unregisterRPC(id) + }) +} + +export function useCallDashboardRPC any>(id: string) { + const bridge = useCastMateBridge() + + return async (...args: Parameters): Promise> => { + const result = await bridge.callRPC(id, ...args) + return result as ReturnType + } +} diff --git a/libs/castmate-dashboard-core/src/dashboard-core-main.ts b/libs/castmate-dashboard-core/src/dashboard-core-main.ts new file mode 100644 index 00000000..cfab7077 --- /dev/null +++ b/libs/castmate-dashboard-core/src/dashboard-core-main.ts @@ -0,0 +1,10 @@ +// export { default as MediaContainer } from "./components/MediaContainer.vue" +// export { default as Revealer } from "./components/Revealer.vue" +// export { default as TimedReveal } from "./components/TimedReveal.vue" + +export * from "./dashboard-editor-util" +// export * from "./util/media-util" +// export * from "./util/stylesheets" +// export * from "./util/animation-util" +export * from "./dashboard-widget-util" +export * from "./dashboard-bridge" diff --git a/libs/castmate-dashboard-core/src/dashboard-editor-util.ts b/libs/castmate-dashboard-core/src/dashboard-editor-util.ts new file mode 100644 index 00000000..175ab3dc --- /dev/null +++ b/libs/castmate-dashboard-core/src/dashboard-editor-util.ts @@ -0,0 +1,5 @@ +import { inject } from "vue" + +export function useIsEditor() { + return inject("isEditor", false) +} diff --git a/libs/castmate-dashboard-core/src/dashboard-widget-util.ts b/libs/castmate-dashboard-core/src/dashboard-widget-util.ts new file mode 100644 index 00000000..620fb280 --- /dev/null +++ b/libs/castmate-dashboard-core/src/dashboard-widget-util.ts @@ -0,0 +1,77 @@ +import { RemoteTemplateResolutionContext, SchemaObj, resolveRemoteTemplateSchema } from "castmate-schema" +import { + Component, + ComputedRef, + MaybeRefOrGetter, + Ref, + VueElement, + VueElementConstructor, + computed, + ref, + toValue, +} from "vue" +import { DashboardWidgetOptions } from "castmate-plugin-dashboards-shared" + +export function declareWidgetOptions(opts: DashboardWidgetOptions) { + return opts +} + +export type DashboardWidgetComponent = Component & { widget: DashboardWidgetOptions } + +export interface DashboardPluginOptions { + id: string + widgets: DashboardWidgetComponent[] +} + +export function definePluginDashboard(opts: { id: string; widgets: Component[] }) { + return opts as DashboardPluginOptions +} + +interface VueResolutionContext extends RemoteTemplateResolutionContext { + evalCounter: Ref + nextEval: number + timer?: NodeJS.Timeout +} + +export function useResolvedWidgetConfig( + config: MaybeRefOrGetter, + widget: MaybeRefOrGetter +) { + const context: VueResolutionContext = { + evalCounter: ref(0), + nextEval: Number.POSITIVE_INFINITY, + scheduleReEval(seconds: number) { + const now = Date.now() + const evalTime = now + seconds * 1000 + + if (evalTime < this.nextEval) { + if (this.timer) { + clearTimeout(this.timer) + } + this.nextEval = evalTime + + this.timer = setTimeout(() => { + this.timer = undefined + this.nextEval = Number.POSITIVE_INFINITY + this.evalCounter.value++ + }, evalTime - now) + } + }, + } + + return computed(() => { + const remoteConfig = toValue(config) + + if (remoteConfig == undefined) return undefined + + const widgetComp = toValue(widget) + + const schema = widgetComp?.widget?.config + + if (!schema) return undefined + + context.evalCounter.value + + return resolveRemoteTemplateSchema(remoteConfig, schema, context) + }) +} diff --git a/libs/castmate-dashboard-core/tsconfig.json b/libs/castmate-dashboard-core/tsconfig.json new file mode 100644 index 00000000..934d023d --- /dev/null +++ b/libs/castmate-dashboard-core/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "ES2022", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "Bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "preserve", + + /* Linting */ + "strict": true + // "noUnusedLocals": true, + // "noUnusedParameters": true, + // "noFallthroughCasesInSwitch": true + }, + "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/libs/castmate-dashboard-core/tsconfig.node.json b/libs/castmate-dashboard-core/tsconfig.node.json new file mode 100644 index 00000000..42872c59 --- /dev/null +++ b/libs/castmate-dashboard-core/tsconfig.node.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/libs/castmate-dashboard-core/vite.config.ts b/libs/castmate-dashboard-core/vite.config.ts new file mode 100644 index 00000000..643b5bde --- /dev/null +++ b/libs/castmate-dashboard-core/vite.config.ts @@ -0,0 +1,29 @@ +import { defineConfig } from "vite" +import vue from "@vitejs/plugin-vue" +import dts from "vite-plugin-dts" + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [ + vue(), + dts({ + insertTypesEntry: true, + }), + ], + build: { + cssCodeSplit: true, + lib: { + entry: "src/main.ts", + name: "castmate-ui-core", + }, + rollupOptions: { + external: ["vue"], + output: { + exports: "named", + globals: { + vue: "Vue", + }, + }, + }, + }, +}) diff --git a/libs/castmate-dashboard-widget-loader/package.json b/libs/castmate-dashboard-widget-loader/package.json new file mode 100644 index 00000000..ece0cddf --- /dev/null +++ b/libs/castmate-dashboard-widget-loader/package.json @@ -0,0 +1,32 @@ +{ + "name": "castmate-dashboard-widget-loader", + "private": true, + "version": "0.0.1", + "type": "module", + "main": "src/dashboard-widget-loader.ts", + "devMain": "src/dashboard-widget-loader.ts", + "types": "./dist/types/dashboard-widget-loader.d.ts", + "scripts": { + "dev": "vite", + "build": "vue-tsc && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@vueuse/core": "*", + "castmate-overlay-core": "workspace:^", + "castmate-schema": "workspace:^", + "chromatism2": "*", + "electron": "29.4.5", + "nanoid": "^5.0.7", + "pinia": "^2.1.7", + "primevue": "3.53.0", + "vue": "^3.4.23" + }, + "devDependencies": { + "@vitejs/plugin-vue": "4.6.2", + "ts-toolbelt": "*", + "typescript": "*", + "vite": "^5.2.9", + "vue-tsc": "*" + } +} diff --git a/libs/castmate-dashboard-widget-loader/src/dashboard-widget-loader.ts b/libs/castmate-dashboard-widget-loader/src/dashboard-widget-loader.ts new file mode 100644 index 00000000..543bcfd9 --- /dev/null +++ b/libs/castmate-dashboard-widget-loader/src/dashboard-widget-loader.ts @@ -0,0 +1,36 @@ +import { DashboardPluginOptions, DashboardWidgetComponent } from "castmate-dashboard-core" +import dashboardPlugin from "castmate-plugin-dashboards-dashboard" +import remotePlugin from "castmate-plugin-remote-dashboard" + +import { defineStore } from "pinia" +import { ref, computed, markRaw } from "vue" + +export interface DashboardWidgetInfo { + plugin: string + component: DashboardWidgetComponent +} + +export const useDashboardWidgets = defineStore("castmate-dashboard-widgets", () => { + const widgets = ref(new Map()) + + function loadPluginWidgets(opts: DashboardPluginOptions) { + for (const widget of opts.widgets) { + widgets.value.set(`${opts.id}.${widget.widget.id}`, { plugin: opts.id, component: markRaw(widget) }) + + console.log("Loading Dashboard Widget", opts.id, widget.widget.id, widget.widget.name) + } + } + + function getWidget(plugin: string, widget: string) { + return widgets.value.get(`${plugin}.${widget}`) + } + + return { loadPluginWidgets, getWidget, widgets: computed(() => [...widgets.value.values()]) } +}) + +export function loadDashboardWidgets() { + const widgets = useDashboardWidgets() + + widgets.loadPluginWidgets(dashboardPlugin) + widgets.loadPluginWidgets(remotePlugin) +} diff --git a/libs/castmate-dashboard-widget-loader/tsconfig.json b/libs/castmate-dashboard-widget-loader/tsconfig.json new file mode 100644 index 00000000..c159b17a --- /dev/null +++ b/libs/castmate-dashboard-widget-loader/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "target": "ES2022", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "Bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "preserve", + + /* Linting */ + "strict": true, + // "noUnusedLocals": true, + // "noUnusedParameters": true, + // "noFallthroughCasesInSwitch": true + "paths": { + "castmate-dashboard-core": ["../castmate-dashboard-core/src/dashboard-core-main.ts"], + "castmate-plugin-dashboards-dashboard": ["../../plugins/dashboards/dashboard/src/main.ts"], + "castmate-plugin-remote-dashboard": ["../../plugins/dashboards/dashboard/src/main.ts"] + // "castmate-plugin-random-overlays": ["../../plugins/random/overlay/src/main.ts"], + // "castmate-plugin-twitch-overlays": ["../../plugins/twitch/overlay/src/main.ts"] + } + }, + "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/libs/castmate-dashboard-widget-loader/tsconfig.node.json b/libs/castmate-dashboard-widget-loader/tsconfig.node.json new file mode 100644 index 00000000..42872c59 --- /dev/null +++ b/libs/castmate-dashboard-widget-loader/tsconfig.node.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/libs/castmate-dashboard-widget-loader/vite.config.ts b/libs/castmate-dashboard-widget-loader/vite.config.ts new file mode 100644 index 00000000..c058234c --- /dev/null +++ b/libs/castmate-dashboard-widget-loader/vite.config.ts @@ -0,0 +1,29 @@ +import { defineConfig } from "vite" +import vue from "@vitejs/plugin-vue" +import dts from "vite-plugin-dts" + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [ + vue(), + dts({ + insertTypesEntry: true, + }), + ], + build: { + cssCodeSplit: true, + lib: { + entry: "src/main.ts", + name: "castmate-widget-loader", + }, + rollupOptions: { + external: ["vue"], + output: { + exports: "named", + globals: { + vue: "Vue", + }, + }, + }, + }, +}) diff --git a/libs/castmate-overlay-core/package.json b/libs/castmate-overlay-core/package.json index 84db38b3..82193122 100644 --- a/libs/castmate-overlay-core/package.json +++ b/libs/castmate-overlay-core/package.json @@ -22,7 +22,7 @@ "vue": "^3.4.23" }, "devDependencies": { - "@vitejs/plugin-vue": "*", + "@vitejs/plugin-vue": "4.6.2", "ts-toolbelt": "*", "typescript": "*", "vite": "^5.2.9", diff --git a/libs/castmate-overlay-widget-loader/package.json b/libs/castmate-overlay-widget-loader/package.json index f665d0fa..b6da6472 100644 --- a/libs/castmate-overlay-widget-loader/package.json +++ b/libs/castmate-overlay-widget-loader/package.json @@ -26,7 +26,7 @@ "vue": "^3.4.23" }, "devDependencies": { - "@vitejs/plugin-vue": "*", + "@vitejs/plugin-vue": "4.6.2", "ts-toolbelt": "*", "typescript": "*", "vite": "^5.2.9", diff --git a/libs/castmate-schema/src/data/command.ts b/libs/castmate-schema/src/data/command.ts index 70e38407..7906c538 100644 --- a/libs/castmate-schema/src/data/command.ts +++ b/libs/castmate-schema/src/data/command.ts @@ -190,7 +190,7 @@ export async function matchAndParseCommand( command: Command ): Promise | undefined> { if (command.mode == "command") { - const commandLower = command.match.toLocaleLowerCase() + const commandLower = command.match.toLocaleLowerCase().trim() if (!message || !message.toLocaleLowerCase().startsWith(commandLower)) return undefined let parse: ParseContext = { index: commandLower.length } @@ -213,7 +213,9 @@ export async function matchAndParseCommand( return argValues } else if (command.mode == "string") { const regexp = new RegExp( - `${command.leftBoundary ? "\\b" : ""}${escapeRegExp(command.match)}${command.rightBoundary ? "\\b" : ""}`, + `${command.leftBoundary ? "\\b" : ""}${escapeRegExp(command.match.trim())}${ + command.rightBoundary ? "\\b" : "" + }`, "ig" ) if (message.match(regexp)) { diff --git a/libs/castmate-schema/src/index.ts b/libs/castmate-schema/src/index.ts index 33d0ecd2..62ce7c24 100644 --- a/libs/castmate-schema/src/index.ts +++ b/libs/castmate-schema/src/index.ts @@ -33,3 +33,5 @@ export * from "./util/object-helpers" export * from "./template/template-utils" export * from "./template/remote-templates" + +export * from "./satellite/satellite-types" diff --git a/libs/castmate-schema/src/satellite/satellite-types.ts b/libs/castmate-schema/src/satellite/satellite-types.ts new file mode 100644 index 00000000..018a8c95 --- /dev/null +++ b/libs/castmate-schema/src/satellite/satellite-types.ts @@ -0,0 +1,45 @@ +export type SatelliteConnectionService = "twitch" + +export interface SatelliteConnectionRequestConfig { + satelliteService: SatelliteConnectionService + satelliteId: string + castmateService: SatelliteConnectionService + castmateId: string + dashId: string +} + +export interface SatelliteConnectionRequest extends SatelliteConnectionRequestConfig { + sdp: RTCSessionDescriptionInit +} + +export interface SatelliteConnectionResponse extends SatelliteConnectionRequestConfig { + sdp: RTCSessionDescriptionInit +} + +export interface SatelliteConnectionICECandidate extends SatelliteConnectionRequestConfig { + side: "castmate" | "satellite" + candidate: RTCIceCandidateInit +} + +export interface SatelliteConnectionOption { + id: string + + remoteService: "twitch" + remoteUserId: string + remoteDisplayName: string + remoteDisplayIcon: string + + type: string + typeId: string + + name: string +} + +export interface SatelliteConnectionInfo { + id: string + + remoteService: SatelliteConnectionService + remoteId: string + type: string + typeId: string +} diff --git a/libs/castmate-schema/src/template/remote-templates.ts b/libs/castmate-schema/src/template/remote-templates.ts index 8c207913..417d3dd6 100644 --- a/libs/castmate-schema/src/template/remote-templates.ts +++ b/libs/castmate-schema/src/template/remote-templates.ts @@ -106,6 +106,8 @@ export function resolveRemoteTemplate( const deserializer = remoteDataDeserializers?.[segment.type] if (deserializer) { result += deserializer(segment, context) + } else { + console.error("MISSING REMOTE DESERIALIZER", segment.type) } } } diff --git a/libs/castmate-schema/src/util/type-helpers.ts b/libs/castmate-schema/src/util/type-helpers.ts index ec49e0b0..720ed20e 100644 --- a/libs/castmate-schema/src/util/type-helpers.ts +++ b/libs/castmate-schema/src/util/type-helpers.ts @@ -75,6 +75,21 @@ export function setByPath(object: ObjectType, path: s } } +export function hashString(str: string, seed = 0) { + let h1 = 0xdeadbeef ^ seed, + h2 = 0x41c6ce57 ^ seed + for (let i = 0, ch; i < str.length; i++) { + ch = str.charCodeAt(i) + h1 = Math.imul(h1 ^ ch, 2654435761) + h2 = Math.imul(h2 ^ ch, 1597334677) + } + h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) + h1 ^= Math.imul(h2 ^ (h2 >>> 13), 3266489909) + h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) + h2 ^= Math.imul(h1 ^ (h1 >>> 13), 3266489909) + return 4294967296 * (2097151 & h2) + (h1 >>> 0) +} + export type MaybePromise = T | Promise | PromiseLike export type MapToUnion = T[keyof T] diff --git a/libs/castmate-ui-core/package.json b/libs/castmate-ui-core/package.json index 386c096a..b217d23b 100644 --- a/libs/castmate-ui-core/package.json +++ b/libs/castmate-ui-core/package.json @@ -22,7 +22,7 @@ "vue": "^3.4.23" }, "devDependencies": { - "@vitejs/plugin-vue": "*", + "@vitejs/plugin-vue": "4.6.2", "ts-toolbelt": "*", "typescript": "*", "vite": "^5.2.9", diff --git a/libs/castmate-ui-core/src/components/drag/DocumentDataCollection.vue b/libs/castmate-ui-core/src/components/drag/DocumentDataCollection.vue index 569b34ba..49f2f3e4 100644 --- a/libs/castmate-ui-core/src/components/drag/DocumentDataCollection.vue +++ b/libs/castmate-ui-core/src/components/drag/DocumentDataCollection.vue @@ -439,6 +439,10 @@ function onPaste(ev: ClipboardEvent) { padding-bottom: 1rem; } +.drag-area:focus { + outline: none !important; +} + .draggable-item:not(:last-of-type) { margin-bottom: 0.5rem; } diff --git a/libs/castmate-ui-core/src/components/drag/GridDocumentDataCollection.vue b/libs/castmate-ui-core/src/components/drag/GridDocumentDataCollection.vue new file mode 100644 index 00000000..e971a8b6 --- /dev/null +++ b/libs/castmate-ui-core/src/components/drag/GridDocumentDataCollection.vue @@ -0,0 +1,527 @@ + + + + + diff --git a/libs/castmate-ui-core/src/components/drag/OrderedTemplateRefs.ts b/libs/castmate-ui-core/src/components/drag/OrderedTemplateRefs.ts index e1acc4c9..1a34541b 100644 --- a/libs/castmate-ui-core/src/components/drag/OrderedTemplateRefs.ts +++ b/libs/castmate-ui-core/src/components/drag/OrderedTemplateRefs.ts @@ -10,7 +10,7 @@ export function useOrderedRefs(items: MaybeRefOrGetter) { watch( () => toValue(items).length, (newLength) => { - console.log("New ordered length", newLength) + //console.log("New ordered length", newLength) orderedElements.value.length = newLength } ) @@ -19,7 +19,7 @@ export function useOrderedRefs(items: MaybeRefOrGetter) { const itemValues = toValue(items) if (index > itemValues.length) return if (elem == null) return - console.log("Set Elem", index, elem) + //console.log("Set Elem", index, elem) orderedElements.value[index] = elem as any } diff --git a/libs/castmate-ui-core/src/components/drag/RowWrapDocumentDataCollection.vue b/libs/castmate-ui-core/src/components/drag/RowWrapDocumentDataCollection.vue new file mode 100644 index 00000000..6aee8b28 --- /dev/null +++ b/libs/castmate-ui-core/src/components/drag/RowWrapDocumentDataCollection.vue @@ -0,0 +1,515 @@ + + + + + diff --git a/libs/castmate-ui-core/src/components/satellite/SatelliteResourceSlotBindingEdit.vue b/libs/castmate-ui-core/src/components/satellite/SatelliteResourceSlotBindingEdit.vue new file mode 100644 index 00000000..cbba7867 --- /dev/null +++ b/libs/castmate-ui-core/src/components/satellite/SatelliteResourceSlotBindingEdit.vue @@ -0,0 +1,29 @@ + + + diff --git a/libs/castmate-ui-core/src/main.ts b/libs/castmate-ui-core/src/main.ts index 557d8f34..540afdf3 100644 --- a/libs/castmate-ui-core/src/main.ts +++ b/libs/castmate-ui-core/src/main.ts @@ -6,6 +6,8 @@ export { default as DataView } from "./components/data/DataView.vue" export { default as ToggleInput } from "./components/data/inputs/ToggleInput.vue" export { default as ToggleSwitch } from "./components/data/base-components/ToggleSwitch.vue" export { default as DocumentDataCollection } from "./components/drag/DocumentDataCollection.vue" +export { default as GridDocumentDataCollection } from "./components/drag/GridDocumentDataCollection.vue" +export { default as RowWrapDocumentDataCollection } from "./components/drag/RowWrapDocumentDataCollection.vue" export { default as DraggableCollection } from "./components/drag/DraggableCollection.vue" export { default as ScrollingTabBody } from "./components/docking/ScrollingTabBody.vue" @@ -65,6 +67,8 @@ export { default as BooleanExpressionValueEdit } from "./components/data/base-co export { default as ViewerVariableSelector } from "./components/viewer-data/ViewerVariableSelector.vue" +export { default as SatelliteResourceSlotBindingEdit } from "./components/satellite/SatelliteResourceSlotBindingEdit.vue" + export * from "./components/data/DataInputTypes" export * from "./util/diff" @@ -77,6 +81,8 @@ export * from "./util/dragging" export * from "./util/selection" export * from "./util/arrays" export * from "./util/generic-login" +export * from "./util/init-store" +export * from "./util/events" export * from "./plugins/plugin-store" export * from "./project/project-store" @@ -91,6 +97,10 @@ export * from "./components/stream-plan/stream-plan-types" export * from "./viewer-data/viewer-data-store" +export * from "./satellite/satellite-connection" +export * from "./satellite/satellite-resources" +export * from "./satellite/satellite-media" + export * from "./util/panning" export * from "./util/electron" diff --git a/libs/castmate-ui-core/src/satellite/satellite-connection.ts b/libs/castmate-ui-core/src/satellite/satellite-connection.ts new file mode 100644 index 00000000..b2bb79b3 --- /dev/null +++ b/libs/castmate-ui-core/src/satellite/satellite-connection.ts @@ -0,0 +1,503 @@ +import { defineStore } from "pinia" +import { handleIpcMessage, useIpcCaller, usePluginStore } from "../main" +import { nanoid } from "nanoid/non-secure" +import { computed, markRaw, ref, reactive } from "vue" +import { EventList } from "../main" +import fs from "node:fs" + +import _groupBy from "lodash/groupBy" + +import { RPCHandler } from "castmate-ws-rpc" + +import { + SatelliteConnectionICECandidate, + SatelliteConnectionRequest, + SatelliteConnectionRequestConfig, + SatelliteConnectionResponse, + SatelliteConnectionService, + SatelliteConnectionOption, + SatelliteConnectionInfo, +} from "castmate-schema" + +//Look Here!: https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Signaling_and_video_calling#signaling_transaction_flow + +const googleStunServers = [ + { urls: "stun:stun.l.google.com:19302" }, + { urls: "stun:stun.l.google.com:5349" }, + { urls: "stun:stun1.l.google.com:3478" }, + { urls: "stun:stun1.l.google.com:5349" }, + { urls: "stun:stun2.l.google.com:19302" }, + { urls: "stun:stun2.l.google.com:5349" }, + { urls: "stun:stun3.l.google.com:3478" }, + { urls: "stun:stun3.l.google.com:5349" }, + { urls: "stun:stun4.l.google.com:19302" }, + { urls: "stun:stun4.l.google.com:5349" }, +] + +const meteredSTUN = [ + { + urls: "stun:stun.relay.metered.ca:80", + }, + { + urls: "turn:global.relay.metered.ca:80", + username: "f264fb62658e24373813a648", + credential: "LQL8adYy2okPQr46", + }, + { + urls: "turn:global.relay.metered.ca:80?transport=tcp", + username: "f264fb62658e24373813a648", + credential: "LQL8adYy2okPQr46", + }, + { + urls: "turn:global.relay.metered.ca:443", + username: "f264fb62658e24373813a648", + credential: "LQL8adYy2okPQr46", + }, + { + urls: "turns:global.relay.metered.ca:443?transport=tcp", + username: "f264fb62658e24373813a648", + credential: "LQL8adYy2okPQr46", + }, +] + +const satelliteConnectionRequest = useIpcCaller<(request: SatelliteConnectionRequest) => any>( + "satellite", + "satelliteConnectionRequest" +) +const satelliteConnectionResponse = useIpcCaller<(response: SatelliteConnectionResponse) => any>( + "satellite", + "satelliteConnectionResponse" +) +const satelliteConnectionIceCandidate = useIpcCaller<(candidate: SatelliteConnectionICECandidate) => any>( + "satellite", + "satelliteConnectionIceCandidate" +) + +type ConnectionState = "connected" | "connecting" | "disconnected" + +const satelliteOnCreated = useIpcCaller<(connectionInfo: SatelliteConnectionInfo) => any>( + "satellite", + "onConnectionCreated" +) +const satelliteOnStateChange = useIpcCaller<(id: string, state: ConnectionState) => any>( + "satellite", + "onConnectionStateChange" +) +const satelliteOnDeleted = useIpcCaller<(id: string) => any>("satellite", "onConnectionDeleted") +const satelliteOnControlMessage = useIpcCaller<(id: string, data: object) => any>("satellite", "onControlMessage") + +const triggerRefreshConnections = useIpcCaller<() => any>("dashboards", "refreshConnections") + +interface PendingMediaRequest { + channel?: RTCDataChannel + filename: string + cachename: string + fileStream: fs.WriteStream + onDone: (state: "success" | "error") => any +} + +class SatelliteConnection { + connection: RTCPeerConnection + id: string + state: ConnectionState = "connecting" + controlChannel?: RTCDataChannel + mediaRequests = new Map() + + constructor(public remoteService: SatelliteConnectionService, public remoteId: string, public dashId: string) { + this.id = nanoid() + this.connection = SatelliteConnection.createConnection() + } + + private static createConnection() { + const connection = markRaw( + new RTCPeerConnection({ + iceServers: [...googleStunServers, ...meteredSTUN], + }) + ) + + return connection + } + + async handleIceCandidate(candidate: SatelliteConnectionICECandidate) { + const candidateObj = new RTCIceCandidate(candidate.candidate) + + console.log("Receieved Ice Candidate", candidate) + await this.connection.addIceCandidate(candidateObj) + } + + async handleResponse(response: SatelliteConnectionResponse) { + const desc = new RTCSessionDescription(response.sdp) + + console.log("Receieved Connection Response", response) + await this.connection.setRemoteDescription(desc) + } +} + +export const useSatelliteConnection = defineStore("satellite-connection", () => { + const connections = ref(new Array()) + + const rtcConnectionOptions = ref(new Array()) + + const onConnection = new EventList<(satelliteId: string) => any>() + const onDisconnection = new EventList<(satelliteId: string) => any>() + const onMessage = new EventList<(satelliteId: string, data: object) => any>() + + const rpcs = new RPCHandler() + + const mode = ref<"satellite" | "castmate">("castmate") + + function getConnection(request: SatelliteConnectionRequestConfig) { + const service = mode.value == "castmate" ? request.satelliteService : request.castmateService + const id = mode.value == "castmate" ? request.satelliteId : request.castmateId + + return connections.value.find( + (c) => c.remoteId == id && c.remoteService == service && request.dashId == c.dashId + ) + } + + function getConnectionById(connectionId: string) { + return connections.value.find((c) => c.id == connectionId) + } + + async function refreshConnections() { + await triggerRefreshConnections() + } + + function createConnection(service: SatelliteConnectionService, remoteId: string, dashId: string) { + const self = reactive(new SatelliteConnection(service, remoteId, dashId)) + + const removeSelf = () => { + const idx = connections.value.findIndex( + (c) => c.remoteId == remoteId && c.remoteService == service && dashId == c.dashId + ) + + if (idx >= 0) connections.value.splice(idx, 1) + + satelliteOnDeleted(self.id) + onDisconnection.run(self.id) + } + + const sendState = () => { + satelliteOnStateChange(self.id, self.state) + } + + function checkIfFullyConnected() { + if (self.controlChannel && self.state != "connected") { + self.state = "connected" + onConnection.run(self.id) + sendState() + } + } + + self.connection.ondatachannel = (ev) => { + if (ev.channel.label == "controlChannel") { + self.controlChannel = markRaw(ev.channel) + self.controlChannel.onmessage = (ev) => { + try { + const data = JSON.parse(ev.data) + //console.log("REC RTC", data) + rpcs.handleMessage(data, (data) => self.controlChannel?.send(JSON.stringify(data)), self.id) + satelliteOnControlMessage(self.id, data) + onMessage.run(self.id, data) + } catch (err) { + console.error("ERROR", err) + } + } + + checkIfFullyConnected() + } else if (ev.channel.label.startsWith("media:")) { + //Media requests + const filename = ev.channel.label.substring(6) + + const request = self.mediaRequests.get(filename) + if (request) { + request.channel = ev.channel + + ev.channel.onmessage = (ev) => { + request.fileStream.write(new Uint8Array(ev.data as ArrayBuffer), (err) => {}) + } + + ev.channel.onerror = (ev) => { + request.onDone("error") + } + + ev.channel.onclose = (ev) => { + request.onDone("success") + } + } else { + ev.channel.close() + } + } + } + + connections.value.push(self) + + satelliteOnCreated({ + id: self.id, + remoteService: self.remoteService, + remoteId: self.remoteId, + type: "dashboard", + typeId: self.dashId, + }) + + self.connection.onconnectionstatechange = (ev) => { + switch (self.connection.connectionState) { + case "new": + case "connecting": + console.log("RTC Connection Connecting...") + break + case "connected": + console.log("RTC Connection Connected") + checkIfFullyConnected() + break + case "disconnected": + console.log("RTC Connection Disconnecting...") + self.state = "disconnected" + sendState() + break + case "closed": + console.log("RTC Connection Closed") + removeSelf() + + break + case "failed": + console.log("Error Connection State") + + self.state = "disconnected" + removeSelf() + + break + default: + console.log("Unknown Connection State") + break + } + } + + return self + } + + //Used by satellite app to request connection to dashboard + function startDashboardConnection(config: SatelliteConnectionRequestConfig) { + const self = createConnection(config.castmateService, config.castmateId, config.dashId) + + self.controlChannel = markRaw(self.connection.createDataChannel("controlChannel")) + self.controlChannel.onmessage = (ev) => { + try { + const data = JSON.parse(ev.data) + console.log("INC MSG", data) + satelliteOnControlMessage(self.id, data) + rpcs.handleMessage(data, (data) => self.controlChannel?.send(JSON.stringify(data)), self.id) + onMessage.run(self.id, data) + } catch (err) { + console.error("ERROR", err) + } + } + + self.connection.onicecandidate = async (ev) => { + if (!ev.candidate) return + + const candidateMsg: SatelliteConnectionICECandidate = { + ...config, + side: "satellite", + candidate: ev.candidate.toJSON(), + } + + console.log("Sending Ice Candidate to CastMate") + await satelliteConnectionIceCandidate(candidateMsg) + } + + self.connection.onnegotiationneeded = async (ev) => { + const offer = await self.connection.createOffer() + + await self.connection.setLocalDescription(offer) + + if (!self.connection.localDescription) return + + const connectionObj: SatelliteConnectionRequest = { + ...config, + sdp: self.connection.localDescription.toJSON(), + } + + console.log("Sending Connection Request to CastMate", connectionObj) + + //Request Connection from satellite to CastMate + satelliteConnectionRequest(connectionObj) + } + + return self + } + + //Handle incoming satellite connection request (As main CastMate, sent by satellite) + async function handleClientConnection(desc: SatelliteConnectionRequest) { + const self = createConnection(desc.satelliteService, desc.satelliteId, desc.dashId) + + const sessionDesc = new RTCSessionDescription(desc.sdp) + + //TODO: Check if permission! + + self.connection.onicecandidate = async (ev) => { + if (!ev.candidate) return + + const candidateMsg: SatelliteConnectionICECandidate = { + satelliteService: desc.satelliteService, + satelliteId: desc.satelliteId, + castmateService: desc.castmateService, + castmateId: desc.castmateId, + dashId: desc.dashId, + side: "castmate", + candidate: ev.candidate.toJSON(), + } + + console.log("Sending Ice Candidate to Satellite") + await satelliteConnectionIceCandidate(candidateMsg) + } + + await self.connection.setRemoteDescription(sessionDesc) + + const answer = await self.connection.createAnswer() + + await self.connection.setLocalDescription(answer) + + if (!self.connection.localDescription) return + + const resp: SatelliteConnectionResponse = { + satelliteService: desc.satelliteService, + satelliteId: desc.satelliteId, + castmateService: desc.castmateService, + castmateId: desc.castmateId, + dashId: desc.dashId, + sdp: self.connection.localDescription.toJSON(), + } + + console.log("Sending Connection Response to Satellite", resp) + await satelliteConnectionResponse(resp) + + return self + } + + async function initialize(initMode: "satellite" | "castmate") { + mode.value = initMode + + handleIpcMessage( + "satellite", + "satelliteConnectionRequest", + async (event, request: SatelliteConnectionRequest) => { + const connection = await handleClientConnection(request) + if (!connection) return + + connections.value.push(connection) + } + ) + + handleIpcMessage( + "satellite", + "satelliteConnectionResponse", + async (event, response: SatelliteConnectionResponse) => { + const connection = getConnection(response) + + if (!connection) return + connection.handleResponse(response) + } + ) + + handleIpcMessage( + "satellite", + "satelliteConnectionIceCandidate", + async (event, candidate: SatelliteConnectionICECandidate) => { + const connection = getConnection(candidate) + connection?.handleIceCandidate(candidate) + } + ) + + handleIpcMessage( + "satellite", + "setRTCConnectionOptions", + async (event, options: SatelliteConnectionOption[]) => { + rtcConnectionOptions.value = options + } + ) + + handleIpcMessage("satellite", "newRTCConnectionOption", async (event, option: SatelliteConnectionOption) => { + rtcConnectionOptions.value.push(option) + }) + + handleIpcMessage("satellite", "removeRTCConnectionOption", async (event, optionId: string) => { + const idx = rtcConnectionOptions.value.findIndex((o) => (o.id = optionId)) + if (idx < 0) return + rtcConnectionOptions.value.splice(idx, 1) + }) + + /// + + handleIpcMessage("satellite", "sendRTCMessage", async (event, id: string, data: string) => { + const connection = connections.value.find((c) => c.id == id) + if (!connection?.controlChannel) throw new Error("Tried to Send without Control Channel") + console.log("SEND RTC", connection?.controlChannel, id, data) + connection?.controlChannel?.send(data) + }) + } + + async function connectToCastMate(request: SatelliteConnectionRequestConfig) { + const connection = startDashboardConnection(request) + } + + function registerRPCHandler any>(name: string, func: T) { + //console.log("Registering UI RPC", name) + rpcs.handle(name, func) + } + + function unregisterRPCHandler(name: string) { + rpcs.unhandle(name) + } + + function callRPC(connectionId: string, name: string, ...args: any[]) { + return rpcs.call( + name, + (data) => getConnectionById(connectionId)?.controlChannel?.send(JSON.stringify(data)), + ...args + ) + } + + return { + initialize, + connectToCastMate, + connections, + getConnectionById, + rtcConnectionOptions, + refreshConnections, + onMessage, + onConnection, + onDisconnection, + registerRPCHandler, + unregisterRPCHandler, + callRPC, + } +}) + +export function useGroupedDashboardRTCConnectionOptions() { + const satelliteStore = useSatelliteConnection() + + return computed(() => { + const groups = _groupBy(satelliteStore.rtcConnectionOptions, "remoteUserId") + return Object.values(groups) + }) +} + +export function usePrimarySatelliteConnection() { + const satelliteStore = useSatelliteConnection() + + return computed(() => { + if (satelliteStore.connections.length == 0) return undefined + return satelliteStore.connections[0] + }) +} + +export function useOnSatelliteMessage(func: (satelliteId: string, data: object) => any) { + const satelliteStore = useSatelliteConnection() + satelliteStore.onMessage.register(func) +} + +export function useSatelliteRPC(name: string, func: (satelliteId: string, ...args: any[]) => any) { + const satelliteStore = useSatelliteConnection() + satelliteStore.registerRPCHandler(name, func) +} diff --git a/libs/castmate-ui-core/src/satellite/satellite-media.ts b/libs/castmate-ui-core/src/satellite/satellite-media.ts new file mode 100644 index 00000000..c8c345cf --- /dev/null +++ b/libs/castmate-ui-core/src/satellite/satellite-media.ts @@ -0,0 +1,127 @@ +import { defineStore } from "pinia" +import { usePrimarySatelliteConnection, useSatelliteConnection } from "./satellite-connection" +import fs from "node:fs" +import path from "path" +import { hashString } from "castmate-schema" +import { handleIpcMessage, useIpcCaller } from "../main" +import { markRaw, ref } from "vue" + +///https://github.com/bryc/code/blob/master/jshash/experimental/cyrb53.js + +const mainGetUserFolder = useIpcCaller<() => string>("filesystem", "getUserFolder") +const mainValidateRemoteMediaPath = useIpcCaller<(mediaFile: string) => string | undefined>( + "media", + "validateRemoteMediaPath" +) +const mainMediaRequestDone = useIpcCaller<(mediaFile: string, cacheName: string) => boolean>( + "satellite", + "mediaRequestDone" +) + +export const useSatelliteMedia = defineStore("satellite-media", () => { + const satelliteStore = useSatelliteConnection() + const primaryConnection = usePrimarySatelliteConnection() + + const mode = ref<"castmate" | "satellite">("castmate") + + async function initialize(initMode: "satellite" | "castmate") { + mode.value = initMode + + handleIpcMessage( + "satellite", + "startMediaRequest", + (event, mediaFile: string, cacheName: string, cacheFile: string) => { + startMediaRequest(mediaFile, cacheName, cacheFile) + } + ) + + if (initMode == "castmate") { + satelliteStore.registerRPCHandler( + "satellite_requestMedia", + async (connectionId: string, mediaFile: string) => { + console.log("Handle Remote Media Request", mediaFile) + const localPath = await mainValidateRemoteMediaPath(mediaFile) + + if (!localPath) return false + + const connection = satelliteStore.getConnectionById(connectionId) + if (!connection) return false + + const channel = connection.connection.createDataChannel(`media:${mediaFile}`) + channel.binaryType = "arraybuffer" + + const readStream = fs.createReadStream(localPath) + readStream.on("data", (chunk) => { + if (typeof chunk == "string") { + channel.send(chunk) + } else { + channel.send(chunk.buffer) + } + }) + + readStream.on("end", () => { + console.log("Sent all media data for", mediaFile) + channel.close() + }) + + readStream.on("error", () => { + channel.close() + }) + + return true + } + ) + } + } + + function createCacheName(remoteId: string, mediaFile: string) { + const ext = path.extname(mediaFile) + const hash = hashString(`${remoteId}${mediaFile}`) + + return `media_${hash}${ext}` + } + + async function startMediaRequest(mediaFile: string, cacheName: string, cacheFile: string) { + const userFolder = await mainGetUserFolder() + + if (!primaryConnection.value) throw new Error("Need connection to request media") + + console.log("Starting Media Request", mediaFile) + + const fileStream = markRaw(fs.createWriteStream(cacheFile)) + + primaryConnection.value.mediaRequests.set(mediaFile, { + filename: mediaFile, + cachename: cacheName, + fileStream, + onDone: markRaw((state) => { + fileStream.end() + fileStream.close() + primaryConnection.value?.mediaRequests.delete(mediaFile) + + if (state == "error") { + try { + fs.unlinkSync(cacheFile) + } catch {} + } + + mainMediaRequestDone(mediaFile, cacheName) + }), + }) + + try { + const success = await satelliteStore.callRPC( + primaryConnection.value.id, + "satellite_requestMedia", + mediaFile + ) + if (!success) { + primaryConnection.value.mediaRequests.get(mediaFile)?.onDone("error") + } + } catch (err) { + primaryConnection.value.mediaRequests.get(mediaFile)?.onDone("error") + } + } + + return { startMediaRequest, initialize } +}) diff --git a/libs/castmate-ui-core/src/satellite/satellite-resources.ts b/libs/castmate-ui-core/src/satellite/satellite-resources.ts new file mode 100644 index 00000000..c2d7e816 --- /dev/null +++ b/libs/castmate-ui-core/src/satellite/satellite-resources.ts @@ -0,0 +1,93 @@ +import { defineStore } from "pinia" +import { useIpcCaller } from "../main" +import { computed, MaybeRefOrGetter, ref, toValue } from "vue" + +const mainCreateSlotBinding = useIpcCaller<(slotId: string, type: string, name: string) => any>( + "satellite", + "createSlotBinding" +) +const mainDeleteSlotBinding = useIpcCaller<(slotId: string) => any>("satellite", "deleteSlotBinding") +const mainBindResourceSlot = useIpcCaller<(slotId: string, resourceId: string | undefined) => any>( + "satellite", + "bindResourceSlot" +) + +const mainGetSatelliteResourceSlotHandlerTypes = useIpcCaller<() => string[]>( + "satellite", + "getSatelliteResourceSlotHandlerTypes" +) + +interface ResourceSlotBinding { + id: string + name: string + resourceType: string + resourceId?: string +} + +export const useSatelliteResourceStore = defineStore("satellite-resource-store", () => { + const slotBindings = ref(new Map()) + + const slotHandlerTypes = ref(new Array()) + + async function initialize() { + slotHandlerTypes.value = await mainGetSatelliteResourceSlotHandlerTypes() + console.log("HANDLER TYPES", slotHandlerTypes.value) + } + + async function createSlotBinding(slotId: string, type: string, name: string) { + await mainCreateSlotBinding(slotId, type, name) + slotBindings.value.set(slotId, { + name, + id: slotId, + resourceType: type, + }) + } + + async function deleteSlotBinding(slotId: string) { + await mainDeleteSlotBinding(slotId) + slotBindings.value.delete(slotId) + } + + async function bindResourceToSlot(slotId: string, resourceId: string | undefined) { + console.log("BINDING!") + await mainBindResourceSlot(slotId, resourceId) + console.log("DONE BINDING") + const binding = slotBindings.value.get(slotId) + if (binding) { + console.log("Setting Resource ID!", resourceId) + binding.resourceId = resourceId + } else { + console.error("MISSING SLOT!", slotId, [...slotBindings.value.keys()]) + } + } + + return { + slotBindings: computed(() => slotBindings.value), + createSlotBinding, + deleteSlotBinding, + bindResourceToSlot, + slotHandlerTypes: computed(() => slotHandlerTypes.value), + initialize, + } +}) + +export function useResourceSlotBinding(slotId: MaybeRefOrGetter) { + const store = useSatelliteResourceStore() + + return computed(() => { + return store.slotBindings.get(toValue(slotId)) + }) +} + +export function useResourceSlotBindingModel(slotId: MaybeRefOrGetter) { + const store = useSatelliteResourceStore() + + return computed({ + get() { + return store.slotBindings.get(toValue(slotId))?.resourceId + }, + set(v) { + store.bindResourceToSlot(toValue(slotId), v) + }, + }) +} diff --git a/libs/castmate-ui-core/src/util/document.ts b/libs/castmate-ui-core/src/util/document.ts index b211b4cd..52afeeb4 100644 --- a/libs/castmate-ui-core/src/util/document.ts +++ b/libs/castmate-ui-core/src/util/document.ts @@ -156,6 +156,27 @@ export function provideDocument(id: MaybeRefOrGetter) { ) } +export function useCompleteDocumentSelection() { + const selection = inject>( + "documentSelection", + computed(() => { + return { + items: [], + container: "", + } + }) + ) + + return computed(() => { + return ( + selection.value ?? { + items: [], + container: "", + } + ) + }) +} + export function useSetDocumentSelection() { const selection = inject>("documentSelection") @@ -166,7 +187,15 @@ export function useSetDocumentSelection() { } export function useIsSelected(path: MaybeRefOrGetter, id: MaybeRefOrGetter) { - const selection = inject>("documentSelection") + const selection = inject>( + "documentSelection", + computed(() => { + return { + items: [], + container: "", + } + }) + ) return computed(() => { const selectionPath = toValue(path) diff --git a/libs/castmate-ui-core/src/util/events.ts b/libs/castmate-ui-core/src/util/events.ts new file mode 100644 index 00000000..b941788c --- /dev/null +++ b/libs/castmate-ui-core/src/util/events.ts @@ -0,0 +1,31 @@ +export class EventList any = () => any> { + private list: TFunc[] = [] + + get handlerCount() { + return this.list.length + } + + register(func: TFunc) { + this.list.push(func) + } + + unregister(func: TFunc) { + const idx = this.list.findIndex((li) => li == func) + if (idx >= 0) { + this.list.splice(idx, 1) + return true + } else { + return false + } + } + + async run(...args: Parameters) { + for (const f of this.list) { + try { + await f(...args) + } catch (err) { + console.error("ERROR w EVENT LIST:", err) + } + } + } +} diff --git a/packages/castmate/src/renderer/store/init-store.ts b/libs/castmate-ui-core/src/util/init-store.ts similarity index 96% rename from packages/castmate/src/renderer/store/init-store.ts rename to libs/castmate-ui-core/src/util/init-store.ts index f010ff2f..ddfe09b0 100644 --- a/packages/castmate/src/renderer/store/init-store.ts +++ b/libs/castmate-ui-core/src/util/init-store.ts @@ -1,5 +1,5 @@ import { createDelayedResolver } from "castmate-schema" -import { ipcInvoke } from "castmate-ui-core" +import { ipcInvoke } from "./electron" import { ipcRenderer } from "electron" import { defineStore } from "pinia" import { computed, ref, markRaw } from "vue" diff --git a/libs/castmate-ui-core/src/util/selection.ts b/libs/castmate-ui-core/src/util/selection.ts index f48dbce4..af85ff76 100644 --- a/libs/castmate-ui-core/src/util/selection.ts +++ b/libs/castmate-ui-core/src/util/selection.ts @@ -23,6 +23,7 @@ export interface SelectionState { from: ComputedRef to: ComputedRef cancelSelection: () => void + externalClickSelect: (ev: MouseEvent) => void } export function selectionOverlaps( @@ -44,6 +45,7 @@ export function injectSelectionState(): SelectionState { from: computed(() => null), to: computed(() => null), cancelSelection() {}, + externalClickSelect(ev) {}, }) } @@ -138,6 +140,35 @@ export function useSelectionRect( selection.value = newSelection } + function externalClickSelect(ev: MouseEvent) { + const element = toValue(elem) + if (!element) return + + const pos = getInternalMousePos(element, ev) + const ids = collectSelection(pos, pos) + + let mode: SelectionMode + if (ev.shiftKey) { + mode = "add" + } else if (ev.ctrlKey) { + mode = "remove" + } else { + mode = "overwrite" + } + + let newSelection: Selection + + if (mode == "add") { + newSelection = _uniq([...oldSelection.value, ...ids]) + } else if (mode == "remove") { + newSelection = oldSelection.value.filter((id) => !ids.includes(id)) + } else { + newSelection = ids + } + + selection.value = newSelection + } + useEventListener(elem, "mousedown", (ev: MouseEvent) => { const element = toValue(elem) @@ -162,7 +193,7 @@ export function useSelectionRect( } oldSelection.value = [...selection.value] - //console.log("Select Start", toValue(path)) + console.log("Select Start", toValue(path)) stopPropagation(ev) ev.preventDefault() }) @@ -217,6 +248,7 @@ export function useSelectionRect( from, to, cancelSelection, + externalClickSelect, } provide("selectionState", state) diff --git a/libs/castmate-ws-rpc/src/rpc-socket.ts b/libs/castmate-ws-rpc/src/rpc-socket.ts index 92e8249c..54837be9 100644 --- a/libs/castmate-ws-rpc/src/rpc-socket.ts +++ b/libs/castmate-ws-rpc/src/rpc-socket.ts @@ -56,7 +56,13 @@ export class RPCHandler { } const args = data.args || [] - this.handlers[requestName](requestId, sender, ...preArgs, ...args) + const handler = this.handlers[requestName] + + if (handler) { + handler(requestId, sender, ...preArgs, ...args) + } else { + //console.log("MISSING HANDLER", requestName) + } } } @@ -67,6 +73,7 @@ export class RPCHandler { try { result = await func(...args) } catch (err) { + console.error(err) await sender({ responseId: requestId, failed: true, diff --git a/package.json b/package.json index 4509a7bb..f2d5f32b 100644 --- a/package.json +++ b/package.json @@ -1,14 +1,15 @@ { "name": "castmate-monorepo", - "version": "0.5.3", + "version": "0.5.4-beta", "description": "", "private": true, "type": "module", "scripts": { "setup-vite": "yarn workspace castmate-vite build", - "build": "node ./vite-util/multi-vite.mjs build && yarn workspace castmate run electron:build", - "buildpublish": "node ./vite-util/multi-vite.mjs build && yarn workspace castmate run electron:buildpublish", + "build": "node ./vite-util/multi-vite.mjs build && yarn workspace castmate run electron:build && yarn workspace castmate-satellite run electron:build", + "buildpublish": "node ./vite-util/multi-vite.mjs build && yarn workspace castmate run electron:buildpublish && yarn workspace castmate-satellite run electron:buildpublish", "dev": "node ./vite-util/multi-vite.mjs", + "satdev": "yarn workspace castmate-satellite dev", "format": "prettier . --write", "clearnode": "node ./vite-util/clear-node-modules.mjs", "ebuild": "electron-rebuild -f" @@ -25,7 +26,7 @@ "devDependencies": { "@electron/rebuild": "^3.6.0", "@types/node": "^20.4.8", - "@vitejs/plugin-vue": "^4.3.4", + "@vitejs/plugin-vue": "4.6.2", "@vue/tsconfig": "^0.4.0", "@vueuse/core": "10.7.2", "chromatism2": "^3.0.2", diff --git a/packages/castmate-satellite/build/icon.png b/packages/castmate-satellite/build/icon.png new file mode 100644 index 00000000..89e81756 Binary files /dev/null and b/packages/castmate-satellite/build/icon.png differ diff --git a/packages/castmate-satellite/electron-builder-config.cjs b/packages/castmate-satellite/electron-builder-config.cjs new file mode 100644 index 00000000..5efa8f43 --- /dev/null +++ b/packages/castmate-satellite/electron-builder-config.cjs @@ -0,0 +1,86 @@ +module.exports = { + appId: "com.lordtocs.castmate.satellite", + productName: "CastMateSatellite", + asar: true, + directories: { + output: "../../release-satellite", + }, + files: [ + "dist/**/*", + "!**/node_modules/*/{CHANGELOG.md,README.md,README,readme.md,readme}", + "!**/node_modules/*/{test,__tests__,tests,powered-test,example,examples}", + "!**/node_modules/*.d.ts", + "!**/node_modules/.bin", + "!**/*.{iml,o,hprof,orig,pyc,pyo,rbc,swp,csproj,sln,xproj}", + "!.editorconfig", + "!**/._*", + "!**/{.DS_Store,.git,.hg,.svn,CVS,RCS,SCCS,.gitignore,.gitattributes}", + "!**/{__pycache__,thumbs.db,.flowconfig,.idea,.vs,.nyc_output}", + "!**/{appveyor.yml,.travis.yml,circle.yml}", + "!**/{npm-debug.log,yarn.lock,.yarn-integrity,.yarn-metadata.json}", + ], + mac: { + artifactName: "${productName}_${version}.${ext}", + target: ["dmg"], + }, + npmRebuild: true, + nodeGypRebuild: false, + nativeRebuilder: "sequential", + win: { + target: [ + { + target: "nsis", + arch: ["x64"], + }, + { + target: "portable", + arch: ["x64"], + }, + ], + artifactName: "${productName}_${version}.${ext}", + }, + nsis: { + oneClick: false, + perMachine: false, + allowToChangeInstallationDirectory: true, + deleteAppDataOnUninstall: true, + }, + portable: { + artifactName: "${productName}_${version}-portable.${ext}", + }, + extraResources: [ + { + from: "../../node_modules/@ffmpeg-installer/win32-x64", + to: "ffmpeg/bin", + filter: ["**/*.exe"], + }, + { + from: "../../node_modules/@ffprobe-installer/win32-x64", + to: "ffmpeg/bin", + filter: ["**/*.exe"], + }, + { + from: "../../node_modules/regedit/vbs", + to: "regedit/vbs", + filter: ["**/*"], + }, + ], + extraFiles: [ + // { + // from: "../castmate-obs-overlay/dist/obs-overlay", + // to: "obs-overlay", + // }, + // { + // from: "starter_media", + // to: "starter_media" + // } + ], + publish: [ + { + provider: "github", + owner: "LordTocs", + repo: "CastMate", + channel: "satellite-latest", + }, + ], +} diff --git a/packages/castmate-satellite/html/index.html b/packages/castmate-satellite/html/index.html new file mode 100644 index 00000000..f4152530 --- /dev/null +++ b/packages/castmate-satellite/html/index.html @@ -0,0 +1,14 @@ + + + + + + + + CastMate Satellite + + +
+ + + diff --git a/packages/castmate-satellite/package.json b/packages/castmate-satellite/package.json new file mode 100644 index 00000000..2725cdb0 --- /dev/null +++ b/packages/castmate-satellite/package.json @@ -0,0 +1,70 @@ +{ + "name": "castmate-satellite", + "version": "0.5.4-beta", + "description": "CastMate", + "author": "LordTocs", + "scripts": { + "compile": "vue-tsc", + "trace": "vue-tsc --traceResolution", + "build": "vue-tsc && vite build", + "dev": "vite serve --port 5175", + "inspect": "electron ./dist/dist-electron/background.js --inspect", + "electron:build": "electron-builder --config electron-builder-config.cjs", + "electron:buildpublish": "electron-builder --config electron-builder-config.cjs --publish always", + "fix-app-deps": "electron-builder install-app-deps" + }, + "main": "dist/dist-electron/background.js", + "electronVersion": "29.1.1", + "dependencies": { + "archiver": "^7.0.1", + "castmate-core": "workspace:^", + "castmate-plugin-dashboards-shared": "workspace:^", + "castmate-plugin-elgato-main": "workspace:^", + "castmate-plugin-govee-main": "workspace:^", + "castmate-plugin-iot-main": "workspace:^", + "castmate-plugin-lifx-main": "workspace:^", + "castmate-plugin-philips-hue-main": "workspace:^", + "castmate-plugin-sound-main": "workspace:^", + "castmate-plugin-tplink-kasa-main": "workspace:^", + "castmate-plugin-twinkly-main": "workspace:^", + "castmate-plugin-twitch-main": "workspace:^", + "castmate-plugin-wyze-main": "workspace:^", + "castmate-schema": "workspace:^" + }, + "devDependencies": { + "@mdi/font": "^7.1.96", + "@rollup/plugin-node-resolve": "^15.2.1", + "@types/archiver": "^6.0.2", + "@vitejs/plugin-vue": "4.6.2", + "@vueuse/core": "*", + "castmate-dashboard-widget-loader": "workspace:^", + "castmate-overlay-core": "workspace:^", + "castmate-plugin-sound-renderer": "workspace:^", + "castmate-plugin-twitch-renderer": "workspace:^", + "castmate-ui-core": "workspace:^", + "castmate-vite": "workspace:^", + "chromatism2": "*", + "electron": "29.4.5", + "electron-builder": "^25.1.8", + "electron-devtools-installer": "^3.2.0", + "eslint": "^8.17.0", + "nanoid": "^5.0.7", + "pinia": "^2.1.7", + "primeflex": "*", + "primeicons": "^6.0.1", + "primevue": "3.53.0", + "sass": "^1.71.0", + "ts-toolbelt": "*", + "vite": "^5.2.9", + "vite-plugin-electron": "^0.12.0", + "vite-plugin-electron-renderer": "^0.14.5", + "vue": "^3.4.23", + "vue-tsc": "*" + }, + "browserslist": [ + "> 1%", + "last 2 versions", + "not dead" + ], + "packageManager": "yarn@3.2.4" +} diff --git a/packages/castmate-satellite/src/main/background.ts b/packages/castmate-satellite/src/main/background.ts new file mode 100644 index 00000000..2c241a06 --- /dev/null +++ b/packages/castmate-satellite/src/main/background.ts @@ -0,0 +1,98 @@ +//import { fileURLToPath } from "node:url" +//import { createRequire } from "node:module" +import installExtension, { VUEJS_DEVTOOLS } from "electron-devtools-installer" +//import electronUpdater from "electron-updater" +import { app, BrowserWindow, ipcMain, contentTracing } from "electron" +import { createWindow } from "./electron/electron-helpers" +import { + initializeCastMate, + finializeCastMateSetup, + loadAutomations, + setupCastMateDirectories, + initializeCastMateSatellite, + finializeCastMateSatelliteSetup, +} from "castmate-core" +import { loadPlugins } from "./plugins" + +const isDevelopment = !app.isPackaged // true //TODO: import.meta.env.DEV + +if (process.platform === "win32") app.setAppUserModelId(app.getName()) + +//??? +process.env["ELECTRON_DISABLE_SECURITY_WARNINGS"] = "true" + +function quit() { + app.quit() + process.exit(0) +} + +function createMainWindow() { + const portable = process.env.PORTABLE_EXECUTABLE_FILE != null || process.argv.includes("--portable") + const win = createWindow("index.html", 1600, 900, { portable: String(portable) }) + + win.on("close", () => { + //Workaround for electron bug. + if (win.webContents.isDevToolsOpened()) { + win.webContents.closeDevTools() + } + }) + + win.on("closed", () => { + quit() + }) +} + +app.whenReady().then(async () => { + //Setup our user folder location / session data + await setupCastMateDirectories("user-sat") + + if (isDevelopment && !process.env.IS_TEST) { + // Install Vue Devtools + console.log("Trying to install dev tools") + try { + await installExtension(VUEJS_DEVTOOLS) + } catch (err) { + console.error("Failed to install vue dev tools", err) + } + } + + //Create the window + await createMainWindow() + + await initializeCastMateSatellite() + + await loadPlugins() + + await finializeCastMateSatelliteSetup() +}) + +// Quit when all windows are closed. +app.on("window-all-closed", () => { + // On macOS it is common for applications and their menu bar + // to stay active until the user quits explicitly with Cmd + Q + if (process.platform !== "darwin") { + quit() + } +}) + +app.on("activate", () => { + // On macOS it's common to re-create a window in the app when the + // dock icon is clicked and there are no other windows open. + if (BrowserWindow.getAllWindows().length === 0) createMainWindow() +}) + +// Exit cleanly on request from parent process in development mode. +if (isDevelopment) { + if (process.platform === "win32") { + process.on("message", (data) => { + if (data === "graceful-exit") { + console.log("Graceful Exit") + quit() + } + }) + } else { + process.on("SIGTERM", () => { + quit() + }) + } +} diff --git a/packages/castmate-satellite/src/main/electron/electron-helpers.ts b/packages/castmate-satellite/src/main/electron/electron-helpers.ts new file mode 100644 index 00000000..3ba27bed --- /dev/null +++ b/packages/castmate-satellite/src/main/electron/electron-helpers.ts @@ -0,0 +1,102 @@ +import { usePluginLogger } from "castmate-core" +import { BrowserWindow, app, shell, ipcMain } from "electron" +import path from "path" + +const viteDevURL = `http://${process.env["VITE_DEV_SERVER_HOSTNAME"]}:${process.env["VITE_DEV_SERVER_PORT"]}` + +const iconPath = app.isPackaged ? path.join(__dirname, "../..", "renderer/assets/icons/") : "src/renderer/assets/icons/" + +const logger = usePluginLogger("system") + +export function createWindow( + htmlFile: string, + width: number, + height: number, + urlQuery: Record = {}, + icon: string = "icon.png" +) { + const win = new BrowserWindow({ + width, + height, + icon: path.join(iconPath, icon), + webPreferences: { + //TODO: Look into these + nodeIntegration: true, + contextIsolation: false, + webSecurity: false, + }, + frame: false, + }) + + if (process.env.VITE_DEV_SERVER_URL) { + //get it from vite + const url = path.posix.join(process.env.VITE_DEV_SERVER_URL, "html", htmlFile) + const params = new URLSearchParams(urlQuery) + win.loadURL(`${url}?${params}`) + } else { + const url = path.join(__dirname, `../../dist/html/${htmlFile}`) + win.loadFile(url, { + query: urlQuery, + }) + } + + win.addListener("maximize", () => { + win.webContents.send("windowFuncs_stateChanged", "maximized") + }) + + win.addListener("minimize", () => { + win.webContents.send("windowFuncs_stateChanged", "minimized") + }) + + win.addListener("unmaximize", () => { + win.webContents.send("windowFuncs_stateChanged", "unmaximized") + }) + + win.addListener("restore", () => { + win.webContents.send("windowFuncs_stateChanged", win.isMaximized() ? "maximized" : "unmaximized") + }) + + win.webContents.setWindowOpenHandler((details) => { + shell.openExternal(details.url) + return { action: "deny" } + }) + + /* + win.webContents.on("new-window", function (e, url) { + e.preventDefault() + shell.openExternal(url) + }) + */ + + return win +} + +//WINDOW FUNCTIONS +ipcMain.handle("windowFuncs_minimize", async (event) => { + const win = BrowserWindow.fromWebContents(event.sender) + win?.minimize() +}) + +ipcMain.handle("windowFuncs_maximize", async (event) => { + const win = BrowserWindow.fromWebContents(event.sender) + win?.maximize() +}) + +ipcMain.handle("windowFuncs_restore", async (event) => { + const win = BrowserWindow.fromWebContents(event.sender) + win?.unmaximize() +}) + +ipcMain.handle("windowFuncs_close", async (event) => { + const win = BrowserWindow.fromWebContents(event.sender) + win?.close() +}) + +ipcMain.handle("windowFuncs_isMaximized", async (event) => { + const win = BrowserWindow.fromWebContents(event.sender) + return win?.isMaximized() +}) + +ipcMain.handle("windowFuncs_getVersion", async (event) => { + return app.getVersion() +}) diff --git a/packages/castmate-satellite/src/main/plugins.ts b/packages/castmate-satellite/src/main/plugins.ts new file mode 100644 index 00000000..ba84a448 --- /dev/null +++ b/packages/castmate-satellite/src/main/plugins.ts @@ -0,0 +1,43 @@ +import { PluginManager, Plugin } from "castmate-core" + +import { twitchSatellite } from "castmate-plugin-twitch-main" +import { dashboardSatellite } from "castmate-plugin-dashboards-main" + +import { satelliteIoTPlugin } from "castmate-plugin-iot-main" +import huePlugin from "castmate-plugin-philips-hue-main" +import kasaPlugin from "castmate-plugin-tplink-kasa-main" +import elgatoPlugin from "castmate-plugin-elgato-main" +import lifxPlugin from "castmate-plugin-lifx-main" +import wyzePlugin from "castmate-plugin-wyze-main" +import goveePlugin from "castmate-plugin-govee-main" +import twinklyPlugin from "castmate-plugin-twinkly-main" + +import soundPlugin from "castmate-plugin-sound-main" + +export async function loadPlugin(plugin: Plugin) { + await PluginManager.getInstance().registerPlugin(plugin) +} + +export async function loadPlugins() { + await loadPlugin(twitchSatellite) + console.log("Load Dashboard Satellite") + await loadPlugin(dashboardSatellite) + + await loadPlugin(satelliteIoTPlugin) + + await loadPlugin(soundPlugin) + //iot + const iotPromises: Promise[] = [ + loadPlugin(huePlugin), + loadPlugin(kasaPlugin), + loadPlugin(elgatoPlugin), + loadPlugin(lifxPlugin), + loadPlugin(wyzePlugin), + loadPlugin(goveePlugin), + loadPlugin(twinklyPlugin), + ] + + await Promise.allSettled(iotPromises) + + //await WebService.getInstance().startWebsockets() +} diff --git a/packages/castmate-satellite/src/renderer/App.vue b/packages/castmate-satellite/src/renderer/App.vue new file mode 100644 index 00000000..b45a3ed3 --- /dev/null +++ b/packages/castmate-satellite/src/renderer/App.vue @@ -0,0 +1,93 @@ + + + + + + + diff --git a/packages/castmate-satellite/src/renderer/assets/castmate/logo-dark.svg b/packages/castmate-satellite/src/renderer/assets/castmate/logo-dark.svg new file mode 100644 index 00000000..06f3f274 --- /dev/null +++ b/packages/castmate-satellite/src/renderer/assets/castmate/logo-dark.svg @@ -0,0 +1,328 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/castmate-satellite/src/renderer/assets/icons/icon.png b/packages/castmate-satellite/src/renderer/assets/icons/icon.png new file mode 100644 index 00000000..fc4534bc Binary files /dev/null and b/packages/castmate-satellite/src/renderer/assets/icons/icon.png differ diff --git a/packages/castmate-satellite/src/renderer/components/connection/RemoteDashButton.vue b/packages/castmate-satellite/src/renderer/components/connection/RemoteDashButton.vue new file mode 100644 index 00000000..be99f7b0 --- /dev/null +++ b/packages/castmate-satellite/src/renderer/components/connection/RemoteDashButton.vue @@ -0,0 +1,30 @@ + + + diff --git a/packages/castmate-satellite/src/renderer/components/connection/RemoteDashGroup.vue b/packages/castmate-satellite/src/renderer/components/connection/RemoteDashGroup.vue new file mode 100644 index 00000000..6d412897 --- /dev/null +++ b/packages/castmate-satellite/src/renderer/components/connection/RemoteDashGroup.vue @@ -0,0 +1,45 @@ + + + + + diff --git a/packages/castmate-satellite/src/renderer/components/dashboard/DashboardDisplay.vue b/packages/castmate-satellite/src/renderer/components/dashboard/DashboardDisplay.vue new file mode 100644 index 00000000..fd260b83 --- /dev/null +++ b/packages/castmate-satellite/src/renderer/components/dashboard/DashboardDisplay.vue @@ -0,0 +1,67 @@ + + + + + diff --git a/packages/castmate-satellite/src/renderer/components/dashboard/DashboardPage.vue b/packages/castmate-satellite/src/renderer/components/dashboard/DashboardPage.vue new file mode 100644 index 00000000..e478a276 --- /dev/null +++ b/packages/castmate-satellite/src/renderer/components/dashboard/DashboardPage.vue @@ -0,0 +1,29 @@ + + + + + diff --git a/packages/castmate-satellite/src/renderer/components/dashboard/DashboardSection.vue b/packages/castmate-satellite/src/renderer/components/dashboard/DashboardSection.vue new file mode 100644 index 00000000..f3ebf9c6 --- /dev/null +++ b/packages/castmate-satellite/src/renderer/components/dashboard/DashboardSection.vue @@ -0,0 +1,53 @@ + + + + + diff --git a/packages/castmate-satellite/src/renderer/components/dashboard/DashboardWidget.vue b/packages/castmate-satellite/src/renderer/components/dashboard/DashboardWidget.vue new file mode 100644 index 00000000..1aea338a --- /dev/null +++ b/packages/castmate-satellite/src/renderer/components/dashboard/DashboardWidget.vue @@ -0,0 +1,71 @@ + + + + + diff --git a/packages/castmate-satellite/src/renderer/components/pages/ConnectionPage.vue b/packages/castmate-satellite/src/renderer/components/pages/ConnectionPage.vue new file mode 100644 index 00000000..92da0905 --- /dev/null +++ b/packages/castmate-satellite/src/renderer/components/pages/ConnectionPage.vue @@ -0,0 +1,44 @@ + + + + + diff --git a/packages/castmate-satellite/src/renderer/components/pages/DashboardPage.vue b/packages/castmate-satellite/src/renderer/components/pages/DashboardPage.vue new file mode 100644 index 00000000..10f111eb --- /dev/null +++ b/packages/castmate-satellite/src/renderer/components/pages/DashboardPage.vue @@ -0,0 +1,10 @@ + + + diff --git a/packages/castmate-satellite/src/renderer/components/pages/SlotsPage.vue b/packages/castmate-satellite/src/renderer/components/pages/SlotsPage.vue new file mode 100644 index 00000000..953683f5 --- /dev/null +++ b/packages/castmate-satellite/src/renderer/components/pages/SlotsPage.vue @@ -0,0 +1,36 @@ + + + + + diff --git a/packages/castmate-satellite/src/renderer/components/system/SystemBar.vue b/packages/castmate-satellite/src/renderer/components/system/SystemBar.vue new file mode 100644 index 00000000..05e1ed45 --- /dev/null +++ b/packages/castmate-satellite/src/renderer/components/system/SystemBar.vue @@ -0,0 +1,171 @@ + + + + + diff --git a/packages/castmate-satellite/src/renderer/css/spellcast.css b/packages/castmate-satellite/src/renderer/css/spellcast.css new file mode 100644 index 00000000..4b707c1b --- /dev/null +++ b/packages/castmate-satellite/src/renderer/css/spellcast.css @@ -0,0 +1,17 @@ +.cmi::before { + display: inline-block; + text-rendering: auto; + line-height: inherit; +} + +.cmi.cmi-spellcast::before { + content: ""; + background-image: url("data:image/svg+xml;utf8,%3C%3Fxml%20version%3D%271.0%27%20encoding%3D%27UTF-8%27%20standalone%3D%27no%27%3F%3E%20%3C%21--%20Created%20with%20Inkscape%20%28http%3A%2F%2Fwww.inkscape.org%2F%29%20--%3E%20%3Csvg%20width%3D%2724mm%27%20height%3D%2724mm%27%20viewBox%3D%270%200%2024%2024%27%20version%3D%271.1%27%20id%3D%27svg5%27%20inkscape%3Aversion%3D%271.1.1%20%283bf5ae0d25%2C%202021-09-20%29%27%20sodipodi%3Adocname%3D%27spellcast-logo-square.svg%27%20xmlns%3Ainkscape%3D%27http%3A%2F%2Fwww.inkscape.org%2Fnamespaces%2Finkscape%27%20xmlns%3Asodipodi%3D%27http%3A%2F%2Fsodipodi.sourceforge.net%2FDTD%2Fsodipodi-0.dtd%27%20xmlns%3Axlink%3D%27http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20xmlns%3Asvg%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%20%3Csodipodi%3Anamedview%20id%3D%27namedview7%27%20pagecolor%3D%27%23ffffff%27%20bordercolor%3D%27%23666666%27%20borderopacity%3D%271.0%27%20inkscape%3Apageshadow%3D%272%27%20inkscape%3Apageopacity%3D%270.0%27%20inkscape%3Apagecheckerboard%3D%270%27%20inkscape%3Adocument-units%3D%27mm%27%20showgrid%3D%27false%27%20showguides%3D%27false%27%20inkscape%3Azoom%3D%273.6203867%27%20inkscape%3Acx%3D%2766.291261%27%20inkscape%3Acy%3D%2779.411407%27%20inkscape%3Awindow-width%3D%273840%27%20inkscape%3Awindow-height%3D%272097%27%20inkscape%3Awindow-x%3D%271912%27%20inkscape%3Awindow-y%3D%27-8%27%20inkscape%3Awindow-maximized%3D%271%27%20inkscape%3Acurrent-layer%3D%27layer1%27%20fit-margin-top%3D%270%27%20fit-margin-left%3D%270%27%20fit-margin-right%3D%270%27%20fit-margin-bottom%3D%270%27%20width%3D%2724mm%27%20%2F%3E%20%3Cdefs%20id%3D%27defs2%27%3E%20%3ClinearGradient%20inkscape%3Acollect%3D%27always%27%20id%3D%27linearGradient13510-9%27%3E%20%3Cstop%20style%3D%27stop-color%3A%2315fb1d%3Bstop-opacity%3A1%27%20offset%3D%270%27%20id%3D%27stop13506%27%20%2F%3E%20%3Cstop%20style%3D%27stop-color%3A%230162ff%3Bstop-opacity%3A1%27%20offset%3D%271%27%20id%3D%27stop13508%27%20%2F%3E%20%3C%2FlinearGradient%3E%20%3CradialGradient%20inkscape%3Acollect%3D%27always%27%20xlink%3Ahref%3D%27%23linearGradient13510-9%27%20id%3D%27radialGradient12046-5-9%27%20cx%3D%2721.534763%27%20cy%3D%2741.178757%27%20fx%3D%2721.534763%27%20fy%3D%2741.178757%27%20r%3D%2717.762384%27%20gradientTransform%3D%27matrix%280.90023675%2C-0.19210011%2C0.36186475%2C1.6958031%2C-20.230021%2C-40.898233%29%27%20gradientUnits%3D%27userSpaceOnUse%27%20%2F%3E%20%3C%2Fdefs%3E%20%3Cg%20inkscape%3Alabel%3D%27Layer%201%27%20inkscape%3Agroupmode%3D%27layer%27%20id%3D%27layer1%27%3E%20%3Ctext%20xml%3Aspace%3D%27preserve%27%20style%3D%27font-style%3Anormal%3Bfont-weight%3Anormal%3Bfont-size%3A10.5833px%3Bline-height%3A1.25%3Bfont-family%3Asans-serif%3Bfill%3A%23000000%3Bfill-opacity%3A1%3Bstroke%3Anone%3Bstroke-width%3A0.264583%27%20x%3D%27-11.254553%27%20y%3D%27553.51935%27%20id%3D%27text19433%27%3E%3Ctspan%20sodipodi%3Arole%3D%27line%27%20id%3D%27tspan19431%27%20style%3D%27stroke-width%3A0.264583%27%20x%3D%27-11.254553%27%20y%3D%27553.51935%27%20%2F%3E%3C%2Ftext%3E%20%3Cpath%20style%3D%27fill%3Aurl%28%23radialGradient12046-5-9%29%3Bfill-opacity%3A1%3Bstroke%3Anone%3Bstroke-width%3A0.0842756px%3Bstroke-linecap%3Abutt%3Bstroke-linejoin%3Amiter%3Bstroke-opacity%3A1%27%20d%3D%27M%203.428161%2C8.9939525%20C%20-1.9131809%2C16.974581%2013.63528%2C24.69225%2013.973404%2C24.692954%20c%200.270362%2C4.58e-4%208.333484%2C-2.362333%207.042654%2C-5.089138%20C%2019.047035%2C15.444369%208.1159333%2C10.20927%2011.263775%2C8.3777282%2012.745237%2C7.4923861%2020.297395%2C11.423605%2021.495394%2C15.473614%2023.599996%2C5.3485901%207.5402441%2C5.0640808%2017.124295%2C-0.69295363%20-7.345933%2C6.3307322%2012.415649%2C13.228519%2010.616206%2C14.737251%208.8167566%2C16.245979%201.5465555%2C14.340349%203.428161%2C8.9939525%20Z%27%20id%3D%27path15277-7-9-3-1-3-9%27%20sodipodi%3Anodetypes%3D%27cssccczc%27%20%2F%3E%20%3Ctext%20xml%3Aspace%3D%27preserve%27%20style%3D%27font-style%3Anormal%3Bfont-weight%3Anormal%3Bfont-size%3A10.5833px%3Bline-height%3A1.25%3Bfont-family%3Asans-serif%3Bfill%3A%23000000%3Bfill-opacity%3A1%3Bstroke%3Anone%3Bstroke-width%3A0.264583%27%20x%3D%27-11.999999%27%20y%3D%27552.48157%27%20id%3D%27text19433-8%27%3E%3Ctspan%20sodipodi%3Arole%3D%27line%27%20id%3D%27tspan19431-9%27%20style%3D%27stroke-width%3A0.264583%27%20x%3D%27-11.999999%27%20y%3D%27552.48157%27%20%2F%3E%3C%2Ftext%3E%20%3C%2Fg%3E%20%3C%2Fsvg%3E%20"); + background-size: 1em; + height: 1em; + width: 1em; +} + +.cmi.cmi-spellcast { + height: 1em; +} diff --git a/packages/castmate-satellite/src/renderer/css/theme-ext.css b/packages/castmate-satellite/src/renderer/css/theme-ext.css new file mode 100644 index 00000000..0c67423c --- /dev/null +++ b/packages/castmate-satellite/src/renderer/css/theme-ext.css @@ -0,0 +1,51 @@ +.mdi { + font-family: "primeicons"; /* Without this the icons will all be off center. Fonts are weird. Don't think about this too hard */ +} + +.active-profile-icon { + color: var(--primary-color); +} + +.no-focus-highlight { + box-shadow: none !important; +} + +a.p-button { + text-decoration: none; +} + +.p-inputgroup { + width: unset !important; +} + +.column-fit-width { + width: 1px; + white-space: nowrap; +} + +.no-right-bezel { + border-top-right-radius: 0px !important; + border-bottom-right-radius: 0px !important; +} + +.no-left-bezel { + border-top-left-radius: 0px !important; + border-bottom-left-radius: 0px !important; +} + +.clickable-input { + cursor: pointer; +} + +.w-0 { + width: 0; +} + +.extra-small-button .p-button.p-button-icon-only { + width: 2rem !important; + padding: 0.25rem 0 !important; +} +.extra-small-button.p-button.p-button-icon-only { + width: 2rem !important; + padding: 0.25rem 0 !important; +} diff --git a/packages/castmate-satellite/src/renderer/css/theme.css b/packages/castmate-satellite/src/renderer/css/theme.css new file mode 100644 index 00000000..1cce2fdd --- /dev/null +++ b/packages/castmate-satellite/src/renderer/css/theme.css @@ -0,0 +1,6380 @@ +:root { + --surface-a: #212121; + --surface-b: #121212; + --surface-c: rgba(158, 173, 230, 0.08); + --surface-d: #3c3c3c; + --surface-e: #212121; + --surface-f: #212121; + --text-color: #e6e6e6; + --text-color-secondary: #b3b3b3; + --primary-color: #e9aaff; + --primary-color-text: #121212; + --secondary-color: #9ec1ff; + --font-family: Lato, Helvetica, sans-serif; + --surface-0: #0e1315; + --surface-50: #262b2c; + --surface-100: #3e4244; + --surface-200: #565a5b; + --surface-300: #6e7173; + --surface-400: #87898a; + --surface-500: #9fa1a1; + --surface-600: #b7b8b9; + --surface-700: #cfd0d0; + --surface-800: #e7e7e8; + --surface-900: #ffffff; + --gray-50: #e7e7e8; + --gray-100: #cfd0d0; + --gray-200: #b7b8b9; + --gray-300: #9fa1a1; + --gray-400: #87898a; + --gray-500: #6e7173; + --gray-600: #565a5b; + --gray-700: #3e4244; + --gray-800: #262b2c; + --gray-900: #0e1315; + --content-padding: 1rem; + --inline-spacing: 0.5rem; + --border-radius: 6px; + --surface-ground: #121212; + --surface-section: #232323; + --surface-card: #161616; + --surface-overlay: #1d1d1d; + --surface-border: #262626; + --surface-hover: rgba($primaryColor, 0.08); + --focus-ring: 0 0 0 1px #e9aaff; + --maskbg: rgba(0, 0, 0, 0.4); + --highlight-bg: rgba(158, 173, 230, 0.16); + --highlight-text-color: #9eade6; + --or-color: blue; + --and-color: green; + --true-color: #262b2c; + color-scheme: dark; +} + +@font-face { + font-family: "Poppins"; + font-style: normal; + font-weight: 300; + src: local(""), url("./fonts/poppins-v15-latin-ext_latin-300.woff2") format("woff2"), + url("./fonts/poppins-v15-latin-ext_latin-300.woff") format("woff"); +} +@font-face { + font-family: "Poppins"; + font-style: normal; + font-weight: 400; + src: local(""), url("./fonts/poppins-v15-latin-ext_latin-regular.woff2") format("woff2"), + url("./fonts/poppins-v15-latin-ext_latin-regular.woff") format("woff"); +} +@font-face { + font-family: "Poppins"; + font-style: normal; + font-weight: 600; + src: local(""), url("./fonts/poppins-v15-latin-ext_latin-600.woff2") format("woff2"), + url("./fonts/poppins-v15-latin-ext_latin-600.woff") format("woff"); +} +@font-face { + font-family: "Poppins"; + font-style: normal; + font-weight: 700; + src: local(""), url("./fonts/poppins-v15-latin-ext_latin-700.woff2") format("woff2"), + url("./fonts/poppins-v15-latin-ext_latin-700.woff") format("woff"); +} +* { + box-sizing: border-box; +} +.p-component { + font-family: Lato, Helvetica, sans-serif; + font-size: 1rem; + font-weight: normal; +} +.p-component-overlay { + background-color: rgba(0, 0, 0, 0.4); + transition-duration: 0.3s; +} +.p-disabled, +.p-component:disabled { + opacity: 0.4; +} +.p-error { + color: #ff9a9a; +} +.p-text-secondary { + color: #b3b3b3; +} +.pi { + font-size: 1rem; +} +.p-icon { + width: 1rem; + height: 1rem; +} +.p-link { + font-size: 1rem; + font-family: Lato, Helvetica, sans-serif; + border-radius: 6px; +} +.p-link:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-component-overlay-enter { + animation: p-component-overlay-enter-animation 150ms forwards; +} +.p-component-overlay-leave { + animation: p-component-overlay-leave-animation 150ms forwards; +} +@keyframes p-component-overlay-enter-animation { + from { + background-color: transparent; + } + to { + background-color: var(--maskbg); + } +} +@keyframes p-component-overlay-leave-animation { + from { + background-color: var(--maskbg); + } + to { + background-color: transparent; + } +} +:root { + --blue-50: #f6fbfd; + --blue-100: #d6eaf5; + --blue-200: #b5d9ed; + --blue-300: #95c8e4; + --blue-400: #74b7dc; + --blue-500: #54a6d4; + --blue-600: #478db4; + --blue-700: #3b7494; + --blue-800: #2e5b75; + --blue-900: #224255; + --green-50: #f9fbf4; + --green-100: #e3eccc; + --green-200: #cddca4; + --green-300: #b7cd7c; + --green-400: #a1bd54; + --green-500: #8bae2c; + --green-600: #769425; + --green-700: #617a1f; + --green-800: #4c6018; + --green-900: #384612; + --yellow-50: #fffdf4; + --yellow-100: #fff4cc; + --yellow-200: #ffeba3; + --yellow-300: #ffe27b; + --yellow-400: #ffd952; + --yellow-500: #ffd02a; + --yellow-600: #d9b124; + --yellow-700: #b3921d; + --yellow-800: #8c7217; + --yellow-900: #665311; + --cyan-50: #f5fafc; + --cyan-100: #cfe9f3; + --cyan-200: #a8d8e9; + --cyan-300: #82c7df; + --cyan-400: #5bb5d6; + --cyan-500: #35a4cc; + --cyan-600: #2d8bad; + --cyan-700: #25738f; + --cyan-800: #1d5a70; + --cyan-900: #154252; + --pink-50: #fdf6f8; + --pink-100: #f5d6dd; + --pink-200: #edb5c2; + --pink-300: #e495a8; + --pink-400: #dc748d; + --pink-500: #d45472; + --pink-600: #b44761; + --pink-700: #943b50; + --pink-800: #752e3f; + --pink-900: #55222e; + --indigo-50: #f6f8fd; + --indigo-100: #d6ddf5; + --indigo-200: #b5c2ed; + --indigo-300: #95a8e4; + --indigo-400: #748ddc; + --indigo-500: #5472d4; + --indigo-600: #4761b4; + --indigo-700: #3b5094; + --indigo-800: #2e3f75; + --indigo-900: #222e55; + --teal-50: #f5fcfa; + --teal-100: #d1f0e8; + --teal-200: #ace3d6; + --teal-300: #88d7c4; + --teal-400: #63cbb2; + --teal-500: #3fbfa0; + --teal-600: #36a288; + --teal-700: #2c8670; + --teal-800: #236958; + --teal-900: #194c40; + --orange-50: #fffaf4; + --orange-100: #ffe5cc; + --orange-200: #ffd0a3; + --orange-300: #ffbb7b; + --orange-400: #ffa752; + --orange-500: #ff922a; + --orange-600: #d97c24; + --orange-700: #b3661d; + --orange-800: #8c5017; + --orange-900: #663a11; + --bluegray-50: #f9fafb; + --bluegray-100: #e1e5ea; + --bluegray-200: #c9d0d9; + --bluegray-300: #b1bbc8; + --bluegray-400: #99a6b7; + --bluegray-500: #8191a6; + --bluegray-600: #6e7b8d; + --bluegray-700: #5a6674; + --bluegray-800: #47505b; + --bluegray-900: #343a42; + --purple-50: #f8f6fd; + --purple-100: #ded6f5; + --purple-200: #c4b5ed; + --purple-300: #aa95e4; + --purple-400: #9074dc; + --purple-500: #7654d4; + --purple-600: #6447b4; + --purple-700: #533b94; + --purple-800: #412e75; + --purple-900: #2f2255; + --red-50: #fff7f6; + --red-100: #ffd8d2; + --red-200: #ffb9af; + --red-300: #ff9b8b; + --red-400: #ff7c68; + --red-500: #ff5d44; + --red-600: #d94f3a; + --red-700: #b34130; + --red-800: #8c3325; + --red-900: #66251b; + --primary-50: #fefbff; + --primary-100: #faebff; + --primary-200: #f6daff; + --primary-300: #f1caff; + --primary-400: #edbaff; + --primary-500: #e9aaff; + --primary-600: #c691d9; + --primary-700: #a377b3; + --primary-800: #805e8c; + --primary-900: #5d4466; +} +.p-autocomplete .p-autocomplete-loader { + right: 0.75rem; +} +.p-autocomplete.p-autocomplete-dd .p-autocomplete-loader { + right: 3.607rem; +} +.p-autocomplete:not(.p-disabled):hover .p-autocomplete-multiple-container { + border-color: #464646; +} +.p-autocomplete:not(.p-disabled).p-focus .p-autocomplete-multiple-container { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; + border-color: #c9b1cb; +} +.p-autocomplete .p-autocomplete-multiple-container { + padding: 0.25rem 0.75rem; + gap: 0.5rem; +} +.p-autocomplete .p-autocomplete-multiple-container .p-autocomplete-input-token { + padding: 0.25rem 0; +} +.p-autocomplete .p-autocomplete-multiple-container .p-autocomplete-input-token input { + font-family: Lato, Helvetica, sans-serif; + font-size: 1rem; + color: #e6e6e6; + padding: 0; + margin: 0; +} +.p-autocomplete .p-autocomplete-multiple-container .p-autocomplete-token { + padding: 0.25rem 0.75rem; + background: #3c3c3c; + color: #e6e6e6; + border-radius: 16px; +} +.p-autocomplete .p-autocomplete-multiple-container .p-autocomplete-token .p-autocomplete-token-icon { + margin-left: 0.5rem; +} +.p-autocomplete .p-autocomplete-multiple-container .p-autocomplete-token.p-focus { + background: #2d3e44; + color: #e6e6e6; +} +.p-autocomplete.p-invalid.p-component > .p-inputtext { + border-color: #ff9a9a; +} +.p-autocomplete-panel { + background: #212121; + color: #e6e6e6; + border: 1px solid #3c3c3c; + border-radius: 6px; + box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12); +} +.p-autocomplete-panel .p-autocomplete-items { + padding: 0.5rem 0.5rem; +} +.p-autocomplete-panel .p-autocomplete-items .p-autocomplete-item { + margin: 0 0 4px 0; + padding: 0.5rem 1rem; + border: 0 none; + color: #e6e6e6; + background: transparent; + transition: box-shadow 0.3s; + border-radius: 6px; +} +.p-autocomplete-panel .p-autocomplete-items .p-autocomplete-item.p-highlight { + color: #9eade6; + background: rgba(158, 173, 230, 0.16); +} +.p-autocomplete-panel .p-autocomplete-items .p-autocomplete-item.p-highlight.p-focus { + background: rgba(233, 170, 255, 0.24); +} +.p-autocomplete-panel .p-autocomplete-items .p-autocomplete-item:not(.p-highlight):not(.p-disabled).p-focus { + color: #e6e6e6; + background: rgba(233, 170, 255, 0.1); +} +.p-autocomplete-panel .p-autocomplete-items .p-autocomplete-item:not(.p-highlight):not(.p-disabled):hover { + color: #e6e6e6; + background: rgba(158, 173, 230, 0.08); +} +.p-autocomplete-panel .p-autocomplete-items .p-autocomplete-item-group { + margin: 0; + padding: 0.75rem 1rem; + color: #e6e6e6; + background: #212121; + font-weight: 600; +} +.p-calendar.p-invalid.p-component > .p-inputtext { + border-color: #ff9a9a; +} +.p-datepicker { + padding: 0.5rem; + background: #212121; + color: #e6e6e6; + border: 2px solid #3c3c3c; + border-radius: 6px; +} +.p-datepicker:not(.p-datepicker-inline) { + background: #212121; + border: 1px solid #3c3c3c; + box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12); +} +.p-datepicker:not(.p-datepicker-inline) .p-datepicker-header { + background: #212121; +} +.p-datepicker .p-datepicker-header { + padding: 0.5rem; + color: #e6e6e6; + background: #212121; + font-weight: 600; + margin: 0; + border-bottom: 1px solid #3c3c3c; + border-top-right-radius: 6px; + border-top-left-radius: 6px; +} +.p-datepicker .p-datepicker-header .p-datepicker-prev, +.p-datepicker .p-datepicker-header .p-datepicker-next { + width: 2rem; + height: 2rem; + color: #b3b3b3; + border: 0 none; + background: transparent; + border-radius: 50%; + transition: background-color 0.3s, color 0.3s, box-shadow 0.3s; +} +.p-datepicker .p-datepicker-header .p-datepicker-prev:enabled:hover, +.p-datepicker .p-datepicker-header .p-datepicker-next:enabled:hover { + color: #e6e6e6; + border-color: transparent; + background: rgba(158, 173, 230, 0.08); +} +.p-datepicker .p-datepicker-header .p-datepicker-prev:focus, +.p-datepicker .p-datepicker-header .p-datepicker-next:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-datepicker .p-datepicker-header .p-datepicker-title { + line-height: 2rem; +} +.p-datepicker .p-datepicker-header .p-datepicker-title .p-datepicker-year, +.p-datepicker .p-datepicker-header .p-datepicker-title .p-datepicker-month { + color: #e6e6e6; + transition: background-color 0.3s, color 0.3s, box-shadow 0.3s; + font-weight: 600; + padding: 0.5rem; +} +.p-datepicker .p-datepicker-header .p-datepicker-title .p-datepicker-year:enabled:hover, +.p-datepicker .p-datepicker-header .p-datepicker-title .p-datepicker-month:enabled:hover { + color: #e9aaff; +} +.p-datepicker .p-datepicker-header .p-datepicker-title .p-datepicker-month { + margin-right: 0.5rem; +} +.p-datepicker table { + font-size: 1rem; + margin: 0.5rem 0; +} +.p-datepicker table th { + padding: 0.5rem; +} +.p-datepicker table th > span { + width: 2.5rem; + height: 2.5rem; +} +.p-datepicker table td { + padding: 0.5rem; +} +.p-datepicker table td > span { + width: 2.5rem; + height: 2.5rem; + border-radius: 50%; + transition: box-shadow 0.3s; + border: 1px solid transparent; +} +.p-datepicker table td > span.p-highlight { + color: #9eade6; + background: rgba(158, 173, 230, 0.16); +} +.p-datepicker table td > span:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-datepicker table td.p-datepicker-today > span { + background: transparent; + color: #e9aaff; + border-color: transparent; +} +.p-datepicker table td.p-datepicker-today > span.p-highlight { + color: #9eade6; + background: rgba(158, 173, 230, 0.16); +} +.p-datepicker .p-datepicker-buttonbar { + padding: 1rem 0; + border-top: 1px solid #3c3c3c; +} +.p-datepicker .p-datepicker-buttonbar .p-button { + width: auto; +} +.p-datepicker .p-timepicker { + border-top: 1px solid #3c3c3c; + padding: 0.5rem; +} +.p-datepicker .p-timepicker button { + width: 2rem; + height: 2rem; + color: #b3b3b3; + border: 0 none; + background: transparent; + border-radius: 50%; + transition: background-color 0.3s, color 0.3s, box-shadow 0.3s; +} +.p-datepicker .p-timepicker button:enabled:hover { + color: #e6e6e6; + border-color: transparent; + background: rgba(158, 173, 230, 0.08); +} +.p-datepicker .p-timepicker button:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-datepicker .p-timepicker button:last-child { + margin-top: 0.2em; +} +.p-datepicker .p-timepicker span { + font-size: 1.25rem; +} +.p-datepicker .p-timepicker > div { + padding: 0 0.5rem; +} +.p-datepicker.p-datepicker-timeonly .p-timepicker { + border-top: 0 none; +} +.p-datepicker .p-monthpicker { + margin: 0.5rem 0; +} +.p-datepicker .p-monthpicker .p-monthpicker-month { + padding: 0.5rem; + transition: box-shadow 0.3s; + border-radius: 6px; +} +.p-datepicker .p-monthpicker .p-monthpicker-month.p-highlight { + color: #9eade6; + background: rgba(158, 173, 230, 0.16); +} +.p-datepicker .p-yearpicker { + margin: 0.5rem 0; +} +.p-datepicker .p-yearpicker .p-yearpicker-year { + padding: 0.5rem; + transition: box-shadow 0.3s; + border-radius: 6px; +} +.p-datepicker .p-yearpicker .p-yearpicker-year.p-highlight { + color: #9eade6; + background: rgba(158, 173, 230, 0.16); +} +.p-datepicker.p-datepicker-multiple-month .p-datepicker-group { + border-left: 1px solid #3c3c3c; + padding-right: 0.5rem; + padding-left: 0.5rem; + padding-top: 0; + padding-bottom: 0; +} +.p-datepicker.p-datepicker-multiple-month .p-datepicker-group:first-child { + padding-left: 0; + border-left: 0 none; +} +.p-datepicker.p-datepicker-multiple-month .p-datepicker-group:last-child { + padding-right: 0; +} +.p-datepicker:not(.p-disabled) table td span:not(.p-highlight):not(.p-disabled):hover { + background: rgba(158, 173, 230, 0.08); +} +.p-datepicker:not(.p-disabled) table td span:not(.p-highlight):not(.p-disabled):focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-datepicker:not(.p-disabled) .p-monthpicker .p-monthpicker-month:not(.p-disabled):not(.p-highlight):hover { + background: rgba(158, 173, 230, 0.08); +} +.p-datepicker:not(.p-disabled) .p-monthpicker .p-monthpicker-month:not(.p-disabled):focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-datepicker:not(.p-disabled) .p-yearpicker .p-yearpicker-year:not(.p-disabled):not(.p-highlight):hover { + background: rgba(158, 173, 230, 0.08); +} +.p-datepicker:not(.p-disabled) .p-yearpicker .p-yearpicker-year:not(.p-disabled):focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +@media screen and (max-width: 769px) { + .p-datepicker table th, + .p-datepicker table td { + padding: 0; + } +} +.p-cascadeselect { + background: #171717; + border: 2px solid #3c3c3c; + transition: background-color 0.3s, color 0.3s, border-color 0.3s, box-shadow 0.3s; + border-radius: 6px; +} +.p-cascadeselect:not(.p-disabled):hover { + border-color: #464646; +} +.p-cascadeselect:not(.p-disabled).p-focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; + border-color: #c9b1cb; +} +.p-cascadeselect .p-cascadeselect-label { + background: transparent; + border: 0 none; + padding: 0.5rem 0.75rem; +} +.p-cascadeselect .p-cascadeselect-label.p-placeholder { + color: #b3b3b3; +} +.p-cascadeselect .p-cascadeselect-label:enabled:focus { + outline: 0 none; + box-shadow: none; +} +.p-cascadeselect .p-cascadeselect-trigger { + background: transparent; + color: #b3b3b3; + width: 2.857rem; + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} +.p-cascadeselect.p-invalid.p-component { + border-color: #ff9a9a; +} +.p-cascadeselect-panel { + background: #212121; + color: #e6e6e6; + border: 1px solid #3c3c3c; + border-radius: 6px; + box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12); +} +.p-cascadeselect-panel .p-cascadeselect-items { + padding: 0.5rem 0.5rem; +} +.p-cascadeselect-panel .p-cascadeselect-items .p-cascadeselect-item { + margin: 0 0 4px 0; + border: 0 none; + color: #e6e6e6; + background: transparent; + transition: box-shadow 0.3s; + border-radius: 6px; +} +.p-cascadeselect-panel .p-cascadeselect-items .p-cascadeselect-item.p-highlight { + color: #9eade6; + background: rgba(158, 173, 230, 0.16); +} +.p-cascadeselect-panel .p-cascadeselect-items .p-cascadeselect-item.p-highlight.p-focus { + background: rgba(233, 170, 255, 0.24); +} +.p-cascadeselect-panel .p-cascadeselect-items .p-cascadeselect-item:not(.p-highlight):not(.p-disabled).p-focus { + color: #e6e6e6; + background: rgba(233, 170, 255, 0.1); +} +.p-cascadeselect-panel .p-cascadeselect-items .p-cascadeselect-item:not(.p-highlight):not(.p-disabled):hover { + color: #e6e6e6; + background: rgba(158, 173, 230, 0.08); +} +.p-cascadeselect-panel .p-cascadeselect-items .p-cascadeselect-item .p-cascadeselect-item-content { + padding: 0.5rem 1rem; +} +.p-cascadeselect-panel .p-cascadeselect-items .p-cascadeselect-item .p-cascadeselect-group-icon { + font-size: 0.875rem; +} +.p-input-filled .p-cascadeselect { + background: #171717; +} +.p-input-filled .p-cascadeselect:not(.p-disabled):hover { + background-color: #171717; +} +.p-input-filled .p-cascadeselect:not(.p-disabled).p-focus { + background-color: #171717; +} +.p-checkbox { + width: 20px; + height: 20px; +} +.p-checkbox .p-checkbox-box { + border: 2px solid #3c3c3c; + background: #171717; + width: 20px; + height: 20px; + color: #e6e6e6; + border-radius: 6px; + transition: background-color 0.3s, color 0.3s, border-color 0.3s, box-shadow 0.3s; +} +.p-checkbox .p-checkbox-box .p-checkbox-icon { + transition-duration: 0.3s; + color: #121212; + font-size: 14px; +} +.p-checkbox .p-checkbox-box .p-checkbox-icon.p-icon { + width: 14px; + height: 14px; +} +.p-checkbox .p-checkbox-box.p-highlight { + border-color: #e9aaff; + background: #e9aaff; +} +.p-checkbox:not(.p-checkbox-disabled) .p-checkbox-box:hover { + border-color: #464646; +} +.p-checkbox:not(.p-checkbox-disabled) .p-checkbox-box.p-focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; + border-color: #c9b1cb; +} +.p-checkbox:not(.p-checkbox-disabled) .p-checkbox-box.p-highlight:hover { + border-color: #de80ff; + background: #de80ff; + color: #121212; +} +.p-checkbox.p-invalid > .p-checkbox-box { + border-color: #ff9a9a; +} +.p-input-filled .p-checkbox .p-checkbox-box { + background-color: #171717; +} +.p-input-filled .p-checkbox .p-checkbox-box.p-highlight { + background: #e9aaff; +} +.p-input-filled .p-checkbox:not(.p-checkbox-disabled) .p-checkbox-box:hover { + background-color: #171717; +} +.p-input-filled .p-checkbox:not(.p-checkbox-disabled) .p-checkbox-box.p-highlight:hover { + background: #de80ff; +} +.p-chips:not(.p-disabled):hover .p-chips-multiple-container { + border-color: #464646; +} +.p-chips:not(.p-disabled).p-focus .p-chips-multiple-container { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; + border-color: #c9b1cb; +} +.p-chips .p-chips-multiple-container { + padding: 0.25rem 0.75rem; +} +.p-chips .p-chips-multiple-container .p-chips-token { + padding: 0.25rem 0.75rem; + margin-right: 0.5rem; + background: #3c3c3c; + color: #e6e6e6; + border-radius: 16px; +} +.p-chips .p-chips-multiple-container .p-chips-token.p-focus { + background: #2d3e44; + color: #e6e6e6; +} +.p-chips .p-chips-multiple-container .p-chips-token .p-chips-token-icon { + margin-left: 0.5rem; +} +.p-chips .p-chips-multiple-container .p-chips-input-token { + padding: 0.25rem 0; +} +.p-chips .p-chips-multiple-container .p-chips-input-token input { + font-family: Lato, Helvetica, sans-serif; + font-size: 1rem; + color: #e6e6e6; + padding: 0; + margin: 0; +} +.p-chips.p-invalid.p-component > .p-inputtext { + border-color: #ff9a9a; +} +.p-colorpicker-preview { + width: 2rem; + height: 2rem; +} +.p-colorpicker-panel { + background: #212121; + border: 1px solid #3c3c3c; +} +.p-colorpicker-panel .p-colorpicker-color-handle, +.p-colorpicker-panel .p-colorpicker-hue-handle { + border-color: #e6e6e6; +} +.p-colorpicker-overlay-panel { + box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12); +} +.p-dropdown { + background: #171717; + border: 2px solid #3c3c3c; + transition: background-color 0.3s, color 0.3s, border-color 0.3s, box-shadow 0.3s; + border-radius: 6px; +} +.p-dropdown:not(.p-disabled):hover { + border-color: #464646; +} +.p-dropdown:not(.p-disabled).p-focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; + border-color: #c9b1cb; +} +.p-dropdown.p-dropdown-clearable .p-dropdown-label { + padding-right: 1.75rem; +} +.p-dropdown .p-dropdown-label { + background: transparent; + border: 0 none; +} +.p-dropdown .p-dropdown-label.p-placeholder { + color: #b3b3b3; +} +.p-dropdown .p-dropdown-label:focus, +.p-dropdown .p-dropdown-label:enabled:focus { + outline: 0 none; + box-shadow: none; +} +.p-dropdown .p-dropdown-trigger { + background: transparent; + color: #b3b3b3; + width: 2.857rem; + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} +.p-dropdown .p-dropdown-clear-icon { + color: #b3b3b3; + right: 2.857rem; +} +.p-dropdown.p-invalid.p-component { + border-color: #ff9a9a; +} +.p-dropdown-panel { + background: #212121; + color: #e6e6e6; + border: 1px solid #3c3c3c; + border-radius: 6px; + box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12); +} +.p-dropdown-panel .p-dropdown-header { + padding: 0.5rem 1.5rem; + border-bottom: 0 none; + color: #e6e6e6; + background: #212121; + margin: 0; + border-top-right-radius: 6px; + border-top-left-radius: 6px; +} +.p-dropdown-panel .p-dropdown-header .p-dropdown-filter { + padding-right: 1.75rem; + margin-right: -1.75rem; +} +.p-dropdown-panel .p-dropdown-header .p-dropdown-filter-icon { + right: 0.75rem; + color: #b3b3b3; +} +.p-dropdown-panel .p-dropdown-items { + padding: 0.5rem 0.5rem; +} +.p-dropdown-panel .p-dropdown-items .p-dropdown-item { + margin: 0 0 4px 0; + padding: 0.5rem 1rem; + border: 0 none; + color: #e6e6e6; + background: transparent; + transition: box-shadow 0.3s; + border-radius: 6px; +} +.p-dropdown-panel .p-dropdown-items .p-dropdown-item.p-highlight { + color: #9eade6; + background: rgba(158, 173, 230, 0.16); +} +.p-dropdown-panel .p-dropdown-items .p-dropdown-item.p-highlight.p-focus { + background: rgba(233, 170, 255, 0.24); +} +.p-dropdown-panel .p-dropdown-items .p-dropdown-item:not(.p-highlight):not(.p-disabled).p-focus { + color: #e6e6e6; + background: rgba(233, 170, 255, 0.1); +} +.p-dropdown-panel .p-dropdown-items .p-dropdown-item:not(.p-highlight):not(.p-disabled):hover { + color: #e6e6e6; + background: rgba(158, 173, 230, 0.08); +} +.p-dropdown-panel .p-dropdown-items .p-dropdown-item-group { + margin: 0; + padding: 0.75rem 1rem; + color: #e6e6e6; + background: #212121; + font-weight: 600; +} +.p-dropdown-panel .p-dropdown-items .p-dropdown-empty-message { + padding: 0.5rem 1rem; + color: #e6e6e6; + background: transparent; +} +.p-input-filled .p-dropdown { + background: #171717; +} +.p-input-filled .p-dropdown:not(.p-disabled):hover { + background-color: #171717; +} +.p-input-filled .p-dropdown:not(.p-disabled).p-focus { + background-color: #171717; +} +.p-input-filled .p-dropdown:not(.p-disabled).p-focus .p-inputtext { + background-color: transparent; +} +.p-editor-container .p-editor-toolbar { + background: #212121; + border-top-right-radius: 6px; + border-top-left-radius: 6px; +} +.p-editor-container .p-editor-toolbar.ql-snow { + border: 2px solid #3c3c3c; +} +.p-editor-container .p-editor-toolbar.ql-snow .ql-stroke { + stroke: #b3b3b3; +} +.p-editor-container .p-editor-toolbar.ql-snow .ql-fill { + fill: #b3b3b3; +} +.p-editor-container .p-editor-toolbar.ql-snow .ql-picker .ql-picker-label { + border: 0 none; + color: #b3b3b3; +} +.p-editor-container .p-editor-toolbar.ql-snow .ql-picker .ql-picker-label:hover { + color: #e6e6e6; +} +.p-editor-container .p-editor-toolbar.ql-snow .ql-picker .ql-picker-label:hover .ql-stroke { + stroke: #e6e6e6; +} +.p-editor-container .p-editor-toolbar.ql-snow .ql-picker .ql-picker-label:hover .ql-fill { + fill: #e6e6e6; +} +.p-editor-container .p-editor-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-label { + color: #e6e6e6; +} +.p-editor-container .p-editor-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-label .ql-stroke { + stroke: #e6e6e6; +} +.p-editor-container .p-editor-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-label .ql-fill { + fill: #e6e6e6; +} +.p-editor-container .p-editor-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-options { + background: #212121; + border: 1px solid #3c3c3c; + box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12); + border-radius: 6px; + padding: 0.5rem 0.5rem; +} +.p-editor-container .p-editor-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-options .ql-picker-item { + color: #e6e6e6; +} +.p-editor-container .p-editor-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-options .ql-picker-item:hover { + color: #e6e6e6; + background: rgba(158, 173, 230, 0.08); +} +.p-editor-container .p-editor-toolbar.ql-snow .ql-picker.ql-expanded:not(.ql-icon-picker) .ql-picker-item { + padding: 0.5rem 1rem; +} +.p-editor-container .p-editor-content { + border-bottom-right-radius: 6px; + border-bottom-left-radius: 6px; +} +.p-editor-container .p-editor-content.ql-snow { + border: 2px solid #3c3c3c; +} +.p-editor-container .p-editor-content .ql-editor { + background: #171717; + color: #e6e6e6; + border-bottom-right-radius: 6px; + border-bottom-left-radius: 6px; +} +.p-editor-container .ql-snow.ql-toolbar button:hover, +.p-editor-container .ql-snow.ql-toolbar button:focus { + color: #e6e6e6; +} +.p-editor-container .ql-snow.ql-toolbar button:hover .ql-stroke, +.p-editor-container .ql-snow.ql-toolbar button:focus .ql-stroke { + stroke: #e6e6e6; +} +.p-editor-container .ql-snow.ql-toolbar button:hover .ql-fill, +.p-editor-container .ql-snow.ql-toolbar button:focus .ql-fill { + fill: #e6e6e6; +} +.p-editor-container .ql-snow.ql-toolbar button.ql-active, +.p-editor-container .ql-snow.ql-toolbar .ql-picker-label.ql-active, +.p-editor-container .ql-snow.ql-toolbar .ql-picker-item.ql-selected { + color: #e9aaff; +} +.p-editor-container .ql-snow.ql-toolbar button.ql-active .ql-stroke, +.p-editor-container .ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-stroke, +.p-editor-container .ql-snow.ql-toolbar .ql-picker-item.ql-selected .ql-stroke { + stroke: #e9aaff; +} +.p-editor-container .ql-snow.ql-toolbar button.ql-active .ql-fill, +.p-editor-container .ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-fill, +.p-editor-container .ql-snow.ql-toolbar .ql-picker-item.ql-selected .ql-fill { + fill: #e9aaff; +} +.p-editor-container .ql-snow.ql-toolbar button.ql-active .ql-picker-label, +.p-editor-container .ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-picker-label, +.p-editor-container .ql-snow.ql-toolbar .ql-picker-item.ql-selected .ql-picker-label { + color: #e9aaff; +} +.p-inputgroup-addon { + background: #212121; + color: #b3b3b3; + border-top: 2px solid #3c3c3c; + border-left: 2px solid #3c3c3c; + border-bottom: 2px solid #3c3c3c; + padding: 0.5rem 0.75rem; + min-width: 2.857rem; +} +.p-inputgroup-addon:last-child { + border-right: 2px solid #3c3c3c; +} +.p-inputgroup > .p-component, +.p-inputgroup > .p-inputwrapper > .p-inputtext, +.p-inputgroup > .p-float-label > .p-component { + border-radius: 0; + margin: 0; +} +.p-inputgroup > .p-component + .p-inputgroup-addon, +.p-inputgroup > .p-inputwrapper > .p-inputtext + .p-inputgroup-addon, +.p-inputgroup > .p-float-label > .p-component + .p-inputgroup-addon { + border-left: 0 none; +} +.p-inputgroup > .p-component:focus, +.p-inputgroup > .p-inputwrapper > .p-inputtext:focus, +.p-inputgroup > .p-float-label > .p-component:focus { + z-index: 1; +} +.p-inputgroup > .p-component:focus ~ label, +.p-inputgroup > .p-inputwrapper > .p-inputtext:focus ~ label, +.p-inputgroup > .p-float-label > .p-component:focus ~ label { + z-index: 1; +} +.p-inputgroup-addon:first-child, +.p-inputgroup button:first-child, +.p-inputgroup input:first-child, +.p-inputgroup > .p-inputwrapper:first-child, +.p-inputgroup > .p-inputwrapper:first-child > .p-inputtext { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; +} +.p-inputgroup .p-float-label:first-child input { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; +} +.p-inputgroup-addon:last-child, +.p-inputgroup button:last-child, +.p-inputgroup input:last-child, +.p-inputgroup > .p-inputwrapper:last-child, +.p-inputgroup > .p-inputwrapper:last-child > .p-inputtext { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} +.p-inputgroup .p-float-label:last-child input { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} +.p-fluid .p-inputgroup .p-button { + width: auto; +} +.p-fluid .p-inputgroup .p-button.p-button-icon-only { + width: 2.857rem; +} +.p-inputnumber.p-invalid.p-component > .p-inputtext { + border-color: #ff9a9a; +} +.p-inputswitch { + width: 3rem; + height: 1.75rem; +} +.p-inputswitch .p-inputswitch-slider { + background: #3c3c3c; + transition: background-color 0.3s, color 0.3s, border-color 0.3s, box-shadow 0.3s; + border-radius: 6px; +} +.p-inputswitch .p-inputswitch-slider:before { + background: #b3b3b3; + width: 1.25rem; + height: 1.25rem; + left: 0.25rem; + margin-top: -0.625rem; + border-radius: 6px; + transition-duration: 0.3s; +} +.p-inputswitch.p-inputswitch-checked .p-inputswitch-slider:before { + transform: translateX(1.25rem); +} +.p-inputswitch.p-focus .p-inputswitch-slider { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-inputswitch:not(.p-disabled):hover .p-inputswitch-slider { + background: rgba(158, 173, 230, 0.08); +} +.p-inputswitch.p-inputswitch-checked .p-inputswitch-slider { + background: #e9aaff; +} +.p-inputswitch.p-inputswitch-checked .p-inputswitch-slider:before { + background: #e6e6e6; +} +.p-inputswitch.p-inputswitch-checked:not(.p-disabled):hover .p-inputswitch-slider { + background: #e495ff; +} +.p-inputswitch.p-invalid .p-inputswitch-slider { + border-color: #ff9a9a; +} +.p-inputtext { + font-family: Lato, Helvetica, sans-serif; + font-size: 1rem; + color: #e6e6e6; + background: #171717; + padding: 0.5rem 0.75rem; + border: 2px solid #3c3c3c; + transition: background-color 0.3s, color 0.3s, border-color 0.3s, box-shadow 0.3s; + appearance: none; + border-radius: 6px; +} +.p-inputtext:enabled:hover { + border-color: #464646; +} +.p-inputtext:enabled:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; + border-color: #c9b1cb; +} +.p-inputtext.p-invalid.p-component { + border-color: #ff9a9a; +} +.p-inputtext.p-inputtext-sm { + font-size: 0.875rem; + padding: 0.4375rem 0.65625rem; +} +.p-inputtext.p-inputtext-lg { + font-size: 1.25rem; + padding: 0.625rem 0.9375rem; +} +.p-float-label > label { + left: 0.75rem; + color: #b3b3b3; + transition-duration: 0.3s; +} +.p-float-label > .p-invalid + label { + color: #ff9a9a; +} +.p-input-icon-left > svg:first-of-type, +.p-input-icon-left > i:first-of-type { + left: 0.75rem; + color: #b3b3b3; +} +.p-input-icon-left > .p-inputtext { + padding-left: 2.5rem; +} +.p-input-icon-left.p-float-label > label { + left: 2.5rem; +} +.p-input-icon-right > svg:last-of-type, +.p-input-icon-right > i:last-of-type { + right: 0.75rem; + color: #b3b3b3; +} +.p-input-icon-right > .p-inputtext { + padding-right: 2.5rem; +} +::-webkit-input-placeholder { + color: #b3b3b3; +} +:-moz-placeholder { + color: #b3b3b3; +} +::-moz-placeholder { + color: #b3b3b3; +} +:-ms-input-placeholder { + color: #b3b3b3; +} +.p-input-filled .p-inputtext { + background-color: #171717; +} +.p-input-filled .p-inputtext:enabled:hover { + background-color: #171717; +} +.p-input-filled .p-inputtext:enabled:focus { + background-color: #171717; +} +.p-inputtext-sm .p-inputtext { + font-size: 0.875rem; + padding: 0.4375rem 0.65625rem; +} +.p-inputtext-lg .p-inputtext { + font-size: 1.25rem; + padding: 0.625rem 0.9375rem; +} +.p-listbox { + background: #212121; + color: #e6e6e6; + border: 2px solid #3c3c3c; + border-radius: 6px; + transition: background-color 0.3s, color 0.3s, border-color 0.3s, box-shadow 0.3s; +} +.p-listbox .p-listbox-header { + padding: 0.5rem 1.5rem; + border-bottom: 0 none; + color: #e6e6e6; + background: #212121; + margin: 0; + border-top-right-radius: 6px; + border-top-left-radius: 6px; +} +.p-listbox .p-listbox-header .p-listbox-filter { + padding-right: 1.75rem; +} +.p-listbox .p-listbox-header .p-listbox-filter-icon { + right: 0.75rem; + color: #b3b3b3; +} +.p-listbox .p-listbox-list { + padding: 0.5rem 0.5rem; + outline: 0 none; +} +.p-listbox .p-listbox-list .p-listbox-item { + margin: 0 0 4px 0; + padding: 0.5rem 1rem; + border: 0 none; + color: #e6e6e6; + transition: box-shadow 0.3s; + border-radius: 6px; +} +.p-listbox .p-listbox-list .p-listbox-item.p-highlight { + color: #9eade6; + background: rgba(158, 173, 230, 0.16); +} +.p-listbox .p-listbox-list .p-listbox-item-group { + margin: 0; + padding: 0.75rem 1rem; + color: #e6e6e6; + background: #212121; + font-weight: 600; +} +.p-listbox .p-listbox-list .p-listbox-empty-message { + padding: 0.5rem 1rem; + color: #e6e6e6; + background: transparent; +} +.p-listbox:not(.p-disabled) .p-listbox-item.p-highlight.p-focus { + background: rgba(233, 170, 255, 0.24); +} +.p-listbox:not(.p-disabled) .p-listbox-item:not(.p-highlight):not(.p-disabled).p-focus { + color: #e6e6e6; + background: rgba(233, 170, 255, 0.1); +} +.p-listbox:not(.p-disabled) .p-listbox-item:not(.p-highlight):not(.p-disabled):hover { + color: #e6e6e6; + background: rgba(158, 173, 230, 0.08); +} +.p-listbox.p-focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; + border-color: #c9b1cb; +} +.p-listbox.p-invalid { + border-color: #ff9a9a; +} +.p-multiselect { + background: #171717; + border: 2px solid #3c3c3c; + transition: background-color 0.3s, color 0.3s, border-color 0.3s, box-shadow 0.3s; + border-radius: 6px; +} +.p-multiselect:not(.p-disabled):hover { + border-color: #464646; +} +.p-multiselect:not(.p-disabled).p-focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; + border-color: #c9b1cb; +} +.p-multiselect .p-multiselect-label { + padding: 0.5rem 0.75rem; + transition: background-color 0.3s, color 0.3s, border-color 0.3s, box-shadow 0.3s; +} +.p-multiselect .p-multiselect-label.p-placeholder { + color: #b3b3b3; +} +.p-multiselect.p-multiselect-chip .p-multiselect-token { + padding: 0.25rem 0.75rem; + margin-right: 0.5rem; + background: #3c3c3c; + color: #e6e6e6; + border-radius: 16px; +} +.p-multiselect.p-multiselect-chip .p-multiselect-token .p-multiselect-token-icon { + margin-left: 0.5rem; +} +.p-multiselect .p-multiselect-trigger { + background: transparent; + color: #b3b3b3; + width: 2.857rem; + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} +.p-multiselect.p-invalid.p-component { + border-color: #ff9a9a; +} +.p-inputwrapper-filled.p-multiselect.p-multiselect-chip .p-multiselect-label { + padding: 0.25rem 0.75rem; +} +.p-multiselect-panel { + background: #212121; + color: #e6e6e6; + border: 1px solid #3c3c3c; + border-radius: 6px; + box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12); +} +.p-multiselect-panel .p-multiselect-header { + padding: 0.5rem 1.5rem; + border-bottom: 0 none; + color: #e6e6e6; + background: #212121; + margin: 0; + border-top-right-radius: 6px; + border-top-left-radius: 6px; +} +.p-multiselect-panel .p-multiselect-header .p-multiselect-filter-container .p-inputtext { + padding-right: 1.75rem; +} +.p-multiselect-panel .p-multiselect-header .p-multiselect-filter-container .p-multiselect-filter-icon { + right: 0.75rem; + color: #b3b3b3; +} +.p-multiselect-panel .p-multiselect-header .p-checkbox { + margin-right: 0.5rem; +} +.p-multiselect-panel .p-multiselect-header .p-multiselect-close { + margin-left: 0.5rem; + width: 2rem; + height: 2rem; + color: #b3b3b3; + border: 0 none; + background: transparent; + border-radius: 50%; + transition: background-color 0.3s, color 0.3s, box-shadow 0.3s; +} +.p-multiselect-panel .p-multiselect-header .p-multiselect-close:enabled:hover { + color: #e6e6e6; + border-color: transparent; + background: rgba(158, 173, 230, 0.08); +} +.p-multiselect-panel .p-multiselect-header .p-multiselect-close:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-multiselect-panel .p-multiselect-items { + padding: 0.5rem 0.5rem; +} +.p-multiselect-panel .p-multiselect-items .p-multiselect-item { + margin: 0 0 4px 0; + padding: 0.5rem 1rem; + border: 0 none; + color: #e6e6e6; + background: transparent; + transition: box-shadow 0.3s; + border-radius: 6px; +} +.p-multiselect-panel .p-multiselect-items .p-multiselect-item.p-highlight { + color: #9eade6; + background: rgba(158, 173, 230, 0.16); +} +.p-multiselect-panel .p-multiselect-items .p-multiselect-item.p-highlight.p-focus { + background: rgba(233, 170, 255, 0.24); +} +.p-multiselect-panel .p-multiselect-items .p-multiselect-item:not(.p-highlight):not(.p-disabled).p-focus { + color: #e6e6e6; + background: rgba(233, 170, 255, 0.1); +} +.p-multiselect-panel .p-multiselect-items .p-multiselect-item:not(.p-highlight):not(.p-disabled):hover { + color: #e6e6e6; + background: rgba(158, 173, 230, 0.08); +} +.p-multiselect-panel .p-multiselect-items .p-multiselect-item .p-checkbox { + margin-right: 0.5rem; +} +.p-multiselect-panel .p-multiselect-items .p-multiselect-item-group { + margin: 0; + padding: 0.75rem 1rem; + color: #e6e6e6; + background: #212121; + font-weight: 600; +} +.p-multiselect-panel .p-multiselect-items .p-multiselect-empty-message { + padding: 0.5rem 1rem; + color: #e6e6e6; + background: transparent; +} +.p-input-filled .p-multiselect { + background: #171717; +} +.p-input-filled .p-multiselect:not(.p-disabled):hover { + background-color: #171717; +} +.p-input-filled .p-multiselect:not(.p-disabled).p-focus { + background-color: #171717; +} +.p-password.p-invalid.p-component > .p-inputtext { + border-color: #ff9a9a; +} +.p-password-panel { + padding: 1rem; + background: #212121; + color: #e6e6e6; + border: 2px solid #3c3c3c; + box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12); + border-radius: 6px; +} +.p-password-panel .p-password-meter { + margin-bottom: 0.5rem; + background: #3c3c3c; +} +.p-password-panel .p-password-meter .p-password-strength.weak { + background: #e693a9; +} +.p-password-panel .p-password-meter .p-password-strength.medium { + background: #ffe08a; +} +.p-password-panel .p-password-meter .p-password-strength.strong { + background: #cede9c; +} +.p-radiobutton { + width: 20px; + height: 20px; +} +.p-radiobutton .p-radiobutton-box { + border: 2px solid #3c3c3c; + background: #171717; + width: 20px; + height: 20px; + color: #e6e6e6; + border-radius: 50%; + transition: background-color 0.3s, color 0.3s, border-color 0.3s, box-shadow 0.3s; +} +.p-radiobutton .p-radiobutton-box:not(.p-disabled):not(.p-highlight):hover { + border-color: #464646; +} +.p-radiobutton .p-radiobutton-box:not(.p-disabled).p-focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; + border-color: #c9b1cb; +} +.p-radiobutton .p-radiobutton-box .p-radiobutton-icon { + width: 12px; + height: 12px; + transition-duration: 0.3s; + background-color: #121212; +} +.p-radiobutton .p-radiobutton-box.p-highlight { + border-color: #e9aaff; + background: #e9aaff; +} +.p-radiobutton .p-radiobutton-box.p-highlight:not(.p-disabled):hover { + border-color: #de80ff; + background: #de80ff; + color: #121212; +} +.p-radiobutton.p-invalid > .p-radiobutton-box { + border-color: #ff9a9a; +} +.p-radiobutton:focus { + outline: 0 none; +} +.p-input-filled .p-radiobutton .p-radiobutton-box { + background-color: #171717; +} +.p-input-filled .p-radiobutton .p-radiobutton-box:not(.p-disabled):hover { + background-color: #171717; +} +.p-input-filled .p-radiobutton .p-radiobutton-box.p-highlight { + background: #e9aaff; +} +.p-input-filled .p-radiobutton .p-radiobutton-box.p-highlight:not(.p-disabled):hover { + background: #de80ff; +} +.p-rating { + gap: 0.5rem; +} +.p-rating .p-rating-item .p-rating-icon { + color: #e6e6e6; + transition: background-color 0.3s, color 0.3s, border-color 0.3s, box-shadow 0.3s; + font-size: 1.143rem; +} +.p-rating .p-rating-item .p-rating-icon.p-icon { + width: 1.143rem; + height: 1.143rem; +} +.p-rating .p-rating-item .p-rating-icon.p-rating-cancel { + color: #df7e6c; +} +.p-rating .p-rating-item.p-focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; + border-color: #c9b1cb; +} +.p-rating .p-rating-item.p-rating-item-active .p-rating-icon { + color: #e9aaff; +} +.p-rating:not(.p-disabled):not(.p-readonly) .p-rating-item:hover .p-rating-icon { + color: #e9aaff; +} +.p-rating:not(.p-disabled):not(.p-readonly) .p-rating-item:hover .p-rating-icon.p-rating-cancel { + color: #f88c79; +} +.p-selectbutton .p-button { + background: #212121; + border: 2px solid #3c3c3c; + color: #e6e6e6; + transition: background-color 0.3s, color 0.3s, border-color 0.3s, box-shadow 0.3s; +} +.p-selectbutton .p-button .p-button-icon-left, +.p-selectbutton .p-button .p-button-icon-right { + color: #b3b3b3; +} +.p-selectbutton .p-button:not(.p-disabled):not(.p-highlight):hover { + background: rgba(158, 173, 230, 0.08); + border-color: #3c3c3c; + color: #e6e6e6; +} +.p-selectbutton .p-button:not(.p-disabled):not(.p-highlight):hover .p-button-icon-left, +.p-selectbutton .p-button:not(.p-disabled):not(.p-highlight):hover .p-button-icon-right { + color: #b3b3b3; +} +.p-selectbutton .p-button.p-highlight { + background: rgba(158, 173, 230, 0.16); + border-color: rgba(158, 173, 230, 0.16); + color: #9eade6; +} +.p-selectbutton .p-button.p-highlight .p-button-icon-left, +.p-selectbutton .p-button.p-highlight .p-button-icon-right { + color: #9eade6; +} +.p-selectbutton .p-button.p-highlight:hover { + background: rgba(233, 170, 255, 0.24); + border-color: rgba(233, 170, 255, 0.24); + color: #9eade6; +} +.p-selectbutton .p-button.p-highlight:hover .p-button-icon-left, +.p-selectbutton .p-button.p-highlight:hover .p-button-icon-right { + color: #9eade6; +} +.p-selectbutton.p-invalid > .p-button { + border-color: #ff9a9a; +} +.p-slider { + background: #3c3c3c; + border: 0 none; + border-radius: 6px; +} +.p-slider.p-slider-horizontal { + height: 0.286rem; +} +.p-slider.p-slider-horizontal .p-slider-handle { + margin-top: -0.5715rem; + margin-left: -0.5715rem; +} +.p-slider.p-slider-vertical { + width: 0.286rem; +} +.p-slider.p-slider-vertical .p-slider-handle { + margin-left: -0.5715rem; + margin-bottom: -0.5715rem; +} +.p-slider .p-slider-handle { + height: 1.143rem; + width: 1.143rem; + background: #3c3c3c; + border: 2px solid #e9aaff; + border-radius: 50%; + transition: background-color 0.3s, color 0.3s, border-color 0.3s, box-shadow 0.3s; +} +.p-slider .p-slider-handle:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-slider .p-slider-range { + background: #e9aaff; +} +.p-slider:not(.p-disabled) .p-slider-handle:hover { + background: #e9aaff; + border-color: #e9aaff; +} +.p-treeselect { + background: #171717; + border: 2px solid #3c3c3c; + transition: background-color 0.3s, color 0.3s, border-color 0.3s, box-shadow 0.3s; + border-radius: 6px; +} +.p-treeselect:not(.p-disabled):hover { + border-color: #464646; +} +.p-treeselect:not(.p-disabled).p-focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; + border-color: #c9b1cb; +} +.p-treeselect .p-treeselect-label { + padding: 0.5rem 0.75rem; + transition: background-color 0.3s, color 0.3s, border-color 0.3s, box-shadow 0.3s; +} +.p-treeselect .p-treeselect-label.p-placeholder { + color: #b3b3b3; +} +.p-treeselect.p-treeselect-chip .p-treeselect-token { + padding: 0.25rem 0.75rem; + margin-right: 0.5rem; + background: #3c3c3c; + color: #e6e6e6; + border-radius: 16px; +} +.p-treeselect .p-treeselect-trigger { + background: transparent; + color: #b3b3b3; + width: 2.857rem; + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} +.p-treeselect.p-invalid.p-component { + border-color: #ff9a9a; +} +.p-inputwrapper-filled.p-treeselect.p-treeselect-chip .p-treeselect-label { + padding: 0.25rem 0.75rem; +} +.p-treeselect-panel { + background: #212121; + color: #e6e6e6; + border: 1px solid #3c3c3c; + border-radius: 6px; + box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12); +} +.p-treeselect-panel .p-treeselect-items-wrapper .p-tree { + border: 0 none; +} +.p-treeselect-panel .p-treeselect-items-wrapper .p-treeselect-empty-message { + padding: 0.5rem 1rem; + color: #e6e6e6; + background: transparent; +} +.p-input-filled .p-treeselect { + background: #171717; +} +.p-input-filled .p-treeselect:not(.p-disabled):hover { + background-color: #171717; +} +.p-input-filled .p-treeselect:not(.p-disabled).p-focus { + background-color: #171717; +} +.p-togglebutton.p-button { + background: #212121; + border: 2px solid #3c3c3c; + color: #e6e6e6; + transition: background-color 0.3s, color 0.3s, border-color 0.3s, box-shadow 0.3s; +} +.p-togglebutton.p-button .p-button-icon-left, +.p-togglebutton.p-button .p-button-icon-right { + color: #b3b3b3; +} +.p-togglebutton.p-button:not(.p-disabled).p-focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; + border-color: #c9b1cb; +} +.p-togglebutton.p-button:not(.p-disabled):not(.p-highlight):hover { + background: rgba(158, 173, 230, 0.08); + border-color: #3c3c3c; + color: #e6e6e6; +} +.p-togglebutton.p-button:not(.p-disabled):not(.p-highlight):hover .p-button-icon-left, +.p-togglebutton.p-button:not(.p-disabled):not(.p-highlight):hover .p-button-icon-right { + color: #b3b3b3; +} +.p-togglebutton.p-button.p-highlight { + background: rgba(158, 173, 230, 0.16); + border-color: rgba(158, 173, 230, 0.16); + color: #9eade6; +} +.p-togglebutton.p-button.p-highlight .p-button-icon-left, +.p-togglebutton.p-button.p-highlight .p-button-icon-right { + color: #9eade6; +} +.p-togglebutton.p-button.p-highlight:hover { + background: rgba(233, 170, 255, 0.24); + border-color: rgba(233, 170, 255, 0.24); + color: #9eade6; +} +.p-togglebutton.p-button.p-highlight:hover .p-button-icon-left, +.p-togglebutton.p-button.p-highlight:hover .p-button-icon-right { + color: #9eade6; +} +.p-togglebutton.p-button.p-invalid > .p-button { + border-color: #ff9a9a; +} +.p-button { + color: #121212; + background: #e9aaff; + border: 2px solid #e9aaff; + padding: 0.5rem 1rem; + font-size: 1rem; + transition: background-color 0.3s, color 0.3s, border-color 0.3s, box-shadow 0.3s; + border-radius: 6px; +} +.p-button:enabled:hover { + background: #e495ff; + color: #121212; + border-color: #e495ff; +} +.p-button:enabled:active { + background: #de80ff; + color: #121212; + border-color: #de80ff; +} +.p-button.p-button-outlined { + background-color: transparent; + color: #e9aaff; + border: 2px solid; +} +.p-button.p-button-outlined:enabled:hover { + background: rgba(233, 170, 255, 0.04); + color: #e9aaff; + border: 2px solid; +} +.p-button.p-button-outlined:enabled:active { + background: rgba(233, 170, 255, 0.16); + color: #e9aaff; + border: 2px solid; +} +.p-button.p-button-outlined.p-button-plain { + color: #b3b3b3; + border-color: #b3b3b3; +} +.p-button.p-button-outlined.p-button-plain:enabled:hover { + background: rgba(158, 173, 230, 0.08); + color: #b3b3b3; +} +.p-button.p-button-outlined.p-button-plain:enabled:active { + background: rgba(255, 255, 255, 0.16); + color: #b3b3b3; +} +.p-button.p-button-text { + background-color: transparent; + color: #e9aaff; + border-color: transparent; +} +.p-button.p-button-text:enabled:hover { + background: rgba(233, 170, 255, 0.04); + color: #e9aaff; + border-color: transparent; +} +.p-button.p-button-text:enabled:active { + background: rgba(233, 170, 255, 0.16); + color: #e9aaff; + border-color: transparent; +} +.p-button.p-button-text.p-button-plain { + color: #b3b3b3; +} +.p-button.p-button-text.p-button-plain:enabled:hover { + background: rgba(158, 173, 230, 0.08); + color: #b3b3b3; +} +.p-button.p-button-text.p-button-plain:enabled:active { + background: rgba(255, 255, 255, 0.16); + color: #b3b3b3; +} +.p-button:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-button .p-button-label { + transition-duration: 0.3s; +} +.p-button .p-button-icon-left { + margin-right: 0.5rem; +} +.p-button .p-button-icon-right { + margin-left: 0.5rem; +} +.p-button .p-button-icon-bottom { + margin-top: 0.5rem; +} +.p-button .p-button-icon-top { + margin-bottom: 0.5rem; +} +.p-button .p-badge { + margin-left: 0.5rem; + min-width: 1rem; + height: 1rem; + line-height: 1rem; + color: #e9aaff; + background-color: #121212; +} +.p-button.p-button-raised { + box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), + 0px 1px 5px 0px rgba(0, 0, 0, 0.12); +} +.p-button.p-button-rounded { + border-radius: 2rem; +} +.p-button.p-button-icon-only { + width: 2.857rem; + padding: 0.5rem 0; +} +.p-button.p-button-icon-only .p-button-icon-left, +.p-button.p-button-icon-only .p-button-icon-right { + margin: 0; +} +.p-button.p-button-icon-only.p-button-rounded { + border-radius: 50%; + height: 2.857rem; +} +.p-button.p-button-sm { + font-size: 0.875rem; + padding: 0.4375rem 0.875rem; +} +.p-button.p-button-sm .p-button-icon { + font-size: 0.875rem; +} +.p-button.p-button-lg { + font-size: 1.25rem; + padding: 0.625rem 1.25rem; +} +.p-button.p-button-lg .p-button-icon { + font-size: 1.25rem; +} +.p-button.p-button-loading-label-only .p-button-label { + margin-left: 0.5rem; +} +.p-button.p-button-loading-label-only .p-button-loading-icon { + margin-right: 0; +} +.p-fluid .p-button { + width: 100%; +} +.p-fluid .p-button-icon-only { + width: 2.857rem; +} +.p-fluid .p-buttonset { + display: flex; +} +.p-fluid .p-buttonset .p-button { + flex: 1; +} +.p-button.p-button-secondary, +.p-buttonset.p-button-secondary > .p-button, +.p-splitbutton.p-button-secondary > .p-button { + color: #131313; + background: #9ec1ff; + border: 1px solid #9ec1ff; +} +.p-button.p-button-secondary:enabled:hover, +.p-buttonset.p-button-secondary > .p-button:enabled:hover, +.p-splitbutton.p-button-secondary > .p-button:enabled:hover { + background: #75a7ff; + color: #131313; + border-color: #75a7ff; +} +.p-button.p-button-secondary:enabled:focus, +.p-buttonset.p-button-secondary > .p-button:enabled:focus, +.p-splitbutton.p-button-secondary > .p-button:enabled:focus { + box-shadow: 1px #d8e6ff; +} +.p-button.p-button-secondary:enabled:active, +.p-buttonset.p-button-secondary > .p-button:enabled:active, +.p-splitbutton.p-button-secondary > .p-button:enabled:active { + background: #4b8cff; + color: #131313; + border-color: #4b8cff; +} +.p-button.p-button-secondary.p-button-outlined, +.p-buttonset.p-button-secondary > .p-button.p-button-outlined, +.p-splitbutton.p-button-secondary > .p-button.p-button-outlined { + background-color: transparent; + color: #9ec1ff; + border: 2px solid; +} +.p-button.p-button-secondary.p-button-outlined:enabled:hover, +.p-buttonset.p-button-secondary > .p-button.p-button-outlined:enabled:hover, +.p-splitbutton.p-button-secondary > .p-button.p-button-outlined:enabled:hover { + background: rgba(158, 193, 255, 0.04); + color: #9ec1ff; + border: 2px solid; +} +.p-button.p-button-secondary.p-button-outlined:enabled:active, +.p-buttonset.p-button-secondary > .p-button.p-button-outlined:enabled:active, +.p-splitbutton.p-button-secondary > .p-button.p-button-outlined:enabled:active { + background: rgba(158, 193, 255, 0.16); + color: #9ec1ff; + border: 2px solid; +} +.p-button.p-button-secondary.p-button-text, +.p-buttonset.p-button-secondary > .p-button.p-button-text, +.p-splitbutton.p-button-secondary > .p-button.p-button-text { + background-color: transparent; + color: #9ec1ff; + border-color: transparent; +} +.p-button.p-button-secondary.p-button-text:enabled:hover, +.p-buttonset.p-button-secondary > .p-button.p-button-text:enabled:hover, +.p-splitbutton.p-button-secondary > .p-button.p-button-text:enabled:hover { + background: rgba(158, 193, 255, 0.04); + border-color: transparent; + color: #9ec1ff; +} +.p-button.p-button-secondary.p-button-text:enabled:active, +.p-buttonset.p-button-secondary > .p-button.p-button-text:enabled:active, +.p-splitbutton.p-button-secondary > .p-button.p-button-text:enabled:active { + background: rgba(158, 193, 255, 0.16); + border-color: transparent; + color: #9ec1ff; +} +.p-button.p-button-info, +.p-buttonset.p-button-info > .p-button, +.p-splitbutton.p-button-info > .p-button { + color: #fff; + background: #35a4cc; + border: 1px solid #35a4cc; +} +.p-button.p-button-info:enabled:hover, +.p-buttonset.p-button-info > .p-button:enabled:hover, +.p-splitbutton.p-button-info > .p-button:enabled:hover { + background: #2f94b9; + color: #fff; + border-color: #2f94b9; +} +.p-button.p-button-info:enabled:focus, +.p-buttonset.p-button-info > .p-button:enabled:focus, +.p-splitbutton.p-button-info > .p-button:enabled:focus { + box-shadow: 0 0 0 1px #aedbeb; +} +.p-button.p-button-info:enabled:active, +.p-buttonset.p-button-info > .p-button:enabled:active, +.p-splitbutton.p-button-info > .p-button:enabled:active { + background: #2984a4; + color: #fff; + border-color: #2984a4; +} +.p-button.p-button-info.p-button-outlined, +.p-buttonset.p-button-info > .p-button.p-button-outlined, +.p-splitbutton.p-button-info > .p-button.p-button-outlined { + background-color: transparent; + color: #35a4cc; + border: 2px solid; +} +.p-button.p-button-info.p-button-outlined:enabled:hover, +.p-buttonset.p-button-info > .p-button.p-button-outlined:enabled:hover, +.p-splitbutton.p-button-info > .p-button.p-button-outlined:enabled:hover { + background: rgba(53, 164, 204, 0.04); + color: #35a4cc; + border: 2px solid; +} +.p-button.p-button-info.p-button-outlined:enabled:active, +.p-buttonset.p-button-info > .p-button.p-button-outlined:enabled:active, +.p-splitbutton.p-button-info > .p-button.p-button-outlined:enabled:active { + background: rgba(53, 164, 204, 0.16); + color: #35a4cc; + border: 2px solid; +} +.p-button.p-button-info.p-button-text, +.p-buttonset.p-button-info > .p-button.p-button-text, +.p-splitbutton.p-button-info > .p-button.p-button-text { + background-color: transparent; + color: #35a4cc; + border-color: transparent; +} +.p-button.p-button-info.p-button-text:enabled:hover, +.p-buttonset.p-button-info > .p-button.p-button-text:enabled:hover, +.p-splitbutton.p-button-info > .p-button.p-button-text:enabled:hover { + background: rgba(53, 164, 204, 0.04); + border-color: transparent; + color: #35a4cc; +} +.p-button.p-button-info.p-button-text:enabled:active, +.p-buttonset.p-button-info > .p-button.p-button-text:enabled:active, +.p-splitbutton.p-button-info > .p-button.p-button-text:enabled:active { + background: rgba(53, 164, 204, 0.16); + border-color: transparent; + color: #35a4cc; +} +.p-button.p-button-success, +.p-buttonset.p-button-success > .p-button, +.p-splitbutton.p-button-success > .p-button { + color: #121212; + background: #cede9c; + border: 1px solid #cede9c; +} +.p-button.p-button-success:enabled:hover, +.p-buttonset.p-button-success > .p-button:enabled:hover, +.p-splitbutton.p-button-success > .p-button:enabled:hover { + background: #c0d580; + color: #121212; + border-color: #c0d580; +} +.p-button.p-button-success:enabled:focus, +.p-buttonset.p-button-success > .p-button:enabled:focus, +.p-splitbutton.p-button-success > .p-button:enabled:focus { + box-shadow: 0 0 0 1px #ebf2d7; +} +.p-button.p-button-success:enabled:active, +.p-buttonset.p-button-success > .p-button:enabled:active, +.p-splitbutton.p-button-success > .p-button:enabled:active { + background: #b2cb63; + color: #121212; + border-color: #b2cb63; +} +.p-button.p-button-success.p-button-outlined, +.p-buttonset.p-button-success > .p-button.p-button-outlined, +.p-splitbutton.p-button-success > .p-button.p-button-outlined { + background-color: transparent; + color: #cede9c; + border: 2px solid; +} +.p-button.p-button-success.p-button-outlined:enabled:hover, +.p-buttonset.p-button-success > .p-button.p-button-outlined:enabled:hover, +.p-splitbutton.p-button-success > .p-button.p-button-outlined:enabled:hover { + background: rgba(206, 222, 156, 0.04); + color: #cede9c; + border: 2px solid; +} +.p-button.p-button-success.p-button-outlined:enabled:active, +.p-buttonset.p-button-success > .p-button.p-button-outlined:enabled:active, +.p-splitbutton.p-button-success > .p-button.p-button-outlined:enabled:active { + background: rgba(206, 222, 156, 0.16); + color: #cede9c; + border: 2px solid; +} +.p-button.p-button-success.p-button-text, +.p-buttonset.p-button-success > .p-button.p-button-text, +.p-splitbutton.p-button-success > .p-button.p-button-text { + background-color: transparent; + color: #cede9c; + border-color: transparent; +} +.p-button.p-button-success.p-button-text:enabled:hover, +.p-buttonset.p-button-success > .p-button.p-button-text:enabled:hover, +.p-splitbutton.p-button-success > .p-button.p-button-text:enabled:hover { + background: rgba(206, 222, 156, 0.04); + border-color: transparent; + color: #cede9c; +} +.p-button.p-button-success.p-button-text:enabled:active, +.p-buttonset.p-button-success > .p-button.p-button-text:enabled:active, +.p-splitbutton.p-button-success > .p-button.p-button-text:enabled:active { + background: rgba(206, 222, 156, 0.16); + border-color: transparent; + color: #cede9c; +} +.p-button.p-button-warning, +.p-buttonset.p-button-warning > .p-button, +.p-splitbutton.p-button-warning > .p-button { + color: #0e1315; + background: #ffe08a; + border: 1px solid #ffe08a; +} +.p-button.p-button-warning:enabled:hover, +.p-buttonset.p-button-warning > .p-button:enabled:hover, +.p-splitbutton.p-button-warning > .p-button:enabled:hover { + background: #ffd663; + color: #0e1315; + border-color: #ffd663; +} +.p-button.p-button-warning:enabled:focus, +.p-buttonset.p-button-warning > .p-button:enabled:focus, +.p-splitbutton.p-button-warning > .p-button:enabled:focus { + box-shadow: 0 0 0 1px #fff3d0; +} +.p-button.p-button-warning:enabled:active, +.p-buttonset.p-button-warning > .p-button:enabled:active, +.p-splitbutton.p-button-warning > .p-button:enabled:active { + background: #ffcb3b; + color: #0e1315; + border-color: #ffcb3b; +} +.p-button.p-button-warning.p-button-outlined, +.p-buttonset.p-button-warning > .p-button.p-button-outlined, +.p-splitbutton.p-button-warning > .p-button.p-button-outlined { + background-color: transparent; + color: #ffe08a; + border: 2px solid; +} +.p-button.p-button-warning.p-button-outlined:enabled:hover, +.p-buttonset.p-button-warning > .p-button.p-button-outlined:enabled:hover, +.p-splitbutton.p-button-warning > .p-button.p-button-outlined:enabled:hover { + background: rgba(255, 224, 138, 0.04); + color: #ffe08a; + border: 2px solid; +} +.p-button.p-button-warning.p-button-outlined:enabled:active, +.p-buttonset.p-button-warning > .p-button.p-button-outlined:enabled:active, +.p-splitbutton.p-button-warning > .p-button.p-button-outlined:enabled:active { + background: rgba(255, 224, 138, 0.16); + color: #ffe08a; + border: 2px solid; +} +.p-button.p-button-warning.p-button-text, +.p-buttonset.p-button-warning > .p-button.p-button-text, +.p-splitbutton.p-button-warning > .p-button.p-button-text { + background-color: transparent; + color: #ffe08a; + border-color: transparent; +} +.p-button.p-button-warning.p-button-text:enabled:hover, +.p-buttonset.p-button-warning > .p-button.p-button-text:enabled:hover, +.p-splitbutton.p-button-warning > .p-button.p-button-text:enabled:hover { + background: rgba(255, 224, 138, 0.04); + border-color: transparent; + color: #ffe08a; +} +.p-button.p-button-warning.p-button-text:enabled:active, +.p-buttonset.p-button-warning > .p-button.p-button-text:enabled:active, +.p-splitbutton.p-button-warning > .p-button.p-button-text:enabled:active { + background: rgba(255, 224, 138, 0.16); + border-color: transparent; + color: #ffe08a; +} +.p-button.p-button-help, +.p-buttonset.p-button-help > .p-button, +.p-splitbutton.p-button-help > .p-button { + color: #121212; + background: #b09ce5; + border: 1px solid #b09ce5; +} +.p-button.p-button-help:enabled:hover, +.p-buttonset.p-button-help > .p-button:enabled:hover, +.p-splitbutton.p-button-help > .p-button:enabled:hover { + background: #987edd; + color: #121212; + border-color: #987edd; +} +.p-button.p-button-help:enabled:focus, +.p-buttonset.p-button-help > .p-button:enabled:focus, +.p-splitbutton.p-button-help > .p-button:enabled:focus { + box-shadow: 0 0 0 1px #dfd7f5; +} +.p-button.p-button-help:enabled:active, +.p-buttonset.p-button-help > .p-button:enabled:active, +.p-splitbutton.p-button-help > .p-button:enabled:active { + background: #7f5fd5; + color: #121212; + border-color: #7f5fd5; +} +.p-button.p-button-help.p-button-outlined, +.p-buttonset.p-button-help > .p-button.p-button-outlined, +.p-splitbutton.p-button-help > .p-button.p-button-outlined { + background-color: transparent; + color: #b09ce5; + border: 2px solid; +} +.p-button.p-button-help.p-button-outlined:enabled:hover, +.p-buttonset.p-button-help > .p-button.p-button-outlined:enabled:hover, +.p-splitbutton.p-button-help > .p-button.p-button-outlined:enabled:hover { + background: rgba(176, 156, 229, 0.04); + color: #b09ce5; + border: 2px solid; +} +.p-button.p-button-help.p-button-outlined:enabled:active, +.p-buttonset.p-button-help > .p-button.p-button-outlined:enabled:active, +.p-splitbutton.p-button-help > .p-button.p-button-outlined:enabled:active { + background: rgba(176, 156, 229, 0.16); + color: #b09ce5; + border: 2px solid; +} +.p-button.p-button-help.p-button-text, +.p-buttonset.p-button-help > .p-button.p-button-text, +.p-splitbutton.p-button-help > .p-button.p-button-text { + background-color: transparent; + color: #b09ce5; + border-color: transparent; +} +.p-button.p-button-help.p-button-text:enabled:hover, +.p-buttonset.p-button-help > .p-button.p-button-text:enabled:hover, +.p-splitbutton.p-button-help > .p-button.p-button-text:enabled:hover { + background: rgba(176, 156, 229, 0.04); + border-color: transparent; + color: #b09ce5; +} +.p-button.p-button-help.p-button-text:enabled:active, +.p-buttonset.p-button-help > .p-button.p-button-text:enabled:active, +.p-splitbutton.p-button-help > .p-button.p-button-text:enabled:active { + background: rgba(176, 156, 229, 0.16); + border-color: transparent; + color: #b09ce5; +} +.p-button.p-button-danger, +.p-buttonset.p-button-danger > .p-button, +.p-splitbutton.p-button-danger > .p-button { + color: #121212; + background: #e693a9; + border: 1px solid #e693a9; +} +.p-button.p-button-danger:enabled:hover, +.p-buttonset.p-button-danger > .p-button:enabled:hover, +.p-splitbutton.p-button-danger > .p-button:enabled:hover { + background: #df7491; + color: #121212; + border-color: #df7491; +} +.p-button.p-button-danger:enabled:focus, +.p-buttonset.p-button-danger > .p-button:enabled:focus, +.p-splitbutton.p-button-danger > .p-button:enabled:focus { + box-shadow: 0 0 0 1px #f5d4dd; +} +.p-button.p-button-danger:enabled:active, +.p-buttonset.p-button-danger > .p-button:enabled:active, +.p-splitbutton.p-button-danger > .p-button:enabled:active { + background: #d85678; + color: #121212; + border-color: #d85678; +} +.p-button.p-button-danger.p-button-outlined, +.p-buttonset.p-button-danger > .p-button.p-button-outlined, +.p-splitbutton.p-button-danger > .p-button.p-button-outlined { + background-color: transparent; + color: #e693a9; + border: 2px solid; +} +.p-button.p-button-danger.p-button-outlined:enabled:hover, +.p-buttonset.p-button-danger > .p-button.p-button-outlined:enabled:hover, +.p-splitbutton.p-button-danger > .p-button.p-button-outlined:enabled:hover { + background: rgba(230, 147, 169, 0.04); + color: #e693a9; + border: 2px solid; +} +.p-button.p-button-danger.p-button-outlined:enabled:active, +.p-buttonset.p-button-danger > .p-button.p-button-outlined:enabled:active, +.p-splitbutton.p-button-danger > .p-button.p-button-outlined:enabled:active { + background: rgba(230, 147, 169, 0.16); + color: #e693a9; + border: 2px solid; +} +.p-button.p-button-danger.p-button-text, +.p-buttonset.p-button-danger > .p-button.p-button-text, +.p-splitbutton.p-button-danger > .p-button.p-button-text { + background-color: transparent; + color: #e693a9; + border-color: transparent; +} +.p-button.p-button-danger.p-button-text:enabled:hover, +.p-buttonset.p-button-danger > .p-button.p-button-text:enabled:hover, +.p-splitbutton.p-button-danger > .p-button.p-button-text:enabled:hover { + background: rgba(230, 147, 169, 0.04); + border-color: transparent; + color: #e693a9; +} +.p-button.p-button-danger.p-button-text:enabled:active, +.p-buttonset.p-button-danger > .p-button.p-button-text:enabled:active, +.p-splitbutton.p-button-danger > .p-button.p-button-text:enabled:active { + background: rgba(230, 147, 169, 0.16); + border-color: transparent; + color: #e693a9; +} +.p-button.p-button-link { + color: #de80ff; + background: transparent; + border: transparent; +} +.p-button.p-button-link:enabled:hover { + background: transparent; + color: #de80ff; + border-color: transparent; +} +.p-button.p-button-link:enabled:hover .p-button-label { + text-decoration: underline; +} +.p-button.p-button-link:enabled:focus { + background: transparent; + box-shadow: 0 0 0 1px #e9aaff; + border-color: transparent; +} +.p-button.p-button-link:enabled:active { + background: transparent; + color: #de80ff; + border-color: transparent; +} +.p-speeddial-button.p-button.p-button-icon-only { + width: 4rem; + height: 4rem; +} +.p-speeddial-button.p-button.p-button-icon-only .p-button-icon { + font-size: 1.3rem; +} +.p-speeddial-button.p-button.p-button-icon-only .p-icon { + width: 1.3rem; + height: 1.3rem; +} +.p-speeddial-list { + outline: 0 none; +} +.p-speeddial-item.p-focus > .p-speeddial-action { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-speeddial-action { + width: 3rem; + height: 3rem; + background: #1e282c; + color: #fff; +} +.p-speeddial-action:hover { + background: #3c3c3c; + color: #fff; +} +.p-speeddial-direction-up .p-speeddial-item { + margin: 0.25rem 0; +} +.p-speeddial-direction-up .p-speeddial-item:first-child { + margin-bottom: 0.5rem; +} +.p-speeddial-direction-down .p-speeddial-item { + margin: 0.25rem 0; +} +.p-speeddial-direction-down .p-speeddial-item:first-child { + margin-top: 0.5rem; +} +.p-speeddial-direction-left .p-speeddial-item { + margin: 0 0.25rem; +} +.p-speeddial-direction-left .p-speeddial-item:first-child { + margin-right: 0.5rem; +} +.p-speeddial-direction-right .p-speeddial-item { + margin: 0 0.25rem; +} +.p-speeddial-direction-right .p-speeddial-item:first-child { + margin-left: 0.5rem; +} +.p-speeddial-circle .p-speeddial-item, +.p-speeddial-semi-circle .p-speeddial-item, +.p-speeddial-quarter-circle .p-speeddial-item { + margin: 0; +} +.p-speeddial-circle .p-speeddial-item:first-child, +.p-speeddial-circle .p-speeddial-item:last-child, +.p-speeddial-semi-circle .p-speeddial-item:first-child, +.p-speeddial-semi-circle .p-speeddial-item:last-child, +.p-speeddial-quarter-circle .p-speeddial-item:first-child, +.p-speeddial-quarter-circle .p-speeddial-item:last-child { + margin: 0; +} +.p-speeddial-mask { + background-color: rgba(0, 0, 0, 0.4); +} +.p-splitbutton { + border-radius: 6px; +} +.p-splitbutton.p-button-outlined > .p-button { + background-color: transparent; + color: #e9aaff; + border: 2px solid; +} +.p-splitbutton.p-button-outlined > .p-button:enabled:hover, +.p-splitbutton.p-button-outlined > .p-button:not(button):not(a):not(.p-disabled):hover { + background: rgba(233, 170, 255, 0.04); + color: #e9aaff; +} +.p-splitbutton.p-button-outlined > .p-button:enabled:active, +.p-splitbutton.p-button-outlined > .p-button:not(button):not(a):not(.p-disabled):active { + background: rgba(233, 170, 255, 0.16); + color: #e9aaff; +} +.p-splitbutton.p-button-outlined.p-button-plain > .p-button { + color: #b3b3b3; + border-color: #b3b3b3; +} +.p-splitbutton.p-button-outlined.p-button-plain > .p-button:enabled:hover, +.p-splitbutton.p-button-outlined.p-button-plain > .p-button:not(button):not(a):not(.p-disabled):hover { + background: rgba(158, 173, 230, 0.08); + color: #b3b3b3; +} +.p-splitbutton.p-button-outlined.p-button-plain > .p-button:enabled:active, +.p-splitbutton.p-button-outlined.p-button-plain > .p-button:not(button):not(a):not(.p-disabled):active { + background: rgba(255, 255, 255, 0.16); + color: #b3b3b3; +} +.p-splitbutton.p-button-text > .p-button { + background-color: transparent; + color: #e9aaff; + border-color: transparent; +} +.p-splitbutton.p-button-text > .p-button:enabled:hover, +.p-splitbutton.p-button-text > .p-button:not(button):not(a):not(.p-disabled):hover { + background: rgba(233, 170, 255, 0.04); + color: #e9aaff; + border-color: transparent; +} +.p-splitbutton.p-button-text > .p-button:enabled:active, +.p-splitbutton.p-button-text > .p-button:not(button):not(a):not(.p-disabled):active { + background: rgba(233, 170, 255, 0.16); + color: #e9aaff; + border-color: transparent; +} +.p-splitbutton.p-button-text.p-button-plain > .p-button { + color: #b3b3b3; +} +.p-splitbutton.p-button-text.p-button-plain > .p-button:enabled:hover, +.p-splitbutton.p-button-text.p-button-plain > .p-button:not(button):not(a):not(.p-disabled):hover { + background: rgba(158, 173, 230, 0.08); + color: #b3b3b3; +} +.p-splitbutton.p-button-text.p-button-plain > .p-button:enabled:active, +.p-splitbutton.p-button-text.p-button-plain > .p-button:not(button):not(a):not(.p-disabled):active { + background: rgba(255, 255, 255, 0.16); + color: #b3b3b3; +} +.p-splitbutton.p-button-raised { + box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), + 0px 1px 5px 0px rgba(0, 0, 0, 0.12); +} +.p-splitbutton.p-button-rounded { + border-radius: 2rem; +} +.p-splitbutton.p-button-rounded > .p-button { + border-radius: 2rem; +} +.p-splitbutton.p-button-sm > .p-button { + font-size: 0.875rem; + padding: 0.4375rem 0.875rem; +} +.p-splitbutton.p-button-sm > .p-button .p-button-icon { + font-size: 0.875rem; +} +.p-splitbutton.p-button-lg > .p-button { + font-size: 1.25rem; + padding: 0.625rem 1.25rem; +} +.p-splitbutton.p-button-lg > .p-button .p-button-icon { + font-size: 1.25rem; +} +.p-splitbutton.p-button-secondary.p-button-outlined > .p-button { + background-color: transparent; + color: #9ec1ff; + border: 2px solid; +} +.p-splitbutton.p-button-secondary.p-button-outlined > .p-button:enabled:hover, +.p-splitbutton.p-button-secondary.p-button-outlined > .p-button:not(button):not(a):not(.p-disabled):hover { + background: rgba(158, 193, 255, 0.04); + color: #9ec1ff; +} +.p-splitbutton.p-button-secondary.p-button-outlined > .p-button:enabled:active, +.p-splitbutton.p-button-secondary.p-button-outlined > .p-button:not(button):not(a):not(.p-disabled):active { + background: rgba(158, 193, 255, 0.16); + color: #9ec1ff; +} +.p-splitbutton.p-button-secondary.p-button-text > .p-button { + background-color: transparent; + color: #9ec1ff; + border-color: transparent; +} +.p-splitbutton.p-button-secondary.p-button-text > .p-button:enabled:hover, +.p-splitbutton.p-button-secondary.p-button-text > .p-button:not(button):not(a):not(.p-disabled):hover { + background: rgba(158, 193, 255, 0.04); + border-color: transparent; + color: #9ec1ff; +} +.p-splitbutton.p-button-secondary.p-button-text > .p-button:enabled:active, +.p-splitbutton.p-button-secondary.p-button-text > .p-button:not(button):not(a):not(.p-disabled):active { + background: rgba(158, 193, 255, 0.16); + border-color: transparent; + color: #9ec1ff; +} +.p-splitbutton.p-button-info.p-button-outlined > .p-button { + background-color: transparent; + color: #35a4cc; + border: 2px solid; +} +.p-splitbutton.p-button-info.p-button-outlined > .p-button:enabled:hover, +.p-splitbutton.p-button-info.p-button-outlined > .p-button:not(button):not(a):not(.p-disabled):hover { + background: rgba(53, 164, 204, 0.04); + color: #35a4cc; +} +.p-splitbutton.p-button-info.p-button-outlined > .p-button:enabled:active, +.p-splitbutton.p-button-info.p-button-outlined > .p-button:not(button):not(a):not(.p-disabled):active { + background: rgba(53, 164, 204, 0.16); + color: #35a4cc; +} +.p-splitbutton.p-button-info.p-button-text > .p-button { + background-color: transparent; + color: #35a4cc; + border-color: transparent; +} +.p-splitbutton.p-button-info.p-button-text > .p-button:enabled:hover, +.p-splitbutton.p-button-info.p-button-text > .p-button:not(button):not(a):not(.p-disabled):hover { + background: rgba(53, 164, 204, 0.04); + border-color: transparent; + color: #35a4cc; +} +.p-splitbutton.p-button-info.p-button-text > .p-button:enabled:active, +.p-splitbutton.p-button-info.p-button-text > .p-button:not(button):not(a):not(.p-disabled):active { + background: rgba(53, 164, 204, 0.16); + border-color: transparent; + color: #35a4cc; +} +.p-splitbutton.p-button-success.p-button-outlined > .p-button { + background-color: transparent; + color: #cede9c; + border: 2px solid; +} +.p-splitbutton.p-button-success.p-button-outlined > .p-button:enabled:hover, +.p-splitbutton.p-button-success.p-button-outlined > .p-button:not(button):not(a):not(.p-disabled):hover { + background: rgba(206, 222, 156, 0.04); + color: #cede9c; +} +.p-splitbutton.p-button-success.p-button-outlined > .p-button:enabled:active, +.p-splitbutton.p-button-success.p-button-outlined > .p-button:not(button):not(a):not(.p-disabled):active { + background: rgba(206, 222, 156, 0.16); + color: #cede9c; +} +.p-splitbutton.p-button-success.p-button-text > .p-button { + background-color: transparent; + color: #cede9c; + border-color: transparent; +} +.p-splitbutton.p-button-success.p-button-text > .p-button:enabled:hover, +.p-splitbutton.p-button-success.p-button-text > .p-button:not(button):not(a):not(.p-disabled):hover { + background: rgba(206, 222, 156, 0.04); + border-color: transparent; + color: #cede9c; +} +.p-splitbutton.p-button-success.p-button-text > .p-button:enabled:active, +.p-splitbutton.p-button-success.p-button-text > .p-button:not(button):not(a):not(.p-disabled):active { + background: rgba(206, 222, 156, 0.16); + border-color: transparent; + color: #cede9c; +} +.p-splitbutton.p-button-warning.p-button-outlined > .p-button { + background-color: transparent; + color: #ffe08a; + border: 2px solid; +} +.p-splitbutton.p-button-warning.p-button-outlined > .p-button:enabled:hover, +.p-splitbutton.p-button-warning.p-button-outlined > .p-button:not(button):not(a):not(.p-disabled):hover { + background: rgba(255, 224, 138, 0.04); + color: #ffe08a; +} +.p-splitbutton.p-button-warning.p-button-outlined > .p-button:enabled:active, +.p-splitbutton.p-button-warning.p-button-outlined > .p-button:not(button):not(a):not(.p-disabled):active { + background: rgba(255, 224, 138, 0.16); + color: #ffe08a; +} +.p-splitbutton.p-button-warning.p-button-text > .p-button { + background-color: transparent; + color: #ffe08a; + border-color: transparent; +} +.p-splitbutton.p-button-warning.p-button-text > .p-button:enabled:hover, +.p-splitbutton.p-button-warning.p-button-text > .p-button:not(button):not(a):not(.p-disabled):hover { + background: rgba(255, 224, 138, 0.04); + border-color: transparent; + color: #ffe08a; +} +.p-splitbutton.p-button-warning.p-button-text > .p-button:enabled:active, +.p-splitbutton.p-button-warning.p-button-text > .p-button:not(button):not(a):not(.p-disabled):active { + background: rgba(255, 224, 138, 0.16); + border-color: transparent; + color: #ffe08a; +} +.p-splitbutton.p-button-help.p-button-outlined > .p-button { + background-color: transparent; + color: #b09ce5; + border: 2px solid; +} +.p-splitbutton.p-button-help.p-button-outlined > .p-button:enabled:hover, +.p-splitbutton.p-button-help.p-button-outlined > .p-button:not(button):not(a):not(.p-disabled):hover { + background: rgba(176, 156, 229, 0.04); + color: #b09ce5; +} +.p-splitbutton.p-button-help.p-button-outlined > .p-button:enabled:active, +.p-splitbutton.p-button-help.p-button-outlined > .p-button:not(button):not(a):not(.p-disabled):active { + background: rgba(176, 156, 229, 0.16); + color: #b09ce5; +} +.p-splitbutton.p-button-help.p-button-text > .p-button { + background-color: transparent; + color: #b09ce5; + border-color: transparent; +} +.p-splitbutton.p-button-help.p-button-text > .p-button:enabled:hover, +.p-splitbutton.p-button-help.p-button-text > .p-button:not(button):not(a):not(.p-disabled):hover { + background: rgba(176, 156, 229, 0.04); + border-color: transparent; + color: #b09ce5; +} +.p-splitbutton.p-button-help.p-button-text > .p-button:enabled:active, +.p-splitbutton.p-button-help.p-button-text > .p-button:not(button):not(a):not(.p-disabled):active { + background: rgba(176, 156, 229, 0.16); + border-color: transparent; + color: #b09ce5; +} +.p-splitbutton.p-button-danger.p-button-outlined > .p-button { + background-color: transparent; + color: #e693a9; + border: 2px solid; +} +.p-splitbutton.p-button-danger.p-button-outlined > .p-button:enabled:hover, +.p-splitbutton.p-button-danger.p-button-outlined > .p-button:not(button):not(a):not(.p-disabled):hover { + background: rgba(230, 147, 169, 0.04); + color: #e693a9; +} +.p-splitbutton.p-button-danger.p-button-outlined > .p-button:enabled:active, +.p-splitbutton.p-button-danger.p-button-outlined > .p-button:not(button):not(a):not(.p-disabled):active { + background: rgba(230, 147, 169, 0.16); + color: #e693a9; +} +.p-splitbutton.p-button-danger.p-button-text > .p-button { + background-color: transparent; + color: #e693a9; + border-color: transparent; +} +.p-splitbutton.p-button-danger.p-button-text > .p-button:enabled:hover, +.p-splitbutton.p-button-danger.p-button-text > .p-button:not(button):not(a):not(.p-disabled):hover { + background: rgba(230, 147, 169, 0.04); + border-color: transparent; + color: #e693a9; +} +.p-splitbutton.p-button-danger.p-button-text > .p-button:enabled:active, +.p-splitbutton.p-button-danger.p-button-text > .p-button:not(button):not(a):not(.p-disabled):active { + background: rgba(230, 147, 169, 0.16); + border-color: transparent; + color: #e693a9; +} +.p-carousel .p-carousel-content .p-carousel-prev, +.p-carousel .p-carousel-content .p-carousel-next { + width: 2rem; + height: 2rem; + color: #b3b3b3; + border: 0 none; + background: transparent; + border-radius: 50%; + transition: background-color 0.3s, color 0.3s, box-shadow 0.3s; + margin: 0.5rem; +} +.p-carousel .p-carousel-content .p-carousel-prev:enabled:hover, +.p-carousel .p-carousel-content .p-carousel-next:enabled:hover { + color: #e6e6e6; + border-color: transparent; + background: rgba(158, 173, 230, 0.08); +} +.p-carousel .p-carousel-content .p-carousel-prev:focus, +.p-carousel .p-carousel-content .p-carousel-next:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-carousel .p-carousel-indicators { + padding: 1rem; +} +.p-carousel .p-carousel-indicators .p-carousel-indicator { + margin-right: 0.5rem; + margin-bottom: 0.5rem; +} +.p-carousel .p-carousel-indicators .p-carousel-indicator button { + background-color: #3c3c3c; + width: 2rem; + height: 0.5rem; + transition: background-color 0.3s, color 0.3s, box-shadow 0.3s; + border-radius: 0; +} +.p-carousel .p-carousel-indicators .p-carousel-indicator button:hover { + background: #505050; +} +.p-carousel .p-carousel-indicators .p-carousel-indicator.p-highlight button { + background: rgba(158, 173, 230, 0.16); + color: #9eade6; +} +.p-datatable .p-paginator-top { + border-width: 0 0 2px 0; + border-radius: 0; +} +.p-datatable .p-paginator-bottom { + border-width: 0 0 2px 0; + border-radius: 0; +} +.p-datatable .p-datatable-header { + background: #212121; + color: #b3b3b3; + border: 2px solid #3c3c3c; + border-width: 0 0 2px 0; + padding: 1rem 1rem; + font-weight: 600; +} +.p-datatable .p-datatable-footer { + background: #212121; + color: #e6e6e6; + border: 2px solid #3c3c3c; + border-width: 0 0 2px 0; + padding: 1rem 1rem; + font-weight: 600; +} +.p-datatable .p-datatable-thead > tr > th { + text-align: left; + padding: 1rem 1rem; + border: 2px solid #3c3c3c; + border-width: 0 0 2px 0; + font-weight: 600; + color: #e6e6e6; + background: #212121; + transition: box-shadow 0.3s; +} +.p-datatable .p-datatable-tfoot > tr > td { + text-align: left; + padding: 1rem 1rem; + border: 2px solid #3c3c3c; + border-width: 0 0 2px 0; + font-weight: 600; + color: #e6e6e6; + background: #212121; +} +.p-datatable .p-sortable-column .p-sortable-column-icon { + color: #b3b3b3; + margin-left: 0.5rem; +} +.p-datatable .p-sortable-column .p-sortable-column-badge { + border-radius: 50%; + height: 1.143rem; + min-width: 1.143rem; + line-height: 1.143rem; + color: #9eade6; + background: rgba(158, 173, 230, 0.16); + margin-left: 0.5rem; +} +.p-datatable .p-sortable-column:not(.p-highlight):hover { + background: rgba(158, 173, 230, 0.08); + color: #e6e6e6; +} +.p-datatable .p-sortable-column:not(.p-highlight):hover .p-sortable-column-icon { + color: #e6e6e6; +} +.p-datatable .p-sortable-column.p-highlight { + background: #212121; + color: #e9aaff; +} +.p-datatable .p-sortable-column.p-highlight .p-sortable-column-icon { + color: #e9aaff; +} +.p-datatable .p-sortable-column.p-highlight:hover { + background: rgba(158, 173, 230, 0.08); + color: #e9aaff; +} +.p-datatable .p-sortable-column.p-highlight:hover .p-sortable-column-icon { + color: #e9aaff; +} +.p-datatable .p-sortable-column:focus { + box-shadow: inset 0 0 0 0.15rem #e9aaff; + outline: 0 none; +} +.p-datatable .p-datatable-tbody > tr { + background: #212121; + color: #e6e6e6; + transition: box-shadow 0.3s; +} +.p-datatable .p-datatable-tbody > tr > td { + text-align: left; + border: 2px solid #3c3c3c; + border-width: 0 0 2px 0; + padding: 1rem 1rem; +} +.p-datatable .p-datatable-tbody > tr > td .p-row-toggler, +.p-datatable .p-datatable-tbody > tr > td .p-row-editor-init, +.p-datatable .p-datatable-tbody > tr > td .p-row-editor-save, +.p-datatable .p-datatable-tbody > tr > td .p-row-editor-cancel { + width: 2rem; + height: 2rem; + color: #b3b3b3; + border: 0 none; + background: transparent; + border-radius: 50%; + transition: background-color 0.3s, color 0.3s, box-shadow 0.3s; +} +.p-datatable .p-datatable-tbody > tr > td .p-row-toggler:enabled:hover, +.p-datatable .p-datatable-tbody > tr > td .p-row-editor-init:enabled:hover, +.p-datatable .p-datatable-tbody > tr > td .p-row-editor-save:enabled:hover, +.p-datatable .p-datatable-tbody > tr > td .p-row-editor-cancel:enabled:hover { + color: #e6e6e6; + border-color: transparent; + background: rgba(158, 173, 230, 0.08); +} +.p-datatable .p-datatable-tbody > tr > td .p-row-toggler:focus, +.p-datatable .p-datatable-tbody > tr > td .p-row-editor-init:focus, +.p-datatable .p-datatable-tbody > tr > td .p-row-editor-save:focus, +.p-datatable .p-datatable-tbody > tr > td .p-row-editor-cancel:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-datatable .p-datatable-tbody > tr > td .p-row-editor-save { + margin-right: 0.5rem; +} +.p-datatable .p-datatable-tbody > tr > td > .p-column-title { + font-weight: 600; +} +.p-datatable .p-datatable-tbody > tr:focus { + outline: 0.15rem solid #e9aaff; + outline-offset: -0.15rem; +} +.p-datatable .p-datatable-tbody > tr.p-highlight { + background: rgba(158, 173, 230, 0.16); + color: #9eade6; +} +.p-datatable .p-datatable-tbody > tr.p-datatable-dragpoint-top > td { + box-shadow: inset 0 2px 0 0 rgba(158, 173, 230, 0.16); +} +.p-datatable .p-datatable-tbody > tr.p-datatable-dragpoint-bottom > td { + box-shadow: inset 0 -2px 0 0 rgba(158, 173, 230, 0.16); +} +.p-datatable.p-datatable-hoverable-rows .p-datatable-tbody > tr:not(.p-highlight):hover { + background: rgba(158, 173, 230, 0.08); + color: #e6e6e6; +} +.p-datatable .p-column-resizer-helper { + background: #e9aaff; +} +.p-datatable .p-datatable-scrollable-header, +.p-datatable .p-datatable-scrollable-footer { + background: #212121; +} +.p-datatable.p-datatable-scrollable > .p-datatable-wrapper > .p-datatable-table > .p-datatable-thead, +.p-datatable.p-datatable-scrollable > .p-datatable-wrapper > .p-datatable-table > .p-datatable-tfoot, +.p-datatable.p-datatable-scrollable + > .p-datatable-wrapper + > .p-virtualscroller + > .p-datatable-table + > .p-datatable-thead, +.p-datatable.p-datatable-scrollable + > .p-datatable-wrapper + > .p-virtualscroller + > .p-datatable-table + > .p-datatable-tfoot { + background-color: #212121; +} +.p-datatable .p-datatable-loading-icon { + font-size: 2rem; +} +.p-datatable .p-datatable-loading-icon.p-icon { + width: 2rem; + height: 2rem; +} +.p-datatable.p-datatable-gridlines .p-datatable-header { + border-width: 1px 1px 0 1px; +} +.p-datatable.p-datatable-gridlines .p-datatable-footer { + border-width: 0 1px 1px 1px; +} +.p-datatable.p-datatable-gridlines .p-paginator-top { + border-width: 0 1px 0 1px; +} +.p-datatable.p-datatable-gridlines .p-paginator-bottom { + border-width: 0 1px 1px 1px; +} +.p-datatable.p-datatable-gridlines .p-datatable-thead > tr > th { + border-width: 1px 0 1px 1px; +} +.p-datatable.p-datatable-gridlines .p-datatable-thead > tr > th:last-child { + border-width: 1px; +} +.p-datatable.p-datatable-gridlines .p-datatable-tbody > tr > td { + border-width: 1px 0 0 1px; +} +.p-datatable.p-datatable-gridlines .p-datatable-tbody > tr > td:last-child { + border-width: 1px 1px 0 1px; +} +.p-datatable.p-datatable-gridlines .p-datatable-tbody > tr:last-child > td { + border-width: 1px 0 1px 1px; +} +.p-datatable.p-datatable-gridlines .p-datatable-tbody > tr:last-child > td:last-child { + border-width: 1px; +} +.p-datatable.p-datatable-gridlines .p-datatable-tfoot > tr > td { + border-width: 1px 0 1px 1px; +} +.p-datatable.p-datatable-gridlines .p-datatable-tfoot > tr > td:last-child { + border-width: 1px 1px 1px 1px; +} +.p-datatable.p-datatable-gridlines .p-datatable-thead + .p-datatable-tfoot > tr > td { + border-width: 0 0 1px 1px; +} +.p-datatable.p-datatable-gridlines .p-datatable-thead + .p-datatable-tfoot > tr > td:last-child { + border-width: 0 1px 1px 1px; +} +.p-datatable.p-datatable-gridlines:has(.p-datatable-thead):has(.p-datatable-tbody) .p-datatable-tbody > tr > td { + border-width: 0 0 1px 1px; +} +.p-datatable.p-datatable-gridlines:has(.p-datatable-thead):has(.p-datatable-tbody) + .p-datatable-tbody + > tr + > td:last-child { + border-width: 0 1px 1px 1px; +} +.p-datatable.p-datatable-gridlines:has(.p-datatable-tbody):has(.p-datatable-tfoot) + .p-datatable-tbody + > tr:last-child + > td { + border-width: 0 0 0 1px; +} +.p-datatable.p-datatable-gridlines:has(.p-datatable-tbody):has(.p-datatable-tfoot) + .p-datatable-tbody + > tr:last-child + > td:last-child { + border-width: 0 1px 0 1px; +} +.p-datatable.p-datatable-striped .p-datatable-tbody > tr:nth-child(even) { + background: #1b2327; +} +.p-datatable.p-datatable-striped .p-datatable-tbody > tr:nth-child(even).p-highlight { + background: rgba(158, 173, 230, 0.16); + color: #9eade6; +} +.p-datatable.p-datatable-striped .p-datatable-tbody > tr:nth-child(even).p-highlight .p-row-toggler { + color: #9eade6; +} +.p-datatable.p-datatable-striped .p-datatable-tbody > tr:nth-child(even).p-highlight .p-row-toggler:hover { + color: #9eade6; +} +.p-datatable.p-datatable-sm .p-datatable-header { + padding: 0.5rem 0.5rem; +} +.p-datatable.p-datatable-sm .p-datatable-thead > tr > th { + padding: 0.5rem 0.5rem; +} +.p-datatable.p-datatable-sm .p-datatable-tbody > tr > td { + padding: 0.5rem 0.5rem; +} +.p-datatable.p-datatable-sm .p-datatable-tfoot > tr > td { + padding: 0.5rem 0.5rem; +} +.p-datatable.p-datatable-sm .p-datatable-footer { + padding: 0.5rem 0.5rem; +} +.p-datatable.p-datatable-lg .p-datatable-header { + padding: 1.25rem 1.25rem; +} +.p-datatable.p-datatable-lg .p-datatable-thead > tr > th { + padding: 1.25rem 1.25rem; +} +.p-datatable.p-datatable-lg .p-datatable-tbody > tr > td { + padding: 1.25rem 1.25rem; +} +.p-datatable.p-datatable-lg .p-datatable-tfoot > tr > td { + padding: 1.25rem 1.25rem; +} +.p-datatable.p-datatable-lg .p-datatable-footer { + padding: 1.25rem 1.25rem; +} +.p-dataview .p-paginator-top { + border-width: 0 0 2px 0; + border-radius: 0; +} +.p-dataview .p-paginator-bottom { + border-width: 0 0 2px 0; + border-radius: 0; +} +.p-dataview .p-dataview-header { + background: #212121; + color: #b3b3b3; + border: 2px solid #3c3c3c; + border-width: 0 0 2px 0; + padding: 1rem 1rem; + font-weight: 600; +} +.p-dataview .p-dataview-content { + background: #212121; + color: #e6e6e6; + border: 0 none; + padding: 0; +} +.p-dataview.p-dataview-list .p-dataview-content > .p-grid > div { + border: solid #3c3c3c; + border-width: 0 0 1px 0; +} +.p-dataview .p-dataview-footer { + background: #212121; + color: #e6e6e6; + border: 2px solid #3c3c3c; + border-width: 0 0 2px 0; + padding: 1rem 1rem; + font-weight: 600; + border-bottom-left-radius: 6px; + border-bottom-right-radius: 6px; +} +.p-column-filter-row .p-column-filter-menu-button, +.p-column-filter-row .p-column-filter-clear-button { + margin-left: 0.5rem; +} +.p-column-filter-menu-button { + width: 2rem; + height: 2rem; + color: #b3b3b3; + border: 0 none; + background: transparent; + border-radius: 50%; + transition: background-color 0.3s, color 0.3s, box-shadow 0.3s; +} +.p-column-filter-menu-button:hover { + color: #e6e6e6; + border-color: transparent; + background: rgba(158, 173, 230, 0.08); +} +.p-column-filter-menu-button.p-column-filter-menu-button-open, +.p-column-filter-menu-button.p-column-filter-menu-button-open:hover { + background: rgba(158, 173, 230, 0.08); + color: #e6e6e6; +} +.p-column-filter-menu-button.p-column-filter-menu-button-active, +.p-column-filter-menu-button.p-column-filter-menu-button-active:hover { + background: rgba(158, 173, 230, 0.16); + color: #9eade6; +} +.p-column-filter-menu-button:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-column-filter-clear-button { + width: 2rem; + height: 2rem; + color: #b3b3b3; + border: 0 none; + background: transparent; + border-radius: 50%; + transition: background-color 0.3s, color 0.3s, box-shadow 0.3s; +} +.p-column-filter-clear-button:hover { + color: #e6e6e6; + border-color: transparent; + background: rgba(158, 173, 230, 0.08); +} +.p-column-filter-clear-button:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-column-filter-overlay { + background: #212121; + color: #e6e6e6; + border: 1px solid #3c3c3c; + border-radius: 6px; + box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12); + min-width: 12.5rem; +} +.p-column-filter-overlay .p-column-filter-row-items { + padding: 0.5rem 0.5rem; +} +.p-column-filter-overlay .p-column-filter-row-items .p-column-filter-row-item { + margin: 0 0 4px 0; + padding: 0.5rem 1rem; + border: 0 none; + color: #e6e6e6; + background: transparent; + transition: box-shadow 0.3s; + border-radius: 6px; +} +.p-column-filter-overlay .p-column-filter-row-items .p-column-filter-row-item.p-highlight { + color: #9eade6; + background: rgba(158, 173, 230, 0.16); +} +.p-column-filter-overlay .p-column-filter-row-items .p-column-filter-row-item:not(.p-highlight):not(.p-disabled):hover { + color: #e6e6e6; + background: rgba(158, 173, 230, 0.08); +} +.p-column-filter-overlay .p-column-filter-row-items .p-column-filter-row-item:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: inset 0 0 0 0.15rem #e9aaff; +} +.p-column-filter-overlay .p-column-filter-row-items .p-column-filter-separator { + border-top: 1px solid #3c3c3c; + margin: 4px 0; +} +.p-column-filter-overlay-menu .p-column-filter-operator { + padding: 0.5rem 1.5rem; + border-bottom: 0 none; + color: #e6e6e6; + background: #212121; + margin: 0; + border-top-right-radius: 6px; + border-top-left-radius: 6px; +} +.p-column-filter-overlay-menu .p-column-filter-constraint { + padding: 1rem; + border-bottom: 1px solid #3c3c3c; +} +.p-column-filter-overlay-menu .p-column-filter-constraint .p-column-filter-matchmode-dropdown { + margin-bottom: 0.5rem; +} +.p-column-filter-overlay-menu .p-column-filter-constraint .p-column-filter-remove-button { + margin-top: 0.5rem; +} +.p-column-filter-overlay-menu .p-column-filter-constraint:last-child { + border-bottom: 0 none; +} +.p-column-filter-overlay-menu .p-column-filter-add-rule { + padding: 0.5rem 1rem; +} +.p-column-filter-overlay-menu .p-column-filter-buttonbar { + padding: 1rem; +} +.fc.fc-unthemed .fc-view-container th { + background: #212121; + border: 2px solid #3c3c3c; + color: #e6e6e6; +} +.fc.fc-unthemed .fc-view-container td.fc-widget-content { + border: 2px solid #3c3c3c; + color: #e6e6e6; +} +.fc.fc-unthemed .fc-view-container td.fc-head-container { + border: 2px solid #3c3c3c; +} +.fc.fc-unthemed .fc-view-container .fc-view { + background: #212121; +} +.fc.fc-unthemed .fc-view-container .fc-row { + border-right: 2px solid #3c3c3c; +} +.fc.fc-unthemed .fc-view-container .fc-event { + background: #e495ff; + border: 2px solid #e495ff; + color: #121212; +} +.fc.fc-unthemed .fc-view-container .fc-divider { + background: #212121; + border: 2px solid #3c3c3c; +} +.fc.fc-unthemed .fc-toolbar .fc-button { + color: #121212; + background: #e9aaff; + border: 2px solid #e9aaff; + font-size: 1rem; + transition: background-color 0.3s, color 0.3s, border-color 0.3s, box-shadow 0.3s; + border-radius: 6px; + display: flex; + align-items: center; +} +.fc.fc-unthemed .fc-toolbar .fc-button:enabled:hover { + background: #e495ff; + color: #121212; + border-color: #e495ff; +} +.fc.fc-unthemed .fc-toolbar .fc-button:enabled:active { + background: #de80ff; + color: #121212; + border-color: #de80ff; +} +.fc.fc-unthemed .fc-toolbar .fc-button:enabled:active:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.fc.fc-unthemed .fc-toolbar .fc-button .fc-icon-chevron-left { + font-family: "PrimeIcons" !important; + text-indent: 0; + font-size: 1rem; +} +.fc.fc-unthemed .fc-toolbar .fc-button .fc-icon-chevron-left:before { + content: ""; +} +.fc.fc-unthemed .fc-toolbar .fc-button .fc-icon-chevron-right { + font-family: "PrimeIcons" !important; + text-indent: 0; + font-size: 1rem; +} +.fc.fc-unthemed .fc-toolbar .fc-button .fc-icon-chevron-right:before { + content: ""; +} +.fc.fc-unthemed .fc-toolbar .fc-button:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.fc.fc-unthemed .fc-toolbar .fc-button.fc-dayGridMonth-button, +.fc.fc-unthemed .fc-toolbar .fc-button.fc-timeGridWeek-button, +.fc.fc-unthemed .fc-toolbar .fc-button.fc-timeGridDay-button { + background: #212121; + border: 2px solid #3c3c3c; + color: #e6e6e6; + transition: background-color 0.3s, color 0.3s, border-color 0.3s, box-shadow 0.3s; +} +.fc.fc-unthemed .fc-toolbar .fc-button.fc-dayGridMonth-button:hover, +.fc.fc-unthemed .fc-toolbar .fc-button.fc-timeGridWeek-button:hover, +.fc.fc-unthemed .fc-toolbar .fc-button.fc-timeGridDay-button:hover { + background: rgba(158, 173, 230, 0.08); + border-color: #3c3c3c; + color: #e6e6e6; +} +.fc.fc-unthemed .fc-toolbar .fc-button.fc-dayGridMonth-button.fc-button-active, +.fc.fc-unthemed .fc-toolbar .fc-button.fc-timeGridWeek-button.fc-button-active, +.fc.fc-unthemed .fc-toolbar .fc-button.fc-timeGridDay-button.fc-button-active { + background: rgba(158, 173, 230, 0.16); + border-color: rgba(158, 173, 230, 0.16); + color: #9eade6; +} +.fc.fc-unthemed .fc-toolbar .fc-button.fc-dayGridMonth-button.fc-button-active:hover, +.fc.fc-unthemed .fc-toolbar .fc-button.fc-timeGridWeek-button.fc-button-active:hover, +.fc.fc-unthemed .fc-toolbar .fc-button.fc-timeGridDay-button.fc-button-active:hover { + background: rgba(233, 170, 255, 0.24); + border-color: rgba(233, 170, 255, 0.24); + color: #9eade6; +} +.fc.fc-unthemed .fc-toolbar .fc-button.fc-dayGridMonth-button:focus, +.fc.fc-unthemed .fc-toolbar .fc-button.fc-timeGridWeek-button:focus, +.fc.fc-unthemed .fc-toolbar .fc-button.fc-timeGridDay-button:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; + z-index: 1; +} +.fc.fc-unthemed .fc-toolbar .fc-button-group .fc-button { + border-radius: 0; +} +.fc.fc-unthemed .fc-toolbar .fc-button-group .fc-button:first-child { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; +} +.fc.fc-unthemed .fc-toolbar .fc-button-group .fc-button:last-child { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} +.fc.fc-theme-standard .fc-view-harness .fc-scrollgrid { + border-color: #3c3c3c; +} +.fc.fc-theme-standard .fc-view-harness th { + background: #212121; + border-color: #3c3c3c; + color: #e6e6e6; +} +.fc.fc-theme-standard .fc-view-harness td { + color: #e6e6e6; + border-color: #3c3c3c; +} +.fc.fc-theme-standard .fc-view-harness .fc-view { + background: #212121; +} +.fc.fc-theme-standard .fc-view-harness .fc-popover { + background: none; + border: 0 none; +} +.fc.fc-theme-standard .fc-view-harness .fc-popover .fc-popover-header { + border: 2px solid #3c3c3c; + padding: 1rem; + background: #212121; + color: #e6e6e6; +} +.fc.fc-theme-standard .fc-view-harness .fc-popover .fc-popover-header .fc-popover-close { + opacity: 1; + display: flex; + align-items: center; + justify-content: center; + overflow: hidden; + font-family: "PrimeIcons" !important; + font-size: 1rem; + width: 2rem; + height: 2rem; + color: #b3b3b3; + border: 0 none; + background: transparent; + border-radius: 50%; + transition: background-color 0.3s, color 0.3s, box-shadow 0.3s; +} +.fc.fc-theme-standard .fc-view-harness .fc-popover .fc-popover-header .fc-popover-close:before { + content: ""; +} +.fc.fc-theme-standard .fc-view-harness .fc-popover .fc-popover-header .fc-popover-close:hover { + color: #e6e6e6; + border-color: transparent; + background: rgba(158, 173, 230, 0.08); +} +.fc.fc-theme-standard .fc-view-harness .fc-popover .fc-popover-header .fc-popover-close:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.fc.fc-theme-standard .fc-view-harness .fc-popover .fc-popover-body { + padding: 1rem; + border: 2px solid #3c3c3c; + background: #212121; + color: #e6e6e6; + border-top: 0 none; +} +.fc.fc-theme-standard .fc-view-harness .fc-event.fc-daygrid-block-event { + color: #121212; + background: #e495ff; + border-color: #e495ff; +} +.fc.fc-theme-standard .fc-view-harness .fc-event.fc-daygrid-block-event .fc-event-main { + color: #121212; +} +.fc.fc-theme-standard .fc-view-harness .fc-event.fc-daygrid-dot-event .fc-daygrid-event-dot { + background: #e495ff; + border-color: #e495ff; +} +.fc.fc-theme-standard .fc-view-harness .fc-event.fc-daygrid-dot-event:hover { + background: rgba(158, 173, 230, 0.08); + color: #e6e6e6; +} +.fc.fc-theme-standard .fc-view-harness .fc-cell-shaded { + background: #212121; +} +.fc.fc-theme-standard .fc-toolbar .fc-button { + color: #121212; + background: #e9aaff; + border: 2px solid #e9aaff; + font-size: 1rem; + transition: background-color 0.3s, color 0.3s, border-color 0.3s, box-shadow 0.3s; + border-radius: 6px; +} +.fc.fc-theme-standard .fc-toolbar .fc-button:enabled:hover { + background: #e495ff; + color: #121212; + border-color: #e495ff; +} +.fc.fc-theme-standard .fc-toolbar .fc-button:enabled:active { + background: #de80ff; + color: #121212; + border-color: #de80ff; +} +.fc.fc-theme-standard .fc-toolbar .fc-button:enabled:active:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.fc.fc-theme-standard .fc-toolbar .fc-button:disabled { + opacity: 0.4; + color: #121212; + background: #e9aaff; + border: 2px solid #e9aaff; +} +.fc.fc-theme-standard .fc-toolbar .fc-button .fc-icon-chevron-left { + font-family: "PrimeIcons" !important; + text-indent: 0; + font-size: 1rem; +} +.fc.fc-theme-standard .fc-toolbar .fc-button .fc-icon-chevron-left:before { + content: ""; +} +.fc.fc-theme-standard .fc-toolbar .fc-button .fc-icon-chevron-right { + font-family: "PrimeIcons" !important; + text-indent: 0; + font-size: 1rem; +} +.fc.fc-theme-standard .fc-toolbar .fc-button .fc-icon-chevron-right:before { + content: ""; +} +.fc.fc-theme-standard .fc-toolbar .fc-button:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.fc.fc-theme-standard .fc-toolbar .fc-button.fc-dayGridMonth-button, +.fc.fc-theme-standard .fc-toolbar .fc-button.fc-timeGridWeek-button, +.fc.fc-theme-standard .fc-toolbar .fc-button.fc-timeGridDay-button { + background: #212121; + border: 2px solid #3c3c3c; + color: #e6e6e6; + transition: background-color 0.3s, color 0.3s, border-color 0.3s, box-shadow 0.3s; +} +.fc.fc-theme-standard .fc-toolbar .fc-button.fc-dayGridMonth-button:hover, +.fc.fc-theme-standard .fc-toolbar .fc-button.fc-timeGridWeek-button:hover, +.fc.fc-theme-standard .fc-toolbar .fc-button.fc-timeGridDay-button:hover { + background: rgba(158, 173, 230, 0.08); + border-color: #3c3c3c; + color: #e6e6e6; +} +.fc.fc-theme-standard .fc-toolbar .fc-button.fc-dayGridMonth-button.fc-button-active, +.fc.fc-theme-standard .fc-toolbar .fc-button.fc-timeGridWeek-button.fc-button-active, +.fc.fc-theme-standard .fc-toolbar .fc-button.fc-timeGridDay-button.fc-button-active { + background: rgba(158, 173, 230, 0.16); + border-color: rgba(158, 173, 230, 0.16); + color: #9eade6; +} +.fc.fc-theme-standard .fc-toolbar .fc-button.fc-dayGridMonth-button.fc-button-active:hover, +.fc.fc-theme-standard .fc-toolbar .fc-button.fc-timeGridWeek-button.fc-button-active:hover, +.fc.fc-theme-standard .fc-toolbar .fc-button.fc-timeGridDay-button.fc-button-active:hover { + background: rgba(233, 170, 255, 0.24); + border-color: rgba(233, 170, 255, 0.24); + color: #9eade6; +} +.fc.fc-theme-standard .fc-toolbar .fc-button.fc-dayGridMonth-button:not(:disabled):focus, +.fc.fc-theme-standard .fc-toolbar .fc-button.fc-timeGridWeek-button:not(:disabled):focus, +.fc.fc-theme-standard .fc-toolbar .fc-button.fc-timeGridDay-button:not(:disabled):focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; + z-index: 1; +} +.fc.fc-theme-standard .fc-toolbar .fc-button-group .fc-button { + border-radius: 0; +} +.fc.fc-theme-standard .fc-toolbar .fc-button-group .fc-button:first-child { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; +} +.fc.fc-theme-standard .fc-toolbar .fc-button-group .fc-button:last-child { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} +.fc.fc-theme-standard .fc-highlight { + color: #9eade6; + background: rgba(158, 173, 230, 0.16); +} +.p-orderlist .p-orderlist-controls { + padding: 1rem; +} +.p-orderlist .p-orderlist-controls .p-button { + margin-bottom: 0.5rem; +} +.p-orderlist .p-orderlist-header { + background: #212121; + color: #e6e6e6; + border: 2px solid #3c3c3c; + padding: 1rem; + font-weight: 600; + border-bottom: 0 none; + border-top-right-radius: 6px; + border-top-left-radius: 6px; +} +.p-orderlist .p-orderlist-list { + border: 2px solid #3c3c3c; + background: #212121; + color: #e6e6e6; + padding: 0.5rem 0.5rem; + border-bottom-right-radius: 6px; + border-bottom-left-radius: 6px; + outline: 0 none; +} +.p-orderlist .p-orderlist-list .p-orderlist-item { + padding: 0.5rem 1rem; + margin: 0 0 4px 0; + border: 0 none; + color: #e6e6e6; + background: transparent; + transition: transform 0.3s, box-shadow 0.3s; +} +.p-orderlist .p-orderlist-list .p-orderlist-item:not(.p-highlight):hover { + background: rgba(158, 173, 230, 0.08); + color: #e6e6e6; +} +.p-orderlist .p-orderlist-list .p-orderlist-item.p-focus { + color: #e6e6e6; + background: rgba(233, 170, 255, 0.1); +} +.p-orderlist .p-orderlist-list .p-orderlist-item.p-highlight { + color: #9eade6; + background: rgba(158, 173, 230, 0.16); +} +.p-orderlist .p-orderlist-list .p-orderlist-item.p-highlight.p-focus { + background: rgba(233, 170, 255, 0.24); +} +.p-orderlist.p-orderlist-striped .p-orderlist-list .p-orderlist-item:nth-child(even) { + background: rgba(255, 255, 255, 0.01); +} +.p-orderlist.p-orderlist-striped .p-orderlist-list .p-orderlist-item:nth-child(even):hover { + background: rgba(158, 173, 230, 0.08); +} +.p-organizationchart .p-organizationchart-node-content.p-organizationchart-selectable-node:not(.p-highlight):hover { + background: rgba(158, 173, 230, 0.08); + color: #e6e6e6; +} +.p-organizationchart .p-organizationchart-node-content.p-highlight { + background: rgba(158, 173, 230, 0.16); + color: #9eade6; +} +.p-organizationchart .p-organizationchart-node-content.p-highlight .p-node-toggler i { + color: rgba(57, 87, 204, 0.16); +} +.p-organizationchart .p-organizationchart-line-down { + background: #3c3c3c; +} +.p-organizationchart .p-organizationchart-line-left { + border-right: 2px solid #3c3c3c; + border-color: #3c3c3c; +} +.p-organizationchart .p-organizationchart-line-top { + border-top: 2px solid #3c3c3c; + border-color: #3c3c3c; +} +.p-organizationchart .p-organizationchart-node-content { + border: 2px solid #3c3c3c; + background: #212121; + color: #e6e6e6; + padding: 1rem; +} +.p-organizationchart .p-organizationchart-node-content .p-node-toggler { + background: inherit; + color: inherit; + border-radius: 50%; +} +.p-organizationchart .p-organizationchart-node-content .p-node-toggler:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-paginator { + background: #212121; + color: #b3b3b3; + border: solid #3c3c3c; + border-width: 2px; + padding: 0.5rem 1rem; + border-radius: 6px; +} +.p-paginator .p-paginator-first, +.p-paginator .p-paginator-prev, +.p-paginator .p-paginator-next, +.p-paginator .p-paginator-last { + background-color: transparent; + border: 0 none; + color: #b3b3b3; + min-width: 2.857rem; + height: 2.857rem; + margin: 0.143rem; + transition: box-shadow 0.3s; + border-radius: 6px; +} +.p-paginator .p-paginator-first:not(.p-disabled):not(.p-highlight):hover, +.p-paginator .p-paginator-prev:not(.p-disabled):not(.p-highlight):hover, +.p-paginator .p-paginator-next:not(.p-disabled):not(.p-highlight):hover, +.p-paginator .p-paginator-last:not(.p-disabled):not(.p-highlight):hover { + background: rgba(158, 173, 230, 0.08); + border-color: transparent; + color: #e6e6e6; +} +.p-paginator .p-paginator-first { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; +} +.p-paginator .p-paginator-last { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} +.p-paginator .p-dropdown { + margin-left: 0.5rem; + margin-right: 0.5rem; + height: 2.857rem; +} +.p-paginator .p-dropdown .p-dropdown-label { + padding-right: 0; +} +.p-paginator .p-paginator-page-input { + margin-left: 0.5rem; + margin-right: 0.5rem; +} +.p-paginator .p-paginator-page-input .p-inputtext { + max-width: 2.857rem; +} +.p-paginator .p-paginator-current { + background-color: transparent; + border: 0 none; + color: #b3b3b3; + min-width: 2.857rem; + height: 2.857rem; + margin: 0.143rem; + padding: 0 0.5rem; +} +.p-paginator .p-paginator-pages .p-paginator-page { + background-color: transparent; + border: 0 none; + color: #b3b3b3; + min-width: 2.857rem; + height: 2.857rem; + margin: 0.143rem; + transition: box-shadow 0.3s; + border-radius: 6px; +} +.p-paginator .p-paginator-pages .p-paginator-page.p-highlight { + background: rgba(158, 173, 230, 0.16); + border-color: rgba(158, 173, 230, 0.16); + color: #9eade6; +} +.p-paginator .p-paginator-pages .p-paginator-page:not(.p-highlight):hover { + background: rgba(158, 173, 230, 0.08); + border-color: transparent; + color: #e6e6e6; +} +.p-picklist .p-picklist-buttons { + padding: 1rem; +} +.p-picklist .p-picklist-buttons .p-button { + margin-bottom: 0.5rem; +} +.p-picklist .p-picklist-header { + background: #212121; + color: #e6e6e6; + border: 2px solid #3c3c3c; + padding: 1rem; + font-weight: 600; + border-bottom: 0 none; + border-top-right-radius: 6px; + border-top-left-radius: 6px; +} +.p-picklist .p-picklist-list { + border: 2px solid #3c3c3c; + background: #212121; + color: #e6e6e6; + padding: 0.5rem 0.5rem; + border-bottom-right-radius: 6px; + border-bottom-left-radius: 6px; + outline: 0 none; +} +.p-picklist .p-picklist-list .p-picklist-item { + padding: 0.5rem 1rem; + margin: 0 0 4px 0; + border: 0 none; + color: #e6e6e6; + background: transparent; + transition: transform 0.3s, box-shadow 0.3s; +} +.p-picklist .p-picklist-list .p-picklist-item:not(.p-highlight):hover { + background: rgba(158, 173, 230, 0.08); + color: #e6e6e6; +} +.p-picklist .p-picklist-list .p-picklist-item.p-focus { + color: #e6e6e6; + background: rgba(233, 170, 255, 0.1); +} +.p-picklist .p-picklist-list .p-picklist-item.p-highlight { + color: #9eade6; + background: rgba(158, 173, 230, 0.16); +} +.p-picklist .p-picklist-list .p-picklist-item.p-highlight.p-focus { + background: rgba(233, 170, 255, 0.24); +} +.p-picklist.p-picklist-striped .p-picklist-list .p-picklist-item:nth-child(even) { + background: rgba(255, 255, 255, 0.01); +} +.p-picklist.p-picklist-striped .p-picklist-list .p-picklist-item:nth-child(even):hover { + background: rgba(158, 173, 230, 0.08); +} +.p-timeline .p-timeline-event-marker { + border: 2px solid #e9aaff; + border-radius: 50%; + width: 1rem; + height: 1rem; + background-color: #212121; +} +.p-timeline .p-timeline-event-connector { + background-color: #3c3c3c; +} +.p-timeline.p-timeline-vertical .p-timeline-event-opposite, +.p-timeline.p-timeline-vertical .p-timeline-event-content { + padding: 0 1rem; +} +.p-timeline.p-timeline-vertical .p-timeline-event-connector { + width: 2px; +} +.p-timeline.p-timeline-horizontal .p-timeline-event-opposite, +.p-timeline.p-timeline-horizontal .p-timeline-event-content { + padding: 1rem 0; +} +.p-timeline.p-timeline-horizontal .p-timeline-event-connector { + height: 2px; +} +.p-tree { + border: 2px solid #3c3c3c; + background: #212121; + color: #e6e6e6; + padding: 1rem; + border-radius: 6px; +} +.p-tree .p-tree-container .p-treenode { + padding: 0.143rem; + outline: 0 none; +} +.p-tree .p-tree-container .p-treenode:focus > .p-treenode-content { + outline: 0 none; + outline-offset: 0; + box-shadow: inset 0 0 0 0.15rem #e9aaff; +} +.p-tree .p-tree-container .p-treenode .p-treenode-content { + border-radius: 6px; + transition: box-shadow 0.3s; + padding: 0.5rem; +} +.p-tree .p-tree-container .p-treenode .p-treenode-content .p-tree-toggler { + margin-right: 0.5rem; + width: 2rem; + height: 2rem; + color: #b3b3b3; + border: 0 none; + background: transparent; + border-radius: 50%; + transition: background-color 0.3s, color 0.3s, box-shadow 0.3s; +} +.p-tree .p-tree-container .p-treenode .p-treenode-content .p-tree-toggler:enabled:hover { + color: #e6e6e6; + border-color: transparent; + background: rgba(158, 173, 230, 0.08); +} +.p-tree .p-tree-container .p-treenode .p-treenode-content .p-tree-toggler:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-tree .p-tree-container .p-treenode .p-treenode-content .p-treenode-icon { + margin-right: 0.5rem; + color: #b3b3b3; +} +.p-tree .p-tree-container .p-treenode .p-treenode-content .p-checkbox { + margin-right: 0.5rem; +} +.p-tree .p-tree-container .p-treenode .p-treenode-content .p-checkbox .p-indeterminate .p-checkbox-icon { + color: #e6e6e6; +} +.p-tree .p-tree-container .p-treenode .p-treenode-content.p-highlight { + background: rgba(158, 173, 230, 0.16); + color: #9eade6; +} +.p-tree .p-tree-container .p-treenode .p-treenode-content.p-highlight .p-tree-toggler, +.p-tree .p-tree-container .p-treenode .p-treenode-content.p-highlight .p-treenode-icon { + color: #9eade6; +} +.p-tree .p-tree-container .p-treenode .p-treenode-content.p-highlight .p-tree-toggler:hover, +.p-tree .p-tree-container .p-treenode .p-treenode-content.p-highlight .p-treenode-icon:hover { + color: #9eade6; +} +.p-tree .p-tree-container .p-treenode .p-treenode-content.p-treenode-selectable:not(.p-highlight):hover { + background: rgba(158, 173, 230, 0.08); + color: #e6e6e6; +} +.p-tree .p-tree-filter-container { + margin-bottom: 0.5rem; +} +.p-tree .p-tree-filter-container .p-tree-filter { + width: 100%; + padding-right: 1.75rem; +} +.p-tree .p-tree-filter-container .p-tree-filter-icon { + right: 0.75rem; + color: #b3b3b3; +} +.p-tree .p-treenode-children { + padding: 0 0 0 1rem; +} +.p-tree .p-tree-loading-icon { + font-size: 2rem; +} +.p-tree .p-tree-loading-icon.p-icon { + width: 2rem; + height: 2rem; +} +.p-treetable .p-paginator-top { + border-width: 0 0 2px 0; + border-radius: 0; +} +.p-treetable .p-paginator-bottom { + border-width: 0 0 2px 0; + border-radius: 0; +} +.p-treetable .p-treetable-header { + background: #212121; + color: #b3b3b3; + border: 2px solid #3c3c3c; + border-width: 0 0 2px 0; + padding: 1rem 1rem; + font-weight: 600; +} +.p-treetable .p-treetable-footer { + background: #212121; + color: #e6e6e6; + border: 2px solid #3c3c3c; + border-width: 0 0 2px 0; + padding: 1rem 1rem; + font-weight: 600; +} +.p-treetable .p-treetable-thead > tr > th { + text-align: left; + padding: 1rem 1rem; + border: 2px solid #3c3c3c; + border-width: 0 0 2px 0; + font-weight: 600; + color: #e6e6e6; + background: #212121; + transition: box-shadow 0.3s; +} +.p-treetable .p-treetable-tfoot > tr > td { + text-align: left; + padding: 1rem 1rem; + border: 2px solid #3c3c3c; + border-width: 0 0 2px 0; + font-weight: 600; + color: #e6e6e6; + background: #212121; +} +.p-treetable .p-sortable-column { + outline-color: #e9aaff; +} +.p-treetable .p-sortable-column .p-sortable-column-icon { + color: #b3b3b3; + margin-left: 0.5rem; +} +.p-treetable .p-sortable-column .p-sortable-column-badge { + border-radius: 50%; + height: 1.143rem; + min-width: 1.143rem; + line-height: 1.143rem; + color: #9eade6; + background: rgba(158, 173, 230, 0.16); + margin-left: 0.5rem; +} +.p-treetable .p-sortable-column:not(.p-highlight):hover { + background: rgba(158, 173, 230, 0.08); + color: #e6e6e6; +} +.p-treetable .p-sortable-column:not(.p-highlight):hover .p-sortable-column-icon { + color: #e6e6e6; +} +.p-treetable .p-sortable-column.p-highlight { + background: #212121; + color: #e9aaff; +} +.p-treetable .p-sortable-column.p-highlight .p-sortable-column-icon { + color: #e9aaff; +} +.p-treetable .p-treetable-tbody > tr { + background: #212121; + color: #e6e6e6; + transition: box-shadow 0.3s; +} +.p-treetable .p-treetable-tbody > tr > td { + text-align: left; + border: 2px solid #3c3c3c; + border-width: 0 0 2px 0; + padding: 1rem 1rem; +} +.p-treetable .p-treetable-tbody > tr > td .p-treetable-toggler { + width: 2rem; + height: 2rem; + color: #b3b3b3; + border: 0 none; + background: transparent; + border-radius: 50%; + transition: background-color 0.3s, color 0.3s, box-shadow 0.3s; + margin-right: 0.5rem; +} +.p-treetable .p-treetable-tbody > tr > td .p-treetable-toggler:enabled:hover { + color: #e6e6e6; + border-color: transparent; + background: rgba(158, 173, 230, 0.08); +} +.p-treetable .p-treetable-tbody > tr > td .p-treetable-toggler:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-treetable .p-treetable-tbody > tr > td .p-treetable-toggler + .p-checkbox { + margin-right: 0.5rem; +} +.p-treetable .p-treetable-tbody > tr > td .p-treetable-toggler + .p-checkbox .p-indeterminate .p-checkbox-icon { + color: #e6e6e6; +} +.p-treetable .p-treetable-tbody > tr:focus { + outline: 0.15rem solid #e9aaff; + outline-offset: -0.15rem; +} +.p-treetable .p-treetable-tbody > tr.p-highlight { + background: rgba(158, 173, 230, 0.16); + color: #9eade6; +} +.p-treetable .p-treetable-tbody > tr.p-highlight .p-treetable-toggler { + color: #9eade6; +} +.p-treetable .p-treetable-tbody > tr.p-highlight .p-treetable-toggler:hover { + color: #9eade6; +} +.p-treetable.p-treetable-hoverable-rows .p-treetable-tbody > tr:not(.p-highlight):hover { + background: rgba(158, 173, 230, 0.08); + color: #e6e6e6; +} +.p-treetable.p-treetable-hoverable-rows .p-treetable-tbody > tr:not(.p-highlight):hover .p-treetable-toggler { + color: #e6e6e6; +} +.p-treetable .p-column-resizer-helper { + background: #e9aaff; +} +.p-treetable .p-treetable-scrollable-header, +.p-treetable .p-treetable-scrollable-footer { + background: #212121; +} +.p-treetable .p-treetable-loading-icon { + font-size: 2rem; +} +.p-treetable .p-treetable-loading-icon.p-icon { + width: 2rem; + height: 2rem; +} +.p-treetable.p-treetable-gridlines .p-datatable-header { + border-width: 1px 1px 0 1px; +} +.p-treetable.p-treetable-gridlines .p-treetable-footer { + border-width: 0 1px 1px 1px; +} +.p-treetable.p-treetable-gridlines .p-treetable-top { + border-width: 0 1px 0 1px; +} +.p-treetable.p-treetable-gridlines .p-treetable-bottom { + border-width: 0 1px 1px 1px; +} +.p-treetable.p-treetable-gridlines .p-treetable-thead > tr > th { + border-width: 1px; +} +.p-treetable.p-treetable-gridlines .p-treetable-tbody > tr > td { + border-width: 1px; +} +.p-treetable.p-treetable-gridlines .p-treetable-tfoot > tr > td { + border-width: 1px; +} +.p-treetable.p-treetable-sm .p-treetable-header { + padding: 0.875rem 0.875rem; +} +.p-treetable.p-treetable-sm .p-treetable-thead > tr > th { + padding: 0.5rem 0.5rem; +} +.p-treetable.p-treetable-sm .p-treetable-tbody > tr > td { + padding: 0.5rem 0.5rem; +} +.p-treetable.p-treetable-sm .p-treetable-tfoot > tr > td { + padding: 0.5rem 0.5rem; +} +.p-treetable.p-treetable-sm .p-treetable-footer { + padding: 0.5rem 0.5rem; +} +.p-treetable.p-treetable-lg .p-treetable-header { + padding: 1.25rem 1.25rem; +} +.p-treetable.p-treetable-lg .p-treetable-thead > tr > th { + padding: 1.25rem 1.25rem; +} +.p-treetable.p-treetable-lg .p-treetable-tbody > tr > td { + padding: 1.25rem 1.25rem; +} +.p-treetable.p-treetable-lg .p-treetable-tfoot > tr > td { + padding: 1.25rem 1.25rem; +} +.p-treetable.p-treetable-lg .p-treetable-footer { + padding: 1.25rem 1.25rem; +} +.p-accordion .p-accordion-header .p-accordion-header-link { + padding: 1rem; + border: 2px solid #3c3c3c; + color: #e6e6e6; + background: #212121; + font-weight: 600; + border-radius: 6px; + transition: box-shadow 0.3s; +} +.p-accordion .p-accordion-header .p-accordion-header-link .p-accordion-toggle-icon { + margin-right: 0.5rem; +} +.p-accordion .p-accordion-header:not(.p-disabled) .p-accordion-header-link:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: inset 0 0 0 1px #e9aaff; +} +.p-accordion .p-accordion-header:not(.p-highlight):not(.p-disabled):hover .p-accordion-header-link { + background: rgba(158, 173, 230, 0.08); + border-color: #3c3c3c; + color: #e6e6e6; +} +.p-accordion .p-accordion-header:not(.p-disabled).p-highlight .p-accordion-header-link { + background: #212121; + border-color: #3c3c3c; + color: #e6e6e6; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.p-accordion .p-accordion-header:not(.p-disabled).p-highlight:hover .p-accordion-header-link { + border-color: #3c3c3c; + background: rgba(158, 173, 230, 0.08); + color: #e6e6e6; +} +.p-accordion .p-accordion-content { + padding: 1rem; + border: 2px solid #3c3c3c; + background: #212121; + color: #e6e6e6; + border-top: 0; + border-top-right-radius: 0; + border-top-left-radius: 0; + border-bottom-right-radius: 6px; + border-bottom-left-radius: 6px; +} +.p-accordion .p-accordion-tab { + margin-bottom: 0; +} +.p-accordion .p-accordion-tab .p-accordion-header .p-accordion-header-link { + border-radius: 0; +} +.p-accordion .p-accordion-tab .p-accordion-content { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.p-accordion .p-accordion-tab:not(:first-child) .p-accordion-header .p-accordion-header-link { + border-top: 0 none; +} +.p-accordion + .p-accordion-tab:not(:first-child) + .p-accordion-header:not(.p-highlight):not(.p-disabled):hover + .p-accordion-header-link, +.p-accordion + .p-accordion-tab:not(:first-child) + .p-accordion-header:not(.p-disabled).p-highlight:hover + .p-accordion-header-link { + border-top: 0 none; +} +.p-accordion .p-accordion-tab:first-child .p-accordion-header .p-accordion-header-link { + border-top-right-radius: 6px; + border-top-left-radius: 6px; +} +.p-accordion .p-accordion-tab:last-child .p-accordion-header:not(.p-highlight) .p-accordion-header-link { + border-bottom-right-radius: 6px; + border-bottom-left-radius: 6px; +} +.p-accordion .p-accordion-tab:last-child .p-accordion-content { + border-bottom-right-radius: 6px; + border-bottom-left-radius: 6px; +} +.p-card { + background: #212121; + color: #e6e6e6; + box-shadow: 0 2px 1px -1px rgba(0, 0, 0, 0.2), 0 1px 1px 0 rgba(0, 0, 0, 0.14), 0 1px 3px 0 rgba(0, 0, 0, 0.12); + border-radius: 6px; +} +.p-card .p-card-body { + padding: 1rem; +} +.p-card .p-card-title { + font-size: 1.5rem; + font-weight: 600; + margin-bottom: 0.5rem; +} +.p-card .p-card-subtitle { + font-weight: 400; + margin-bottom: 0.5rem; + color: #b3b3b3; +} +.p-card .p-card-content { + padding: 1rem 0; +} +.p-card .p-card-footer { + padding: 1rem 0 0 0; +} +.p-fieldset { + border: 2px solid #3c3c3c; + background: #212121; + color: #e6e6e6; + border-radius: 6px; +} +.p-fieldset .p-fieldset-legend { + padding: 1rem; + border: 2px solid #3c3c3c; + color: #e6e6e6; + background: #212121; + font-weight: 600; + border-radius: 6px; +} +.p-fieldset.p-fieldset-toggleable .p-fieldset-legend { + padding: 0; + transition: background-color 0.3s, color 0.3s, box-shadow 0.3s; +} +.p-fieldset.p-fieldset-toggleable .p-fieldset-legend a { + padding: 1rem; + color: #e6e6e6; + border-radius: 6px; + transition: box-shadow 0.3s; +} +.p-fieldset.p-fieldset-toggleable .p-fieldset-legend a .p-fieldset-toggler { + margin-right: 0.5rem; +} +.p-fieldset.p-fieldset-toggleable .p-fieldset-legend a:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-fieldset.p-fieldset-toggleable .p-fieldset-legend a:hover { + color: #e6e6e6; +} +.p-fieldset.p-fieldset-toggleable .p-fieldset-legend:hover { + background: rgba(158, 173, 230, 0.08); + border-color: #3c3c3c; + color: #e6e6e6; +} +.p-fieldset .p-fieldset-content { + padding: 1rem; +} +.p-divider .p-divider-content { + background-color: #212121; +} +.p-divider.p-divider-horizontal { + margin: 1rem 0; + padding: 0 1rem; +} +.p-divider.p-divider-horizontal:before { + border-top: 1px #3c3c3c; +} +.p-divider.p-divider-horizontal .p-divider-content { + padding: 0 0.5rem; +} +.p-divider.p-divider-vertical { + margin: 0 1rem; + padding: 1rem 0; +} +.p-divider.p-divider-vertical:before { + border-left: 1px #3c3c3c; +} +.p-divider.p-divider-vertical .p-divider-content { + padding: 0.5rem 0; +} +.p-panel .p-panel-header { + border: 2px solid #3c3c3c; + padding: 1rem; + background: #212121; + color: #e6e6e6; + border-top-right-radius: 6px; + border-top-left-radius: 6px; +} +.p-panel .p-panel-header .p-panel-title { + font-weight: 600; +} +.p-panel .p-panel-header .p-panel-header-icon { + width: 2rem; + height: 2rem; + color: #b3b3b3; + border: 0 none; + background: transparent; + border-radius: 50%; + transition: background-color 0.3s, color 0.3s, box-shadow 0.3s; +} +.p-panel .p-panel-header .p-panel-header-icon:enabled:hover { + color: #e6e6e6; + border-color: transparent; + background: rgba(158, 173, 230, 0.08); +} +.p-panel .p-panel-header .p-panel-header-icon:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-panel.p-panel-toggleable .p-panel-header { + padding: 0.5rem 1rem; +} +.p-panel .p-panel-content { + padding: 1rem; + border: 2px solid #3c3c3c; + background: #212121; + color: #e6e6e6; + border-top: 0 none; +} +.p-panel .p-panel-content:last-child { + border-bottom-right-radius: 6px; + border-bottom-left-radius: 6px; +} +.p-panel .p-panel-footer { + padding: 0.5rem 1rem; + border: 2px solid #3c3c3c; + background: #212121; + color: #e6e6e6; + border-bottom-right-radius: 6px; + border-bottom-left-radius: 6px; + border-top: 0 none; +} +.p-scrollpanel .p-scrollpanel-bar { + background: #3c3c3c; + border: 0 none; + transition: background-color 0.3s, color 0.3s, border-color 0.3s, box-shadow 0.3s; +} +.p-scrollpanel .p-scrollpanel-bar:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-splitter { + border: 2px solid #3c3c3c; + background: #212121; + border-radius: 6px; + color: #e6e6e6; +} +.p-splitter .p-splitter-gutter { + transition: background-color 0.3s, color 0.3s, box-shadow 0.3s; + background: rgba(255, 255, 255, 0.03); +} +.p-splitter .p-splitter-gutter .p-splitter-gutter-handle { + background: #3c3c3c; + transition: background-color 0.3s, color 0.3s, border-color 0.3s, box-shadow 0.3s; +} +.p-splitter .p-splitter-gutter .p-splitter-gutter-handle:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-splitter .p-splitter-gutter-resizing { + background: #3c3c3c; +} +.p-tabview .p-tabview-nav { + background: transparent; + border: 1px solid #3c3c3c; + border-width: 0 0 2px 0; +} +.p-tabview .p-tabview-nav li { + margin-right: 0; +} +.p-tabview .p-tabview-nav li .p-tabview-nav-link { + border: solid #3c3c3c; + border-width: 0 0 2px 0; + border-color: transparent transparent #3c3c3c transparent; + background: #212121; + color: #b3b3b3; + padding: 1rem; + font-weight: 600; + border-top-right-radius: 6px; + border-top-left-radius: 6px; + transition: box-shadow 0.3s; + margin: 0 0 -2px 0; +} +.p-tabview .p-tabview-nav li .p-tabview-nav-link:not(.p-disabled):focus { + outline: 0 none; + outline-offset: 0; + box-shadow: inset 0 0 0 1px #e9aaff; +} +.p-tabview .p-tabview-nav li:not(.p-highlight):not(.p-disabled):hover .p-tabview-nav-link { + background: #212121; + border-color: #e9aaff; + color: #e6e6e6; +} +.p-tabview .p-tabview-nav li.p-highlight .p-tabview-nav-link { + background: #212121; + border-color: #e9aaff; + color: #e9aaff; +} +.p-tabview .p-tabview-nav-btn.p-link { + background: #212121; + color: #e9aaff; + width: 2.857rem; + box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), + 0px 1px 5px 0px rgba(0, 0, 0, 0.12); + border-radius: 0; +} +.p-tabview .p-tabview-nav-btn.p-link:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: inset 0 0 0 1px #e9aaff; +} +.p-tabview .p-tabview-panels { + background: #212121; + padding: 1rem; + border: 0 none; + color: #e6e6e6; + border-bottom-right-radius: 6px; + border-bottom-left-radius: 6px; +} +.p-toolbar { + background: #212121; + border: 2px solid #3c3c3c; + padding: 1rem; + border-radius: 6px; + gap: 0.5rem; +} +.p-toolbar .p-toolbar-separator { + margin: 0 0.5rem; +} +.p-confirm-popup { + background: #212121; + color: #e6e6e6; + border: 2px solid #3c3c3c; + border-radius: 6px; + box-shadow: 0px 11px 15px -7px rgba(0, 0, 0, 0.2), 0px 24px 38px 3px rgba(0, 0, 0, 0.14), + 0px 9px 46px 8px rgba(0, 0, 0, 0.12); +} +.p-confirm-popup .p-confirm-popup-content { + padding: 1rem; +} +.p-confirm-popup .p-confirm-popup-footer { + text-align: right; + padding: 0 1rem 1rem 1rem; +} +.p-confirm-popup .p-confirm-popup-footer button { + margin: 0 0.5rem 0 0; + width: auto; +} +.p-confirm-popup .p-confirm-popup-footer button:last-child { + margin: 0; +} +.p-confirm-popup:after { + border: solid transparent; + border-color: rgba(33, 33, 33, 0); + border-bottom-color: #212121; +} +.p-confirm-popup:before { + border: solid transparent; + border-color: rgba(60, 60, 60, 0); + border-bottom-color: #3c3c3c; +} +.p-confirm-popup.p-confirm-popup-flipped:after { + border-top-color: #212121; +} +.p-confirm-popup.p-confirm-popup-flipped:before { + border-top-color: #3c3c3c; +} +.p-confirm-popup .p-confirm-popup-icon { + font-size: 1.5rem; +} +.p-confirm-popup .p-confirm-popup-icon.p-icon { + width: 1.5rem; + height: 1.5rem; +} +.p-confirm-popup .p-confirm-popup-message { + margin-left: 1rem; +} +.p-dialog { + border-radius: 6px; + box-shadow: 0px 11px 15px -7px rgba(0, 0, 0, 0.2), 0px 24px 38px 3px rgba(0, 0, 0, 0.14), + 0px 9px 46px 8px rgba(0, 0, 0, 0.12); + border: 2px solid #3c3c3c; +} +.p-dialog .p-dialog-header { + border-bottom: 0 none; + background: #212121; + color: #e6e6e6; + padding: 1.5rem; + border-top-right-radius: 6px; + border-top-left-radius: 6px; +} +.p-dialog .p-dialog-header .p-dialog-title { + font-weight: 600; + font-size: 1.25rem; +} +.p-dialog .p-dialog-header .p-dialog-header-icon { + width: 2rem; + height: 2rem; + color: #b3b3b3; + border: 0 none; + background: transparent; + border-radius: 50%; + transition: background-color 0.3s, color 0.3s, box-shadow 0.3s; + margin-right: 0.5rem; +} +.p-dialog .p-dialog-header .p-dialog-header-icon:enabled:hover { + color: #e6e6e6; + border-color: transparent; + background: rgba(158, 173, 230, 0.08); +} +.p-dialog .p-dialog-header .p-dialog-header-icon:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-dialog .p-dialog-header .p-dialog-header-icon:last-child { + margin-right: 0; +} +.p-dialog .p-dialog-content { + background: #212121; + color: #e6e6e6; + padding: 0 1.5rem 2rem 1.5rem; +} +.p-dialog .p-dialog-content:last-of-type { + border-bottom-right-radius: 6px; + border-bottom-left-radius: 6px; +} +.p-dialog .p-dialog-footer { + border-top: 0 none; + background: #212121; + color: #e6e6e6; + padding: 0 1.5rem 1.5rem 1.5rem; + text-align: right; + border-bottom-right-radius: 6px; + border-bottom-left-radius: 6px; +} +.p-dialog .p-dialog-footer button { + margin: 0 0.5rem 0 0; + width: auto; +} +.p-dialog.p-confirm-dialog .p-confirm-dialog-icon { + font-size: 2rem; +} +.p-dialog.p-confirm-dialog .p-confirm-dialog-message:not(:first-child) { + margin-left: 1rem; +} +.p-overlaypanel { + background: #212121; + color: #e6e6e6; + border: 2px solid #3c3c3c; + border-radius: 6px; + box-shadow: 0px 11px 15px -7px rgba(0, 0, 0, 0.2), 0px 24px 38px 3px rgba(0, 0, 0, 0.14), + 0px 9px 46px 8px rgba(0, 0, 0, 0.12); +} +.p-overlaypanel .p-overlaypanel-content { + padding: 1rem; +} +.p-overlaypanel .p-overlaypanel-close { + background: #e9aaff; + color: #121212; + width: 2rem; + height: 2rem; + transition: background-color 0.3s, color 0.3s, box-shadow 0.3s; + border-radius: 50%; + position: absolute; + top: -1rem; + right: -1rem; +} +.p-overlaypanel .p-overlaypanel-close:enabled:hover { + background: #e495ff; + color: #121212; +} +.p-overlaypanel:after { + border: solid transparent; + border-color: rgba(33, 33, 33, 0); + border-bottom-color: #212121; +} +.p-overlaypanel:before { + border: solid transparent; + border-color: rgba(60, 60, 60, 0); + border-bottom-color: #393939; +} +.p-overlaypanel.p-overlaypanel-flipped:after { + border-top-color: #212121; +} +.p-overlaypanel.p-overlaypanel-flipped:before { + border-top-color: #3c3c3c; +} +.p-sidebar { + background: #212121; + color: #e6e6e6; + border: 2px solid #3c3c3c; + box-shadow: 0px 11px 15px -7px rgba(0, 0, 0, 0.2), 0px 24px 38px 3px rgba(0, 0, 0, 0.14), + 0px 9px 46px 8px rgba(0, 0, 0, 0.12); +} +.p-sidebar .p-sidebar-header { + padding: 1rem; +} +.p-sidebar .p-sidebar-header .p-sidebar-close, +.p-sidebar .p-sidebar-header .p-sidebar-icon { + width: 2rem; + height: 2rem; + color: #b3b3b3; + border: 0 none; + background: transparent; + border-radius: 50%; + transition: background-color 0.3s, color 0.3s, box-shadow 0.3s; +} +.p-sidebar .p-sidebar-header .p-sidebar-close:enabled:hover, +.p-sidebar .p-sidebar-header .p-sidebar-icon:enabled:hover { + color: #e6e6e6; + border-color: transparent; + background: rgba(158, 173, 230, 0.08); +} +.p-sidebar .p-sidebar-header .p-sidebar-close:focus, +.p-sidebar .p-sidebar-header .p-sidebar-icon:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-sidebar .p-sidebar-header + .p-sidebar-content { + padding-top: 0; +} +.p-sidebar .p-sidebar-content { + padding: 1rem; +} +.p-tooltip .p-tooltip-text { + background: #3c3c3c; + color: #e6e6e6; + padding: 0.5rem 0.75rem; + box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12); + border-radius: 6px; +} +.p-tooltip.p-tooltip-right .p-tooltip-arrow { + border-right-color: #3c3c3c; +} +.p-tooltip.p-tooltip-left .p-tooltip-arrow { + border-left-color: #3c3c3c; +} +.p-tooltip.p-tooltip-top .p-tooltip-arrow { + border-top-color: #3c3c3c; +} +.p-tooltip.p-tooltip-bottom .p-tooltip-arrow { + border-bottom-color: #3c3c3c; +} +.p-fileupload .p-fileupload-buttonbar { + background: #212121; + padding: 1rem; + border: 2px solid #3c3c3c; + color: #e6e6e6; + border-bottom: 0 none; + border-top-right-radius: 6px; + border-top-left-radius: 6px; + gap: 0.5rem; +} +.p-fileupload .p-fileupload-buttonbar .p-button.p-fileupload-choose.p-focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-fileupload .p-fileupload-content { + background: #212121; + padding: 2rem 1rem; + border: 2px solid #3c3c3c; + color: #e6e6e6; + border-bottom-right-radius: 6px; + border-bottom-left-radius: 6px; +} +.p-fileupload .p-fileupload-file { + padding: 1rem; + border: 1px solid #3c3c3c; + border-radius: 6px; + gap: 0.5rem; + margin-bottom: 0.5rem; +} +.p-fileupload .p-fileupload-file:last-child { + margin-bottom: 0; +} +.p-fileupload .p-fileupload-file-name { + margin-bottom: 0.5rem; +} +.p-fileupload .p-fileupload-file-size { + margin-right: 0.5rem; +} +.p-fileupload .p-progressbar { + height: 0.25rem; +} +.p-fileupload .p-fileupload-row > div { + padding: 1rem 1rem; +} +.p-fileupload.p-fileupload-advanced .p-message { + margin-top: 0; +} +.p-fileupload-choose:not(.p-disabled):hover { + background: #e495ff; + color: #121212; + border-color: #e495ff; +} +.p-fileupload-choose:not(.p-disabled):active { + background: #de80ff; + color: #121212; + border-color: #de80ff; +} +.p-breadcrumb { + background: #212121; + border: 2px solid #3c3c3c; + border-radius: 6px; + padding: 1rem; +} +.p-breadcrumb .p-breadcrumb-list li .p-menuitem-link { + transition: box-shadow 0.3s; + border-radius: 6px; +} +.p-breadcrumb .p-breadcrumb-list li .p-menuitem-link:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-breadcrumb .p-breadcrumb-list li .p-menuitem-link .p-menuitem-text { + color: #e6e6e6; +} +.p-breadcrumb .p-breadcrumb-list li .p-menuitem-link .p-menuitem-icon { + color: #b3b3b3; +} +.p-breadcrumb .p-breadcrumb-list li.p-menuitem-separator { + margin: 0 0.5rem 0 0.5rem; + color: #e6e6e6; +} +.p-breadcrumb .p-breadcrumb-list li:last-child .p-menuitem-text { + color: #e6e6e6; +} +.p-breadcrumb .p-breadcrumb-list li:last-child .p-menuitem-icon { + color: #b3b3b3; +} +.p-contextmenu { + padding: 0.5rem 0.5rem; + background: #212121; + color: #e6e6e6; + border: 2px solid #3c3c3c; + box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12); + border-radius: 6px; + width: 12.5rem; +} +.p-contextmenu .p-contextmenu-root-list { + outline: 0 none; +} +.p-contextmenu .p-submenu-list { + padding: 0.5rem 0.5rem; + background: #212121; + border: 2px solid #3c3c3c; + box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12); + border-radius: 6px; +} +.p-contextmenu .p-menuitem > .p-menuitem-content { + color: #e6e6e6; + transition: box-shadow 0.3s; + border-radius: 6px; +} +.p-contextmenu .p-menuitem > .p-menuitem-content .p-menuitem-link { + color: #e6e6e6; + padding: 0.75rem 1rem; + user-select: none; +} +.p-contextmenu .p-menuitem > .p-menuitem-content .p-menuitem-link .p-menuitem-text { + color: #e6e6e6; +} +.p-contextmenu .p-menuitem > .p-menuitem-content .p-menuitem-link .p-menuitem-icon { + color: #b3b3b3; + margin-right: 0.5rem; +} +.p-contextmenu .p-menuitem > .p-menuitem-content .p-menuitem-link .p-submenu-icon { + color: #b3b3b3; +} +.p-contextmenu .p-menuitem.p-highlight > .p-menuitem-content { + color: #e6e6e6; + background: rgba(158, 173, 230, 0.08); +} +.p-contextmenu .p-menuitem.p-highlight > .p-menuitem-content .p-menuitem-link .p-menuitem-text { + color: #e6e6e6; +} +.p-contextmenu .p-menuitem.p-highlight > .p-menuitem-content .p-menuitem-link .p-menuitem-icon, +.p-contextmenu .p-menuitem.p-highlight > .p-menuitem-content .p-menuitem-link .p-submenu-icon { + color: #e6e6e6; +} +.p-contextmenu .p-menuitem.p-highlight.p-focus > .p-menuitem-content { + background: rgba(158, 173, 230, 0.08); +} +.p-contextmenu .p-menuitem:not(.p-highlight):not(.p-disabled).p-focus > .p-menuitem-content { + color: #e6e6e6; + background: rgba(233, 170, 255, 0.1); +} +.p-contextmenu + .p-menuitem:not(.p-highlight):not(.p-disabled).p-focus + > .p-menuitem-content + .p-menuitem-link + .p-menuitem-text { + color: #e6e6e6; +} +.p-contextmenu + .p-menuitem:not(.p-highlight):not(.p-disabled).p-focus + > .p-menuitem-content + .p-menuitem-link + .p-menuitem-icon, +.p-contextmenu + .p-menuitem:not(.p-highlight):not(.p-disabled).p-focus + > .p-menuitem-content + .p-menuitem-link + .p-submenu-icon { + color: #e6e6e6; +} +.p-contextmenu .p-menuitem:not(.p-highlight):not(.p-disabled) > .p-menuitem-content:hover { + color: #e6e6e6; + background: rgba(158, 173, 230, 0.08); +} +.p-contextmenu + .p-menuitem:not(.p-highlight):not(.p-disabled) + > .p-menuitem-content:hover + .p-menuitem-link + .p-menuitem-text { + color: #e6e6e6; +} +.p-contextmenu + .p-menuitem:not(.p-highlight):not(.p-disabled) + > .p-menuitem-content:hover + .p-menuitem-link + .p-menuitem-icon, +.p-contextmenu + .p-menuitem:not(.p-highlight):not(.p-disabled) + > .p-menuitem-content:hover + .p-menuitem-link + .p-submenu-icon { + color: #e6e6e6; +} +.p-contextmenu .p-menuitem-separator { + border-top: 1px solid #3c3c3c; + margin: 4px 0; +} +.p-contextmenu .p-submenu-icon { + font-size: 0.875rem; +} +.p-contextmenu .p-submenu-icon.p-icon { + width: 0.875rem; + height: 0.875rem; +} +.p-dock .p-dock-list-container { + background: rgba(255, 255, 255, 0.1); + border: 1px solid rgba(255, 255, 255, 0.2); + padding: 0.5rem 0.5rem; + border-radius: 0.5rem; +} +.p-dock .p-dock-list-container .p-dock-list { + outline: 0 none; +} +.p-dock .p-dock-item { + padding: 0.5rem; + border-radius: 6px; +} +.p-dock .p-dock-item.p-focus { + outline: 0 none; + outline-offset: 0; + box-shadow: inset 0 0 0 0.15rem #e9aaff; +} +.p-dock .p-dock-link { + width: 4rem; + height: 4rem; +} +.p-dock.p-dock-top .p-dock-item-second-prev, +.p-dock.p-dock-top .p-dock-item-second-next, +.p-dock.p-dock-bottom .p-dock-item-second-prev, +.p-dock.p-dock-bottom .p-dock-item-second-next { + margin: 0 0.9rem; +} +.p-dock.p-dock-top .p-dock-item-prev, +.p-dock.p-dock-top .p-dock-item-next, +.p-dock.p-dock-bottom .p-dock-item-prev, +.p-dock.p-dock-bottom .p-dock-item-next { + margin: 0 1.3rem; +} +.p-dock.p-dock-top .p-dock-item-current, +.p-dock.p-dock-bottom .p-dock-item-current { + margin: 0 1.5rem; +} +.p-dock.p-dock-left .p-dock-item-second-prev, +.p-dock.p-dock-left .p-dock-item-second-next, +.p-dock.p-dock-right .p-dock-item-second-prev, +.p-dock.p-dock-right .p-dock-item-second-next { + margin: 0.9rem 0; +} +.p-dock.p-dock-left .p-dock-item-prev, +.p-dock.p-dock-left .p-dock-item-next, +.p-dock.p-dock-right .p-dock-item-prev, +.p-dock.p-dock-right .p-dock-item-next { + margin: 1.3rem 0; +} +.p-dock.p-dock-left .p-dock-item-current, +.p-dock.p-dock-right .p-dock-item-current { + margin: 1.5rem 0; +} +@media screen and (max-width: 960px) { + .p-dock.p-dock-top .p-dock-list-container, + .p-dock.p-dock-bottom .p-dock-list-container { + overflow-x: auto; + width: 100%; + } + .p-dock.p-dock-top .p-dock-list-container .p-dock-list, + .p-dock.p-dock-bottom .p-dock-list-container .p-dock-list { + margin: 0 auto; + } + .p-dock.p-dock-left .p-dock-list-container, + .p-dock.p-dock-right .p-dock-list-container { + overflow-y: auto; + height: 100%; + } + .p-dock.p-dock-left .p-dock-list-container .p-dock-list, + .p-dock.p-dock-right .p-dock-list-container .p-dock-list { + margin: auto 0; + } + .p-dock .p-dock-list .p-dock-item { + transform: none; + margin: 0; + } +} +.p-megamenu { + padding: 0.5rem; + background: #212121; + color: #e6e6e6; + border: 2px solid #3c3c3c; + border-radius: 6px; +} +.p-megamenu .p-megamenu-root-list { + outline: 0 none; +} +.p-megamenu .p-menuitem > .p-menuitem-content { + color: #e6e6e6; + transition: box-shadow 0.3s; + border-radius: 6px; +} +.p-megamenu .p-menuitem > .p-menuitem-content .p-menuitem-link { + color: #e6e6e6; + padding: 0.75rem 1rem; + user-select: none; +} +.p-megamenu .p-menuitem > .p-menuitem-content .p-menuitem-link .p-menuitem-text { + color: #e6e6e6; +} +.p-megamenu .p-menuitem > .p-menuitem-content .p-menuitem-link .p-menuitem-icon { + color: #b3b3b3; + margin-right: 0.5rem; +} +.p-megamenu .p-menuitem > .p-menuitem-content .p-menuitem-link .p-submenu-icon { + color: #b3b3b3; +} +.p-megamenu .p-menuitem.p-highlight > .p-menuitem-content { + color: #e6e6e6; + background: rgba(158, 173, 230, 0.08); +} +.p-megamenu .p-menuitem.p-highlight > .p-menuitem-content .p-menuitem-link .p-menuitem-text { + color: #e6e6e6; +} +.p-megamenu .p-menuitem.p-highlight > .p-menuitem-content .p-menuitem-link .p-menuitem-icon, +.p-megamenu .p-menuitem.p-highlight > .p-menuitem-content .p-menuitem-link .p-submenu-icon { + color: #e6e6e6; +} +.p-megamenu .p-menuitem.p-highlight.p-focus > .p-menuitem-content { + background: rgba(158, 173, 230, 0.08); +} +.p-megamenu .p-menuitem:not(.p-highlight):not(.p-disabled).p-focus > .p-menuitem-content { + color: #e6e6e6; + background: rgba(233, 170, 255, 0.1); +} +.p-megamenu + .p-menuitem:not(.p-highlight):not(.p-disabled).p-focus + > .p-menuitem-content + .p-menuitem-link + .p-menuitem-text { + color: #e6e6e6; +} +.p-megamenu + .p-menuitem:not(.p-highlight):not(.p-disabled).p-focus + > .p-menuitem-content + .p-menuitem-link + .p-menuitem-icon, +.p-megamenu + .p-menuitem:not(.p-highlight):not(.p-disabled).p-focus + > .p-menuitem-content + .p-menuitem-link + .p-submenu-icon { + color: #e6e6e6; +} +.p-megamenu .p-menuitem:not(.p-highlight):not(.p-disabled) > .p-menuitem-content:hover { + color: #e6e6e6; + background: rgba(158, 173, 230, 0.08); +} +.p-megamenu + .p-menuitem:not(.p-highlight):not(.p-disabled) + > .p-menuitem-content:hover + .p-menuitem-link + .p-menuitem-text { + color: #e6e6e6; +} +.p-megamenu + .p-menuitem:not(.p-highlight):not(.p-disabled) + > .p-menuitem-content:hover + .p-menuitem-link + .p-menuitem-icon, +.p-megamenu + .p-menuitem:not(.p-highlight):not(.p-disabled) + > .p-menuitem-content:hover + .p-menuitem-link + .p-submenu-icon { + color: #e6e6e6; +} +.p-megamenu .p-megamenu-panel { + background: #212121; + color: #e6e6e6; + border: 2px solid #3c3c3c; + box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12); +} +.p-megamenu .p-submenu-header { + margin: 0; + padding: 0.75rem 1rem; + color: #e6e6e6; + background: #212121; + font-weight: 600; + border-top-right-radius: 6px; + border-top-left-radius: 6px; +} +.p-megamenu .p-submenu-list { + padding: 0.5rem 0.5rem; + width: 12.5rem; +} +.p-megamenu .p-submenu-list .p-menuitem-separator { + border-top: 1px solid #3c3c3c; + margin: 4px 0; +} +.p-megamenu.p-megamenu-vertical { + width: 12.5rem; + padding: 0.5rem 0.5rem; +} +.p-megamenu.p-megamenu-horizontal .p-megamenu-root-list > .p-menuitem > .p-menuitem-content { + color: #e6e6e6; + transition: box-shadow 0.3s; + border-radius: 6px; +} +.p-megamenu.p-megamenu-horizontal .p-megamenu-root-list > .p-menuitem > .p-menuitem-content .p-menuitem-link { + padding: 0.75rem 1rem; + user-select: none; +} +.p-megamenu.p-megamenu-horizontal + .p-megamenu-root-list + > .p-menuitem + > .p-menuitem-content + .p-menuitem-link + .p-menuitem-text { + color: #e6e6e6; +} +.p-megamenu.p-megamenu-horizontal + .p-megamenu-root-list + > .p-menuitem + > .p-menuitem-content + .p-menuitem-link + .p-menuitem-icon { + color: #b3b3b3; + margin-right: 0.5rem; +} +.p-megamenu.p-megamenu-horizontal + .p-megamenu-root-list + > .p-menuitem + > .p-menuitem-content + .p-menuitem-link + .p-submenu-icon { + color: #b3b3b3; + margin-left: 0.5rem; +} +.p-megamenu.p-megamenu-horizontal + .p-megamenu-root-list + > .p-menuitem:not(.p-highlight):not(.p-disabled) + > .p-menuitem-content:hover { + color: #e6e6e6; + background: rgba(158, 173, 230, 0.08); +} +.p-megamenu.p-megamenu-horizontal + .p-megamenu-root-list + > .p-menuitem:not(.p-highlight):not(.p-disabled) + > .p-menuitem-content:hover + .p-menuitem-link + .p-menuitem-text { + color: #e6e6e6; +} +.p-megamenu.p-megamenu-horizontal + .p-megamenu-root-list + > .p-menuitem:not(.p-highlight):not(.p-disabled) + > .p-menuitem-content:hover + .p-menuitem-link + .p-menuitem-icon, +.p-megamenu.p-megamenu-horizontal + .p-megamenu-root-list + > .p-menuitem:not(.p-highlight):not(.p-disabled) + > .p-menuitem-content:hover + .p-menuitem-link + .p-submenu-icon { + color: #e6e6e6; +} +.p-menu { + padding: 0.5rem 0.5rem; + background: #212121; + color: #e6e6e6; + border: 2px solid #3c3c3c; + border-radius: 6px; + width: 12.5rem; +} +.p-menu .p-menuitem > .p-menuitem-content { + color: #e6e6e6; + transition: box-shadow 0.3s; + border-radius: 6px; +} +.p-menu .p-menuitem > .p-menuitem-content .p-menuitem-link { + color: #e6e6e6; + padding: 0.75rem 1rem; + user-select: none; +} +.p-menu .p-menuitem > .p-menuitem-content .p-menuitem-link .p-menuitem-text { + color: #e6e6e6; +} +.p-menu .p-menuitem > .p-menuitem-content .p-menuitem-link .p-menuitem-icon { + color: #b3b3b3; + margin-right: 0.5rem; +} +.p-menu .p-menuitem > .p-menuitem-content .p-menuitem-link .p-submenu-icon { + color: #b3b3b3; +} +.p-menu .p-menuitem.p-highlight > .p-menuitem-content { + color: #e6e6e6; + background: rgba(158, 173, 230, 0.08); +} +.p-menu .p-menuitem.p-highlight > .p-menuitem-content .p-menuitem-link .p-menuitem-text { + color: #e6e6e6; +} +.p-menu .p-menuitem.p-highlight > .p-menuitem-content .p-menuitem-link .p-menuitem-icon, +.p-menu .p-menuitem.p-highlight > .p-menuitem-content .p-menuitem-link .p-submenu-icon { + color: #e6e6e6; +} +.p-menu .p-menuitem.p-highlight.p-focus > .p-menuitem-content { + background: rgba(158, 173, 230, 0.08); +} +.p-menu .p-menuitem:not(.p-highlight):not(.p-disabled).p-focus > .p-menuitem-content { + color: #e6e6e6; + background: rgba(233, 170, 255, 0.1); +} +.p-menu .p-menuitem:not(.p-highlight):not(.p-disabled).p-focus > .p-menuitem-content .p-menuitem-link .p-menuitem-text { + color: #e6e6e6; +} +.p-menu .p-menuitem:not(.p-highlight):not(.p-disabled).p-focus > .p-menuitem-content .p-menuitem-link .p-menuitem-icon, +.p-menu .p-menuitem:not(.p-highlight):not(.p-disabled).p-focus > .p-menuitem-content .p-menuitem-link .p-submenu-icon { + color: #e6e6e6; +} +.p-menu .p-menuitem:not(.p-highlight):not(.p-disabled) > .p-menuitem-content:hover { + color: #e6e6e6; + background: rgba(158, 173, 230, 0.08); +} +.p-menu .p-menuitem:not(.p-highlight):not(.p-disabled) > .p-menuitem-content:hover .p-menuitem-link .p-menuitem-text { + color: #e6e6e6; +} +.p-menu .p-menuitem:not(.p-highlight):not(.p-disabled) > .p-menuitem-content:hover .p-menuitem-link .p-menuitem-icon, +.p-menu .p-menuitem:not(.p-highlight):not(.p-disabled) > .p-menuitem-content:hover .p-menuitem-link .p-submenu-icon { + color: #e6e6e6; +} +.p-menu.p-menu-overlay { + background: #212121; + border: 2px solid #3c3c3c; + box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12); +} +.p-menu .p-submenu-header { + margin: 0; + padding: 0.75rem 1rem; + color: #e6e6e6; + background: #212121; + font-weight: 600; + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.p-menu .p-menuitem-separator { + border-top: 1px solid #3c3c3c; + margin: 4px 0; +} +.p-menubar { + padding: 0.5rem; + background: #212121; + color: #e6e6e6; + border: 2px solid #3c3c3c; + border-radius: 6px; +} +.p-menubar .p-menubar-root-list { + outline: 0 none; +} +.p-menubar .p-menubar-root-list > .p-menuitem > .p-menuitem-content { + color: #e6e6e6; + transition: box-shadow 0.3s; + border-radius: 6px; +} +.p-menubar .p-menubar-root-list > .p-menuitem > .p-menuitem-content .p-menuitem-link { + padding: 0.75rem 1rem; + user-select: none; +} +.p-menubar .p-menubar-root-list > .p-menuitem > .p-menuitem-content .p-menuitem-link .p-menuitem-text { + color: #e6e6e6; +} +.p-menubar .p-menubar-root-list > .p-menuitem > .p-menuitem-content .p-menuitem-link .p-menuitem-icon { + color: #b3b3b3; + margin-right: 0.5rem; +} +.p-menubar .p-menubar-root-list > .p-menuitem > .p-menuitem-content .p-menuitem-link .p-submenu-icon { + color: #b3b3b3; + margin-left: 0.5rem; +} +.p-menubar .p-menubar-root-list > .p-menuitem:not(.p-highlight):not(.p-disabled) > .p-menuitem-content:hover { + color: #e6e6e6; + background: rgba(158, 173, 230, 0.08); +} +.p-menubar + .p-menubar-root-list + > .p-menuitem:not(.p-highlight):not(.p-disabled) + > .p-menuitem-content:hover + .p-menuitem-link + .p-menuitem-text { + color: #e6e6e6; +} +.p-menubar + .p-menubar-root-list + > .p-menuitem:not(.p-highlight):not(.p-disabled) + > .p-menuitem-content:hover + .p-menuitem-link + .p-menuitem-icon, +.p-menubar + .p-menubar-root-list + > .p-menuitem:not(.p-highlight):not(.p-disabled) + > .p-menuitem-content:hover + .p-menuitem-link + .p-submenu-icon { + color: #e6e6e6; +} +.p-menubar .p-menuitem > .p-menuitem-content { + color: #e6e6e6; + transition: box-shadow 0.3s; + border-radius: 6px; +} +.p-menubar .p-menuitem > .p-menuitem-content .p-menuitem-link { + color: #e6e6e6; + padding: 0.75rem 1rem; + user-select: none; +} +.p-menubar .p-menuitem > .p-menuitem-content .p-menuitem-link .p-menuitem-text { + color: #e6e6e6; +} +.p-menubar .p-menuitem > .p-menuitem-content .p-menuitem-link .p-menuitem-icon { + color: #b3b3b3; + margin-right: 0.5rem; +} +.p-menubar .p-menuitem > .p-menuitem-content .p-menuitem-link .p-submenu-icon { + color: #b3b3b3; +} +.p-menubar .p-menuitem.p-highlight > .p-menuitem-content { + color: #e6e6e6; + background: rgba(158, 173, 230, 0.08); +} +.p-menubar .p-menuitem.p-highlight > .p-menuitem-content .p-menuitem-link .p-menuitem-text { + color: #e6e6e6; +} +.p-menubar .p-menuitem.p-highlight > .p-menuitem-content .p-menuitem-link .p-menuitem-icon, +.p-menubar .p-menuitem.p-highlight > .p-menuitem-content .p-menuitem-link .p-submenu-icon { + color: #e6e6e6; +} +.p-menubar .p-menuitem.p-highlight.p-focus > .p-menuitem-content { + background: rgba(158, 173, 230, 0.08); +} +.p-menubar .p-menuitem:not(.p-highlight):not(.p-disabled).p-focus > .p-menuitem-content { + color: #e6e6e6; + background: rgba(233, 170, 255, 0.1); +} +.p-menubar + .p-menuitem:not(.p-highlight):not(.p-disabled).p-focus + > .p-menuitem-content + .p-menuitem-link + .p-menuitem-text { + color: #e6e6e6; +} +.p-menubar + .p-menuitem:not(.p-highlight):not(.p-disabled).p-focus + > .p-menuitem-content + .p-menuitem-link + .p-menuitem-icon, +.p-menubar + .p-menuitem:not(.p-highlight):not(.p-disabled).p-focus + > .p-menuitem-content + .p-menuitem-link + .p-submenu-icon { + color: #e6e6e6; +} +.p-menubar .p-menuitem:not(.p-highlight):not(.p-disabled) > .p-menuitem-content:hover { + color: #e6e6e6; + background: rgba(158, 173, 230, 0.08); +} +.p-menubar + .p-menuitem:not(.p-highlight):not(.p-disabled) + > .p-menuitem-content:hover + .p-menuitem-link + .p-menuitem-text { + color: #e6e6e6; +} +.p-menubar .p-menuitem:not(.p-highlight):not(.p-disabled) > .p-menuitem-content:hover .p-menuitem-link .p-menuitem-icon, +.p-menubar .p-menuitem:not(.p-highlight):not(.p-disabled) > .p-menuitem-content:hover .p-menuitem-link .p-submenu-icon { + color: #e6e6e6; +} +.p-menubar .p-submenu-list { + padding: 0.5rem 0.5rem; + background: #212121; + border: 2px solid #3c3c3c; + box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12); + width: 12.5rem; +} +.p-menubar .p-submenu-list .p-menuitem-separator { + border-top: 1px solid #3c3c3c; + margin: 4px 0; +} +.p-menubar .p-submenu-list .p-submenu-icon { + font-size: 0.875rem; +} +@media screen and (max-width: 960px) { + .p-menubar { + position: relative; + } + .p-menubar .p-menubar-button { + display: flex; + width: 2rem; + height: 2rem; + color: #b3b3b3; + border-radius: 50%; + transition: background-color 0.3s, color 0.3s, box-shadow 0.3s; + } + .p-menubar .p-menubar-button:hover { + color: #e6e6e6; + background: rgba(158, 173, 230, 0.08); + } + .p-menubar .p-menubar-button:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; + } + .p-menubar .p-menubar-root-list { + position: absolute; + display: none; + padding: 0.5rem 0.5rem; + background: #212121; + border: 2px solid #3c3c3c; + box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12); + width: 100%; + } + .p-menubar .p-menubar-root-list .p-menuitem-separator { + border-top: 1px solid #3c3c3c; + margin: 4px 0; + } + .p-menubar .p-menubar-root-list .p-submenu-icon { + font-size: 0.875rem; + } + .p-menubar .p-menubar-root-list .p-menuitem { + width: 100%; + position: static; + } + .p-menubar .p-menubar-root-list .p-menuitem .p-menuitem-content .p-menuitem-link .p-submenu-icon { + margin-left: auto; + transition: transform 0.3s; + } + .p-menubar + .p-menubar-root-list + .p-menuitem.p-menuitem-active + > .p-menuitem-content + > .p-menuitem-link + > .p-submenu-icon { + transform: rotate(-180deg); + } + .p-menubar .p-menubar-root-list .p-submenu-list { + width: 100%; + position: static; + box-shadow: none; + border: 0 none; + } + .p-menubar .p-menubar-root-list .p-submenu-list .p-submenu-icon { + transition: transform 0.3s; + transform: rotate(90deg); + } + .p-menubar + .p-menubar-root-list + .p-submenu-list + .p-menuitem-active + > .p-menuitem-content + > .p-menuitem-link + > .p-submenu-icon { + transform: rotate(-90deg); + } + .p-menubar .p-menubar-root-list .p-menuitem { + width: 100%; + position: static; + } + .p-menubar .p-menubar-root-list .p-submenu-list .p-menuitem .p-menuitem-content .p-menuitem-link { + padding-left: 2.25rem; + } + .p-menubar + .p-menubar-root-list + .p-submenu-list + .p-menuitem + .p-submenu-list + .p-menuitem + .p-menuitem-content + .p-menuitem-link { + padding-left: 3.75rem; + } + .p-menubar + .p-menubar-root-list + .p-submenu-list + .p-menuitem + .p-submenu-list + .p-menuitem + .p-submenu-list + .p-menuitem + .p-menuitem-content + .p-menuitem-link { + padding-left: 5.25rem; + } + .p-menubar + .p-menubar-root-list + .p-submenu-list + .p-menuitem + .p-submenu-list + .p-menuitem + .p-submenu-list + .p-menuitem + .p-submenu-list + .p-menuitem + .p-menuitem-content + .p-menuitem-link { + padding-left: 6.75rem; + } + .p-menubar + .p-menubar-root-list + .p-submenu-list + .p-menuitem + .p-submenu-list + .p-menuitem + .p-submenu-list + .p-menuitem + .p-submenu-list + .p-menuitem + .p-submenu-list + .p-menuitem + .p-menuitem-content + .p-menuitem-link { + padding-left: 8.25rem; + } + .p-menubar.p-menubar-mobile-active .p-menubar-root-list { + display: flex; + flex-direction: column; + top: 100%; + left: 0; + z-index: 1; + } +} +.p-panelmenu .p-panelmenu-header { + outline: 0 none; +} +.p-panelmenu .p-panelmenu-header .p-panelmenu-header-content { + border: 2px solid #3c3c3c; + color: #e6e6e6; + background: #212121; + border-radius: 6px; + transition: box-shadow 0.3s; +} +.p-panelmenu .p-panelmenu-header .p-panelmenu-header-content .p-panelmenu-header-action { + color: #e6e6e6; + padding: 1rem; + font-weight: 600; +} +.p-panelmenu .p-panelmenu-header .p-panelmenu-header-content .p-panelmenu-header-action .p-submenu-icon { + margin-right: 0.5rem; +} +.p-panelmenu .p-panelmenu-header .p-panelmenu-header-content .p-panelmenu-header-action .p-menuitem-icon { + margin-right: 0.5rem; +} +.p-panelmenu .p-panelmenu-header:not(.p-disabled):focus .p-panelmenu-header-content { + outline: 0 none; + outline-offset: 0; + box-shadow: inset 0 0 0 1px #e9aaff; +} +.p-panelmenu .p-panelmenu-header:not(.p-highlight):not(.p-disabled):hover .p-panelmenu-header-content { + background: rgba(158, 173, 230, 0.08); + border-color: #3c3c3c; + color: #e6e6e6; +} +.p-panelmenu .p-panelmenu-header:not(.p-disabled).p-highlight .p-panelmenu-header-content { + background: #212121; + border-color: #3c3c3c; + color: #e6e6e6; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + margin-bottom: 0; +} +.p-panelmenu .p-panelmenu-header:not(.p-disabled).p-highlight:hover .p-panelmenu-header-content { + border-color: #3c3c3c; + background: rgba(158, 173, 230, 0.08); + color: #e6e6e6; +} +.p-panelmenu .p-panelmenu-content { + padding: 0.5rem 0.5rem; + border: 2px solid #3c3c3c; + background: #212121; + color: #e6e6e6; + border-top: 0; + border-top-right-radius: 0; + border-top-left-radius: 0; + border-bottom-right-radius: 6px; + border-bottom-left-radius: 6px; +} +.p-panelmenu .p-panelmenu-content .p-panelmenu-root-list { + outline: 0 none; +} +.p-panelmenu .p-panelmenu-content .p-menuitem > .p-menuitem-content { + color: #e6e6e6; + transition: box-shadow 0.3s; + border-radius: 6px; +} +.p-panelmenu .p-panelmenu-content .p-menuitem > .p-menuitem-content .p-menuitem-link { + color: #e6e6e6; + padding: 0.75rem 1rem; + user-select: none; +} +.p-panelmenu .p-panelmenu-content .p-menuitem > .p-menuitem-content .p-menuitem-link .p-menuitem-text { + color: #e6e6e6; +} +.p-panelmenu .p-panelmenu-content .p-menuitem > .p-menuitem-content .p-menuitem-link .p-menuitem-icon { + color: #b3b3b3; + margin-right: 0.5rem; +} +.p-panelmenu .p-panelmenu-content .p-menuitem > .p-menuitem-content .p-menuitem-link .p-submenu-icon { + color: #b3b3b3; +} +.p-panelmenu .p-panelmenu-content .p-menuitem.p-highlight > .p-menuitem-content { + color: #e6e6e6; + background: rgba(158, 173, 230, 0.08); +} +.p-panelmenu .p-panelmenu-content .p-menuitem.p-highlight > .p-menuitem-content .p-menuitem-link .p-menuitem-text { + color: #e6e6e6; +} +.p-panelmenu .p-panelmenu-content .p-menuitem.p-highlight > .p-menuitem-content .p-menuitem-link .p-menuitem-icon, +.p-panelmenu .p-panelmenu-content .p-menuitem.p-highlight > .p-menuitem-content .p-menuitem-link .p-submenu-icon { + color: #e6e6e6; +} +.p-panelmenu .p-panelmenu-content .p-menuitem.p-highlight.p-focus > .p-menuitem-content { + background: rgba(158, 173, 230, 0.08); +} +.p-panelmenu .p-panelmenu-content .p-menuitem:not(.p-highlight):not(.p-disabled).p-focus > .p-menuitem-content { + color: #e6e6e6; + background: rgba(233, 170, 255, 0.1); +} +.p-panelmenu + .p-panelmenu-content + .p-menuitem:not(.p-highlight):not(.p-disabled).p-focus + > .p-menuitem-content + .p-menuitem-link + .p-menuitem-text { + color: #e6e6e6; +} +.p-panelmenu + .p-panelmenu-content + .p-menuitem:not(.p-highlight):not(.p-disabled).p-focus + > .p-menuitem-content + .p-menuitem-link + .p-menuitem-icon, +.p-panelmenu + .p-panelmenu-content + .p-menuitem:not(.p-highlight):not(.p-disabled).p-focus + > .p-menuitem-content + .p-menuitem-link + .p-submenu-icon { + color: #e6e6e6; +} +.p-panelmenu .p-panelmenu-content .p-menuitem:not(.p-highlight):not(.p-disabled) > .p-menuitem-content:hover { + color: #e6e6e6; + background: rgba(158, 173, 230, 0.08); +} +.p-panelmenu + .p-panelmenu-content + .p-menuitem:not(.p-highlight):not(.p-disabled) + > .p-menuitem-content:hover + .p-menuitem-link + .p-menuitem-text { + color: #e6e6e6; +} +.p-panelmenu + .p-panelmenu-content + .p-menuitem:not(.p-highlight):not(.p-disabled) + > .p-menuitem-content:hover + .p-menuitem-link + .p-menuitem-icon, +.p-panelmenu + .p-panelmenu-content + .p-menuitem:not(.p-highlight):not(.p-disabled) + > .p-menuitem-content:hover + .p-menuitem-link + .p-submenu-icon { + color: #e6e6e6; +} +.p-panelmenu .p-panelmenu-content .p-menuitem .p-menuitem-content .p-menuitem-link .p-submenu-icon { + margin-right: 0.5rem; +} +.p-panelmenu .p-panelmenu-content .p-menuitem-separator { + border-top: 1px solid #3c3c3c; + margin: 4px 0; +} +.p-panelmenu .p-panelmenu-content .p-submenu-list:not(.p-panelmenu-root-list) { + padding: 0 0 0 1rem; +} +.p-panelmenu .p-panelmenu-panel { + margin-bottom: 0; +} +.p-panelmenu .p-panelmenu-panel .p-panelmenu-header .p-panelmenu-header-content { + border-radius: 0; +} +.p-panelmenu .p-panelmenu-panel .p-panelmenu-content { + border-radius: 0; +} +.p-panelmenu .p-panelmenu-panel:not(:first-child) .p-panelmenu-header .p-panelmenu-header-content { + border-top: 0 none; +} +.p-panelmenu + .p-panelmenu-panel:not(:first-child) + .p-panelmenu-header:not(.p-highlight):not(.p-disabled):hover + .p-panelmenu-header-content, +.p-panelmenu + .p-panelmenu-panel:not(:first-child) + .p-panelmenu-header:not(.p-disabled).p-highlight:hover + .p-panelmenu-header-content { + border-top: 0 none; +} +.p-panelmenu .p-panelmenu-panel:first-child .p-panelmenu-header .p-panelmenu-header-content { + border-top-right-radius: 6px; + border-top-left-radius: 6px; +} +.p-panelmenu .p-panelmenu-panel:last-child .p-panelmenu-header:not(.p-highlight) .p-panelmenu-header-content { + border-bottom-right-radius: 6px; + border-bottom-left-radius: 6px; +} +.p-panelmenu .p-panelmenu-panel:last-child .p-panelmenu-content { + border-bottom-right-radius: 6px; + border-bottom-left-radius: 6px; +} +.p-steps .p-steps-item .p-menuitem-link { + background: transparent; + transition: box-shadow 0.3s; + border-radius: 6px; + background: transparent; +} +.p-steps .p-steps-item .p-menuitem-link .p-steps-number { + color: #e6e6e6; + border: 2px solid #3c3c3c; + background: transparent; + min-width: 2rem; + height: 2rem; + line-height: 2rem; + font-size: 1.143rem; + z-index: 1; + border-radius: 50%; +} +.p-steps .p-steps-item .p-menuitem-link .p-steps-title { + margin-top: 0.5rem; + color: #b3b3b3; +} +.p-steps .p-steps-item .p-menuitem-link:not(.p-disabled):focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-steps .p-steps-item.p-highlight .p-steps-number { + background: rgba(158, 173, 230, 0.16); + color: #9eade6; +} +.p-steps .p-steps-item.p-highlight .p-steps-title { + font-weight: 600; + color: #e6e6e6; +} +.p-steps .p-steps-item:before { + content: " "; + border-top: 1px solid #3c3c3c; + width: 100%; + top: 50%; + left: 0; + display: block; + position: absolute; + margin-top: -1rem; +} +.p-tabmenu .p-tabmenu-nav { + background: transparent; + border: 1px solid #3c3c3c; + border-width: 0 0 2px 0; +} +.p-tabmenu .p-tabmenu-nav .p-tabmenuitem { + margin-right: 0; +} +.p-tabmenu .p-tabmenu-nav .p-tabmenuitem .p-menuitem-link { + border: solid #3c3c3c; + border-width: 0 0 2px 0; + border-color: transparent transparent #3c3c3c transparent; + background: #212121; + color: #b3b3b3; + padding: 1rem; + font-weight: 600; + border-top-right-radius: 6px; + border-top-left-radius: 6px; + transition: box-shadow 0.3s; + margin: 0 0 -2px 0; +} +.p-tabmenu .p-tabmenu-nav .p-tabmenuitem .p-menuitem-link .p-menuitem-icon { + margin-right: 0.5rem; +} +.p-tabmenu .p-tabmenu-nav .p-tabmenuitem .p-menuitem-link:not(.p-disabled):focus { + outline: 0 none; + outline-offset: 0; + box-shadow: inset 0 0 0 1px #e9aaff; +} +.p-tabmenu .p-tabmenu-nav .p-tabmenuitem:not(.p-highlight):not(.p-disabled):hover .p-menuitem-link { + background: #212121; + border-color: #e9aaff; + color: #e6e6e6; +} +.p-tabmenu .p-tabmenu-nav .p-tabmenuitem.p-highlight .p-menuitem-link { + background: #212121; + border-color: #e9aaff; + color: #e9aaff; +} +.p-tieredmenu { + padding: 0.5rem 0.5rem; + background: #212121; + color: #e6e6e6; + border: 2px solid #3c3c3c; + border-radius: 6px; + width: 12.5rem; +} +.p-tieredmenu.p-tieredmenu-overlay { + background: #212121; + border: 2px solid #3c3c3c; + box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12); +} +.p-tieredmenu .p-tieredmenu-root-list { + outline: 0 none; +} +.p-tieredmenu .p-submenu-list { + padding: 0.5rem 0.5rem; + background: #212121; + border: 2px solid #3c3c3c; + box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12); +} +.p-tieredmenu .p-menuitem > .p-menuitem-content { + color: #e6e6e6; + transition: box-shadow 0.3s; + border-radius: 6px; +} +.p-tieredmenu .p-menuitem > .p-menuitem-content .p-menuitem-link { + color: #e6e6e6; + padding: 0.75rem 1rem; + user-select: none; +} +.p-tieredmenu .p-menuitem > .p-menuitem-content .p-menuitem-link .p-menuitem-text { + color: #e6e6e6; +} +.p-tieredmenu .p-menuitem > .p-menuitem-content .p-menuitem-link .p-menuitem-icon { + color: #b3b3b3; + margin-right: 0.5rem; +} +.p-tieredmenu .p-menuitem > .p-menuitem-content .p-menuitem-link .p-submenu-icon { + color: #b3b3b3; +} +.p-tieredmenu .p-menuitem.p-highlight > .p-menuitem-content { + color: #e6e6e6; + background: rgba(158, 173, 230, 0.08); +} +.p-tieredmenu .p-menuitem.p-highlight > .p-menuitem-content .p-menuitem-link .p-menuitem-text { + color: #e6e6e6; +} +.p-tieredmenu .p-menuitem.p-highlight > .p-menuitem-content .p-menuitem-link .p-menuitem-icon, +.p-tieredmenu .p-menuitem.p-highlight > .p-menuitem-content .p-menuitem-link .p-submenu-icon { + color: #e6e6e6; +} +.p-tieredmenu .p-menuitem.p-highlight.p-focus > .p-menuitem-content { + background: rgba(158, 173, 230, 0.08); +} +.p-tieredmenu .p-menuitem:not(.p-highlight):not(.p-disabled).p-focus > .p-menuitem-content { + color: #e6e6e6; + background: rgba(233, 170, 255, 0.1); +} +.p-tieredmenu + .p-menuitem:not(.p-highlight):not(.p-disabled).p-focus + > .p-menuitem-content + .p-menuitem-link + .p-menuitem-text { + color: #e6e6e6; +} +.p-tieredmenu + .p-menuitem:not(.p-highlight):not(.p-disabled).p-focus + > .p-menuitem-content + .p-menuitem-link + .p-menuitem-icon, +.p-tieredmenu + .p-menuitem:not(.p-highlight):not(.p-disabled).p-focus + > .p-menuitem-content + .p-menuitem-link + .p-submenu-icon { + color: #e6e6e6; +} +.p-tieredmenu .p-menuitem:not(.p-highlight):not(.p-disabled) > .p-menuitem-content:hover { + color: #e6e6e6; + background: rgba(158, 173, 230, 0.08); +} +.p-tieredmenu + .p-menuitem:not(.p-highlight):not(.p-disabled) + > .p-menuitem-content:hover + .p-menuitem-link + .p-menuitem-text { + color: #e6e6e6; +} +.p-tieredmenu + .p-menuitem:not(.p-highlight):not(.p-disabled) + > .p-menuitem-content:hover + .p-menuitem-link + .p-menuitem-icon, +.p-tieredmenu + .p-menuitem:not(.p-highlight):not(.p-disabled) + > .p-menuitem-content:hover + .p-menuitem-link + .p-submenu-icon { + color: #e6e6e6; +} +.p-tieredmenu .p-menuitem-separator { + border-top: 1px solid #3c3c3c; + margin: 4px 0; +} +.p-tieredmenu .p-submenu-icon { + font-size: 0.875rem; +} +.p-tieredmenu .p-submenu-icon.p-icon { + width: 0.875rem; + height: 0.875rem; +} +.p-inline-message { + padding: 0.5rem 0.75rem; + margin: 0; + border-radius: 6px; +} +.p-inline-message.p-inline-message-info { + background: #a3d7e6; + border: 4px solid #65bcd6; + border-width: 2px; + color: #121212; +} +.p-inline-message.p-inline-message-info .p-inline-message-icon { + color: #121212; +} +.p-inline-message.p-inline-message-success { + background: #bfd47f; + border: 4px solid #a2c044; + border-width: 2px; + color: #121212; +} +.p-inline-message.p-inline-message-success .p-inline-message-icon { + color: #121212; +} +.p-inline-message.p-inline-message-warn { + background: #ff9c3e; + border: 4px solid #ff8817; + border-width: 2px; + color: #121212; +} +.p-inline-message.p-inline-message-warn .p-inline-message-icon { + color: #121212; +} +.p-inline-message.p-inline-message-error { + background: #e6a3b2; + border: 4px solid #de8499; + border-width: 2px; + color: #121212; +} +.p-inline-message.p-inline-message-error .p-inline-message-icon { + color: #121212; +} +.p-inline-message .p-inline-message-icon { + font-size: 1rem; + margin-right: 0.5rem; +} +.p-inline-message .p-inline-message-text { + font-size: 1rem; +} +.p-inline-message.p-inline-message-icon-only .p-inline-message-icon { + margin-right: 0; +} +.p-message { + margin: 1rem 0; + border-radius: 6px; +} +.p-message .p-message-wrapper { + padding: 1rem 1.5rem; +} +.p-message .p-message-close { + width: 2rem; + height: 2rem; + border-radius: 50%; + background: transparent; + transition: background-color 0.3s, color 0.3s, box-shadow 0.3s; +} +.p-message .p-message-close:hover { + background: rgba(255, 255, 255, 0.3); +} +.p-message .p-message-close:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-message.p-message-info { + background: #a3d7e6; + border: 4px solid #65bcd6; + border-width: 0 0 0 6px; + color: #121212; +} +.p-message.p-message-info .p-message-icon { + color: #121212; +} +.p-message.p-message-info .p-message-close { + color: #121212; +} +.p-message.p-message-success { + background: #bfd47f; + border: 4px solid #a2c044; + border-width: 0 0 0 6px; + color: #121212; +} +.p-message.p-message-success .p-message-icon { + color: #121212; +} +.p-message.p-message-success .p-message-close { + color: #121212; +} +.p-message.p-message-warn { + background: #ff9c3e; + border: 4px solid #ff8817; + border-width: 0 0 0 6px; + color: #121212; +} +.p-message.p-message-warn .p-message-icon { + color: #121212; +} +.p-message.p-message-warn .p-message-close { + color: #121212; +} +.p-message.p-message-error { + background: #e6a3b2; + border: 4px solid #de8499; + border-width: 0 0 0 6px; + color: #121212; +} +.p-message.p-message-error .p-message-icon { + color: #121212; +} +.p-message.p-message-error .p-message-close { + color: #121212; +} +.p-message .p-message-text { + font-size: 1rem; + font-weight: 400; +} +.p-message .p-message-icon { + font-size: 1.5rem; + margin-right: 0.5rem; +} +.p-message .p-icon:not(.p-message-close-icon) { + width: 1.5rem; + height: 1.5rem; +} +.p-toast { + opacity: 0.9; +} +.p-toast .p-toast-message { + margin: 0 0 1rem 0; + box-shadow: none; + border-radius: 6px; +} +.p-toast .p-toast-message .p-toast-message-content { + padding: 1rem; + border-width: 0 0 0 6px; +} +.p-toast .p-toast-message .p-toast-message-content .p-toast-message-text { + margin: 0 0 0 1rem; +} +.p-toast .p-toast-message .p-toast-message-content .p-toast-message-icon { + font-size: 2rem; +} +.p-toast .p-toast-message .p-toast-message-content .p-toast-message-icon.p-icon { + width: 2rem; + height: 2rem; +} +.p-toast .p-toast-message .p-toast-message-content .p-toast-summary { + font-weight: 600; +} +.p-toast .p-toast-message .p-toast-message-content .p-toast-detail { + margin: 0.5rem 0 0 0; +} +.p-toast .p-toast-message .p-toast-icon-close { + width: 2rem; + height: 2rem; + border-radius: 50%; + background: transparent; + transition: background-color 0.3s, color 0.3s, box-shadow 0.3s; +} +.p-toast .p-toast-message .p-toast-icon-close:hover { + background: rgba(255, 255, 255, 0.3); +} +.p-toast .p-toast-message .p-toast-icon-close:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-toast .p-toast-message.p-toast-message-info { + background: #a3d7e6; + border: 4px solid #65bcd6; + border-width: 0 0 0 6px; + color: #121212; +} +.p-toast .p-toast-message.p-toast-message-info .p-toast-message-icon, +.p-toast .p-toast-message.p-toast-message-info .p-toast-icon-close { + color: #121212; +} +.p-toast .p-toast-message.p-toast-message-success { + background: #bfd47f; + border: 4px solid #a2c044; + border-width: 0 0 0 6px; + color: #121212; +} +.p-toast .p-toast-message.p-toast-message-success .p-toast-message-icon, +.p-toast .p-toast-message.p-toast-message-success .p-toast-icon-close { + color: #121212; +} +.p-toast .p-toast-message.p-toast-message-warn { + background: #ff9c3e; + border: 4px solid #ff8817; + border-width: 0 0 0 6px; + color: #121212; +} +.p-toast .p-toast-message.p-toast-message-warn .p-toast-message-icon, +.p-toast .p-toast-message.p-toast-message-warn .p-toast-icon-close { + color: #121212; +} +.p-toast .p-toast-message.p-toast-message-error { + background: #e6a3b2; + border: 4px solid #de8499; + border-width: 0 0 0 6px; + color: #121212; +} +.p-toast .p-toast-message.p-toast-message-error .p-toast-message-icon, +.p-toast .p-toast-message.p-toast-message-error .p-toast-icon-close { + color: #121212; +} +.p-galleria .p-galleria-close { + margin: 0.5rem; + background: transparent; + color: #f8f9fa; + width: 4rem; + height: 4rem; + transition: background-color 0.3s, color 0.3s, box-shadow 0.3s; + border-radius: 50%; +} +.p-galleria .p-galleria-close .p-galleria-close-icon { + font-size: 2rem; +} +.p-galleria .p-galleria-close .p-icon { + width: 2rem; + height: 2rem; +} +.p-galleria .p-galleria-close:hover { + background: rgba(255, 255, 255, 0.1); + color: #f8f9fa; +} +.p-galleria .p-galleria-item-nav { + background: transparent; + color: #f8f9fa; + width: 4rem; + height: 4rem; + transition: background-color 0.3s, color 0.3s, box-shadow 0.3s; + border-radius: 6px; + margin: 0 0.5rem; +} +.p-galleria .p-galleria-item-nav .p-galleria-item-prev-icon, +.p-galleria .p-galleria-item-nav .p-galleria-item-next-icon { + font-size: 2rem; +} +.p-galleria .p-galleria-item-nav .p-icon { + width: 2rem; + height: 2rem; +} +.p-galleria .p-galleria-item-nav:not(.p-disabled):hover { + background: rgba(255, 255, 255, 0.1); + color: #f8f9fa; +} +.p-galleria .p-galleria-caption { + background: rgba(0, 0, 0, 0.5); + color: #f8f9fa; + padding: 1rem; +} +.p-galleria .p-galleria-indicators { + padding: 1rem; +} +.p-galleria .p-galleria-indicators .p-galleria-indicator button { + background-color: #3c3c3c; + width: 1rem; + height: 1rem; + transition: background-color 0.3s, color 0.3s, box-shadow 0.3s; + border-radius: 50%; +} +.p-galleria .p-galleria-indicators .p-galleria-indicator button:hover { + background: #505050; +} +.p-galleria .p-galleria-indicators .p-galleria-indicator.p-highlight button { + background: rgba(158, 173, 230, 0.16); + color: #9eade6; +} +.p-galleria.p-galleria-indicators-bottom .p-galleria-indicator, +.p-galleria.p-galleria-indicators-top .p-galleria-indicator { + margin-right: 0.5rem; +} +.p-galleria.p-galleria-indicators-left .p-galleria-indicator, +.p-galleria.p-galleria-indicators-right .p-galleria-indicator { + margin-bottom: 0.5rem; +} +.p-galleria.p-galleria-indicator-onitem .p-galleria-indicators { + background: rgba(0, 0, 0, 0.5); +} +.p-galleria.p-galleria-indicator-onitem .p-galleria-indicators .p-galleria-indicator button { + background: rgba(255, 255, 255, 0.4); +} +.p-galleria.p-galleria-indicator-onitem .p-galleria-indicators .p-galleria-indicator button:hover { + background: rgba(255, 255, 255, 0.6); +} +.p-galleria.p-galleria-indicator-onitem .p-galleria-indicators .p-galleria-indicator.p-highlight button { + background: rgba(158, 173, 230, 0.16); + color: #9eade6; +} +.p-galleria .p-galleria-thumbnail-container { + background: rgba(0, 0, 0, 0.9); + padding: 1rem 0.25rem; +} +.p-galleria .p-galleria-thumbnail-container .p-galleria-thumbnail-prev, +.p-galleria .p-galleria-thumbnail-container .p-galleria-thumbnail-next { + margin: 0.5rem; + background-color: transparent; + color: #f8f9fa; + width: 2rem; + height: 2rem; + transition: background-color 0.3s, color 0.3s, box-shadow 0.3s; + border-radius: 50%; +} +.p-galleria .p-galleria-thumbnail-container .p-galleria-thumbnail-prev:hover, +.p-galleria .p-galleria-thumbnail-container .p-galleria-thumbnail-next:hover { + background: rgba(255, 255, 255, 0.1); + color: #f8f9fa; +} +.p-galleria .p-galleria-thumbnail-container .p-galleria-thumbnail-item-content:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-galleria-mask { + --maskbg: rgba(0, 0, 0, 0.9); +} +.p-image-mask { + --maskbg: rgba(0, 0, 0, 0.9); +} +.p-image-preview-indicator { + background-color: transparent; + color: #f8f9fa; + transition: background-color 0.3s, color 0.3s, box-shadow 0.3s; +} +.p-image-preview-indicator .p-icon { + width: 1.5rem; + height: 1.5rem; +} +.p-image-preview-container:hover > .p-image-preview-indicator { + background-color: rgba(0, 0, 0, 0.5); +} +.p-image-toolbar { + padding: 1rem; +} +.p-image-action.p-link { + color: #f8f9fa; + background-color: transparent; + width: 3rem; + height: 3rem; + border-radius: 50%; + transition: background-color 0.3s, color 0.3s, box-shadow 0.3s; + margin-right: 0.5rem; +} +.p-image-action.p-link:last-child { + margin-right: 0; +} +.p-image-action.p-link:hover { + color: #f8f9fa; + background-color: rgba(255, 255, 255, 0.1); +} +.p-image-action.p-link i { + font-size: 1.5rem; +} +.p-image-action.p-link .p-icon { + width: 1.5rem; + height: 1.5rem; +} +.p-avatar { + background-color: #3c3c3c; + border-radius: 6px; +} +.p-avatar.p-avatar-lg { + width: 3rem; + height: 3rem; + font-size: 1.5rem; +} +.p-avatar.p-avatar-lg .p-avatar-icon { + font-size: 1.5rem; +} +.p-avatar.p-avatar-xl { + width: 4rem; + height: 4rem; + font-size: 2rem; +} +.p-avatar.p-avatar-xl .p-avatar-icon { + font-size: 2rem; +} +.p-avatar-group .p-avatar { + border: 2px solid #212121; +} +.p-badge { + background: #e9aaff; + color: #121212; + font-size: 0.75rem; + font-weight: 700; + min-width: 1.5rem; + height: 1.5rem; + line-height: 1.5rem; +} +.p-badge.p-badge-secondary { + background-color: #9ec1ff; + color: #131313; +} +.p-badge.p-badge-success { + background-color: #cede9c; + color: #121212; +} +.p-badge.p-badge-info { + background-color: #35a4cc; + color: #fff; +} +.p-badge.p-badge-warning { + background-color: #ffe08a; + color: #0e1315; +} +.p-badge.p-badge-danger { + background-color: #e693a9; + color: #121212; +} +.p-badge.p-badge-lg { + font-size: 1.125rem; + min-width: 2.25rem; + height: 2.25rem; + line-height: 2.25rem; +} +.p-badge.p-badge-xl { + font-size: 1.5rem; + min-width: 3rem; + height: 3rem; + line-height: 3rem; +} +.p-chip { + background-color: #3c3c3c; + color: #e6e6e6; + border-radius: 16px; + padding: 0 0.75rem; +} +.p-chip .p-chip-text { + line-height: 1.5; + margin-top: 0.25rem; + margin-bottom: 0.25rem; +} +.p-chip .p-chip-icon { + margin-right: 0.5rem; +} +.p-chip img { + width: 2rem; + height: 2rem; + margin-left: -0.75rem; + margin-right: 0.5rem; +} +.p-chip .p-chip-remove-icon { + margin-left: 0.5rem; + border-radius: 6px; + transition: background-color 0.3s, color 0.3s, box-shadow 0.3s; +} +.p-chip .p-chip-remove-icon:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-inplace .p-inplace-display { + padding: 0.5rem 0.75rem; + border-radius: 6px; + transition: background-color 0.3s, color 0.3s, border-color 0.3s, box-shadow 0.3s; +} +.p-inplace .p-inplace-display:not(.p-disabled):hover { + background: rgba(158, 173, 230, 0.08); + color: #e6e6e6; +} +.p-inplace .p-inplace-display:focus { + outline: 0 none; + outline-offset: 0; + box-shadow: 0 0 0 1px #e9aaff; +} +.p-progressbar { + border: 0 none; + height: 1.5rem; + background: #3c3c3c; + border-radius: 6px; +} +.p-progressbar .p-progressbar-value { + border: 0 none; + margin: 0; + background: #e9aaff; +} +.p-progressbar .p-progressbar-label { + color: #121212; + line-height: 1.5rem; +} +.p-progress-spinner-svg { + animation: p-progress-spinner-rotate 2s linear infinite; +} +.p-progress-spinner-circle { + stroke-dasharray: 89, 200; + stroke-dashoffset: 0; + stroke: #121212; + animation: p-progress-spinner-dash 1.5s ease-in-out infinite, p-progress-spinner-color 6s ease-in-out infinite; + stroke-linecap: round; +} +@keyframes p-progress-spinner-rotate { + 100% { + transform: rotate(360deg); + } +} +@keyframes p-progress-spinner-dash { + 0% { + stroke-dasharray: 1, 200; + stroke-dashoffset: 0; + } + 50% { + stroke-dasharray: 89, 200; + stroke-dashoffset: -35px; + } + 100% { + stroke-dasharray: 89, 200; + stroke-dashoffset: -124px; + } +} +@keyframes p-progress-spinner-color { + 100%, + 0% { + stroke: #121212; + } + 40% { + stroke: #121212; + } + 66% { + stroke: #121212; + } + 80%, + 90% { + stroke: #121212; + } +} +.p-scrolltop { + width: 3rem; + height: 3rem; + border-radius: 50%; + box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12); + transition: background-color 0.3s, color 0.3s, box-shadow 0.3s; +} +.p-scrolltop.p-link { + background: rgba(158, 173, 230, 0.16); +} +.p-scrolltop.p-link:hover { + background: rgba(158, 173, 230, 0.3616); +} +.p-scrolltop .p-scrolltop-icon { + font-size: 1.5rem; + color: #9eade6; +} +.p-scrolltop .p-scrolltop-icon.p-icon { + width: 1.5rem; + height: 1.5rem; +} +.p-skeleton { + background-color: rgba(255, 255, 255, 0.06); + border-radius: 6px; +} +.p-skeleton:after { + background: linear-gradient(90deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.04), rgba(255, 255, 255, 0)); +} +.p-tag { + background: #e9aaff; + color: #121212; + font-size: 0.75rem; + font-weight: 700; + padding: 0.25rem 0.4rem; + border-radius: 6px; +} +.p-tag.p-tag-success { + background-color: #cede9c; + color: #121212; +} +.p-tag.p-tag-info { + background-color: #35a4cc; + color: #fff; +} +.p-tag.p-tag-warning { + background-color: #ffe08a; + color: #0e1315; +} +.p-tag.p-tag-danger { + background-color: #e693a9; + color: #121212; +} +.p-tag .p-tag-icon { + margin-right: 0.25rem; + font-size: 0.75rem; +} +.p-tag .p-tag-icon.p-icon { + width: 0.75rem; + height: 0.75rem; +} +.p-terminal { + background: #212121; + color: #e6e6e6; + border: 2px solid #3c3c3c; + padding: 1rem; +} +.p-terminal .p-terminal-input { + font-size: 1rem; + font-family: Lato, Helvetica, sans-serif; +} +.p-button .p-button-label { + font-weight: 600; +} +.p-buttonset .p-button-label, +.p-togglebutton .p-button-label { + font-weight: 400; +} +.p-carousel .p-carousel-indicators .p-carousel-indicator.p-highlight button { + background-color: #e9aaff; +} +.p-galleria .p-galleria-indicators .p-galleria-indicator.p-highlight button { + background-color: #e9aaff; +} +.p-panel { + border: 2px solid #3c3c3c; + border-radius: 6px; +} +.p-panel .p-panel-header { + border: 0 none; +} +.p-panel .p-panel-content { + border: 0 none; +} +.p-fieldset .p-fieldset-legend { + border-color: transparent; +} +.p-accordion .p-accordion-toggle-icon { + order: 10; + margin-left: auto; +} +.p-accordion .p-accordion-toggle-icon.pi-chevron-right::before { + content: ""; +} +.p-accordion .p-accordion-toggle-icon.pi-chevron-down::before { + content: ""; +} +.p-accordion .p-accordion-header.p-highlight .p-accordion-header-link { + padding-bottom: calc(1rem + 2px); + border-bottom: 0 none; +} +.p-accordion .p-accordion-header:not(.p-disabled).p-highlight:hover .p-accordion-header-link { + border-bottom: 0 none; +} +.p-inline-message.p-inline-message-info { + border-color: #a3d7e6; +} +.p-inline-message.p-inline-message-success { + border-color: #bfd47f; +} +.p-inline-message.p-inline-message-warn { + border-color: #ff9c3e; +} +.p-inline-message.p-inline-message-error { + border-color: #e6a3b2; +} +.p-inputtext:enabled:focus { + box-shadow: none; +} +.p-dropdown:not(.p-disabled).p-focus { + box-shadow: none; +} +.p-multiselect:not(.p-disabled).p-focus { + box-shadow: none; +} +.p-cascadeselect:not(.p-disabled).p-focus { + box-shadow: none; +} +.p-autocomplete.p-autocomplete-multiple:not(.p-disabled).p-focus { + box-shadow: none; +} +.p-chips .p-chips-multiple-container:not(.p-disabled).p-focus { + box-shadow: none; +} +.p-orderlist .p-orderlist-list { + border-top: 0 none; +} +.p-picklist .p-picklist-list { + border-top: 0 none; +} +.p-panelmenu .p-submenu-icon.pi-chevron-right, +.p-panelmenu .p-submenu-icon.pi-chevron-down { + order: 10; + margin-left: auto; +} +.p-panelmenu .p-submenu-icon.pi-chevron-right::before { + content: ""; +} +.p-panelmenu .p-submenu-icon.pi-chevron-down::before { + content: ""; +} +.p-panelmenu .p-panelmenu-header.p-highlight > a { + padding-bottom: calc(1rem + 2px); + border-bottom: 0 none; +} +.p-panelmenu .p-panelmenu-header:not(.p-highlight):not(.p-disabled) > a:hover { + padding-bottom: calc(1rem + 2px); + border-bottom: 0 none; +} +.p-datatable .p-datatable-tbody > tr.p-datatable-dragpoint-top > td { + box-shadow: inset 0 2px 0 0 #e9aaff; +} +.p-datatable .p-datatable-tbody > tr.p-datatable-dragpoint-bottom > td { + box-shadow: inset 0 -2px 0 0 #e9aaff; +} diff --git a/packages/castmate-satellite/src/renderer/index.ts b/packages/castmate-satellite/src/renderer/index.ts new file mode 100644 index 00000000..b4bd1c4e --- /dev/null +++ b/packages/castmate-satellite/src/renderer/index.ts @@ -0,0 +1,87 @@ +import { createApp } from "vue" +import App from "./App.vue" + +import PrimeVue from "primevue/config" +import DialogService from "primevue/dialogservice" +import ConfirmationService from "primevue/confirmationservice" + +import { + initData, + useInitStore, + usePluginStore, + useResourceStore, + useSatelliteConnection, + useSatelliteMedia, + useSatelliteResourceStore, +} from "castmate-ui-core" + +import "./theme/castmate/theme.scss" +import "./css/theme-ext.css" +import "./css/spellcast.css" + +import "primevue/resources/primevue.min.css" + +import "primeicons/primeicons.css" +import "primeflex/primeflex.css" + +import "@mdi/font/css/materialdesignicons.css" + +import Tooltip from "primevue/tooltip" + +import { createPinia } from "pinia" + +import { setupProxyDialogService } from "castmate-ui-core" + +import { loadDashboardWidgets } from "castmate-dashboard-widget-loader" + +import { initSatellitePlugin as initSoundPlugin } from "castmate-plugin-sound-renderer" +//import { initPlugin as initTwitchPlugin } from "castmate-plugin-twitch-renderer" + +const pinia = createPinia() +const app = createApp(App) + +//DialogService.install?.(app) +app.use(PrimeVue) +//app.use(DialogService) +setupProxyDialogService(app) + +app.use(ConfirmationService) + +app.directive("tooltip", Tooltip) +//app.use(Maska) + +//app.use(router) +app.use(pinia) + +const initStore = useInitStore() +const pluginStore = usePluginStore() +const resourceStore = useResourceStore() + +const satelliteStore = useSatelliteConnection() +const satelliteResources = useSatelliteResourceStore() +const satelliteMedia = useSatelliteMedia() + +async function init() { + await initStore.initialize() + + await initStore.waitForInitialSetup() + + await initData() + + await pluginStore.initialize() + await resourceStore.initialize() + + await initStore.waitForInit() + + await initSoundPlugin() + + await satelliteStore.initialize("satellite") + await satelliteResources.initialize() + await satelliteMedia.initialize("satellite") + + loadDashboardWidgets() +} + +init() + +app.mount("#app") diff --git a/packages/castmate-satellite/src/renderer/theme/_extensions.scss b/packages/castmate-satellite/src/renderer/theme/_extensions.scss new file mode 100644 index 00000000..c3542ec1 --- /dev/null +++ b/packages/castmate-satellite/src/renderer/theme/_extensions.scss @@ -0,0 +1,166 @@ +@mixin focused-ring($ring-color) { + box-shadow: 0 0 0 2px #1c2127, 0 0 0 4px $ring-color, 0 1px 2px 0 rgba(0, 0, 0, 0.0); +} + +@layer primevue { + .p-button-label { + font-weight: 700; + } + + .p-selectbutton > .p-button, + .p-togglebutton.p-button { + transition: background-color $transitionDuration, border-color $transitionDuration, box-shadow $transitionDuration; + } + + .p-accordion { + .p-accordion-header { + .p-accordion-header-link { + transition: background-color $transitionDuration, border-color $transitionDuration, box-shadow $transitionDuration; + } + } + } + + .p-tabview { + .p-tabview-nav { + li { + .p-tabview-nav-link { + transition: background-color $transitionDuration, border-color $transitionDuration, box-shadow $transitionDuration; + } + } + } + } + + .p-tabmenu { + .p-tabmenu-nav { + .p-tabmenuitem { + .p-menuitem-link { + transition: background-color $transitionDuration, border-color $transitionDuration, box-shadow $transitionDuration; + } + } + } + } + + .p-carousel { + .p-carousel-indicators .p-carousel-indicator.p-highlight button { + background-color: $primaryColor; + } + } + + .p-galleria { + .p-galleria-indicators .p-galleria-indicator.p-highlight button { + background-color: $primaryColor; + } + } + + .p-button { + &:focus { + @include focused-ring(rgba($buttonBg, .7)); + } + + &.p-button-secondary:enabled:focus { + @include focused-ring(rgba($secondaryButtonBg, .7)); + } + + &.p-button-success:enabled:focus { + @include focused-ring(rgba($successButtonBg, .7)); + } + + &.p-button-info:enabled:focus { + @include focused-ring(rgba($infoButtonBg, .7)); + } + + &.p-button-warning:enabled:focus { + @include focused-ring(rgba($warningButtonBg, .7)); + } + + &.p-button-help:enabled:focus { + @include focused-ring(rgba($helpButtonBg, .7)); + } + + &.p-button-danger:enabled:focus { + @include focused-ring(rgba($dangerButtonBg, .7)); + } + } + + .p-datatable { + .p-datatable-tbody { + > tr { + &.p-datatable-dragpoint-top > td { + box-shadow: inset 0 2px 0 0 $primaryColor; + } + + &.p-datatable-dragpoint-bottom > td { + box-shadow: inset 0 -2px 0 0 $primaryColor; + } + } + } + } + + .p-speeddial-item { + &.p-focus > .p-speeddial-action { + @include focused-ring(rgba($buttonBg, .7)); + } + } + + .p-toast-message { + backdrop-filter: blur(10px); + } + + .p-message { + .p-message-close { + &:hover { + background: rgba(255,255,255,.1); + } + } + } + + .p-toast { + .p-toast-message { + .p-toast-icon-close { + &:hover { + background: rgba(255,255,255,.1); + } + } + } + } + + .p-inline-message-text { + font-weight: 500; + } + + .p-picklist-buttons .p-button, + .p-orderlist-controls .p-button { + transition: opacity $transitionDuration, background-color $transitionDuration, color $transitionDuration, border-color $transitionDuration, box-shadow $transitionDuration; + } + + .p-steps { + .p-steps-item { + &.p-highlight { + .p-steps-number { + background: $primaryColor; + color: $primaryTextColor; + } + } + } + } + + .p-stepper { + .p-stepper-header { + .p-stepper-action { + .p-stepper-number { + border-style: solid; + border-color: $shade600; + } + } + + &.p-highlight { + .p-stepper-action { + .p-stepper-number { + background: $primaryColor; + color: $primaryTextColor; + } + } + } + } + } +} \ No newline at end of file diff --git a/packages/castmate-satellite/src/renderer/theme/_variables.scss b/packages/castmate-satellite/src/renderer/theme/_variables.scss new file mode 100644 index 00000000..0eadb9b3 --- /dev/null +++ b/packages/castmate-satellite/src/renderer/theme/_variables.scss @@ -0,0 +1,912 @@ +$colors: ( + "blue": #3b82f6, + "green": #22c55e, + "yellow": #eab308, + "cyan": #06b6d4, + "pink": #ec4899, + "indigo": #6366f1, + "teal": #14b8a6, + "orange": #f97316, + "bluegray": #64748b, + "purple": #a855f7, + "red": #ff3d32, + "primary": $primaryColor, +); + +//shades +$shade000: rgba(255, 255, 255, 0.87) !default; //text color +$shade100: rgba(255, 255, 255, 0.6) !default; //text secondary color +$shade500: #6b7280 !default; +$shade600: #424b57 !default; //input bg, border, divider +$shade700: #374151 !default; //menu bg +$shade800: #1f2937 !default; //elevated surface +$shade900: #111827 !default; //ground surface + +$hoverBg: rgba(255, 255, 255, 0.03) !default; + +//global +$fontFamily: "Inter var", sans-serif !default; +$fontSize: 1rem !default; +$fontWeight: normal !default; +$textColor: $shade000 !default; +$textSecondaryColor: $shade100 !default; +$borderRadius: 6px !default; +$transitionDuration: 0.2s !default; +$formElementTransition: background-color $transitionDuration, color $transitionDuration, + border-color $transitionDuration, box-shadow $transitionDuration !default; +$actionIconTransition: background-color $transitionDuration, color $transitionDuration, box-shadow $transitionDuration !default; +$listItemTransition: box-shadow $transitionDuration !default; +$primeIconFontSize: 1rem !default; +$divider: 1px solid $shade600 !default; +$inlineSpacing: 0.5rem !default; //spacing between inline elements +$disabledOpacity: 0.4 !default; //opacity of a disabled item +$maskBg: rgba(0, 0, 0, 0.4) !default; //modal mask bg color +$loadingIconFontSize: 2rem !default; +$errorColor: #fca5a5 !default; + +//scale +$scaleSM: 0.875 !default; +$scaleLG: 1.25 !default; + +//focus +$focusOutlineColor: $primaryLightestColor !default; +$focusOutline: 0 none !default; +$focusOutlineOffset: 0 !default; +$inputFocusOutlineOffset: $focusOutlineOffset !default; +$focusShadow: 0 0 0 0.2rem $focusOutlineColor !default; + +//action icons +$actionIconWidth: 2rem !default; +$actionIconHeight: 2rem !default; +$actionIconBg: transparent !default; +$actionIconBorder: 0 none !default; +$actionIconColor: $shade100 !default; +$actionIconHoverBg: $hoverBg !default; +$actionIconHoverBorderColor: transparent !default; +$actionIconHoverColor: $shade000 !default; +$actionIconBorderRadius: 50% !default; + +//input field (e.g. inputtext, spinner, inputmask) +$inputPadding: 0.75rem 0.75rem !default; +$inputTextFontSize: 1rem !default; +$inputBg: $shade900 !default; +$inputTextColor: $shade000 !default; +$inputIconColor: $shade100 !default; +$inputBorder: 1px solid $shade600 !default; +$inputHoverBorderColor: $primaryColor !default; +$inputFocusBorderColor: $primaryColor !default; +$inputErrorBorderColor: $errorColor !default; +$inputPlaceholderTextColor: $shade100 !default; +$inputFilledBg: $shade600 !default; +$inputFilledHoverBg: $inputFilledBg !default; +$inputFilledFocusBg: $inputFilledBg !default; + +//input groups +$inputGroupBg: $shade800 !default; +$inputGroupTextColor: $shade100 !default; +$inputGroupAddOnMinWidth: 3rem !default; + +//input lists (e.g. dropdown, autocomplete, multiselect, orderlist) +$inputListBg: $shade800 !default; +$inputListTextColor: $shade000 !default; +$inputListBorder: $inputBorder !default; +$inputListPadding: 0.75rem 0 !default; +$inputListItemPadding: 0.75rem 1.25rem !default; +$inputListItemBg: transparent !default; +$inputListItemTextColor: $shade000 !default; +$inputListItemHoverBg: $hoverBg !default; +$inputListItemTextHoverColor: $shade000 !default; +$inputListItemFocusBg: $shade600 !default; +$inputListItemTextFocusColor: $shade000 !default; +$inputListItemBorder: 0 none !default; +$inputListItemBorderRadius: 0 !default; +$inputListItemMargin: 0 !default; +$inputListItemFocusShadow: inset 0 0 0 0.15rem $focusOutlineColor !default; +$inputListHeaderPadding: 0.75rem 1.25rem !default; +$inputListHeaderMargin: 0 !default; +$inputListHeaderBg: $shade800 !default; +$inputListHeaderTextColor: $shade000 !default; +$inputListHeaderBorder: 1px solid $shade600 !default; + +//inputs with overlays (e.g. autocomplete, dropdown, multiselect) +$inputOverlayBg: $inputListBg !default; +$inputOverlayHeaderBg: $inputListHeaderBg !default; +$inputOverlayBorder: 1px solid $shade600 !default; +$inputOverlayShadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), + 0 1px 10px 0 rgba(0, 0, 0, 0.12) !default; + +//password +$passwordMeterBg: $shade600 !default; +$passwordWeakBg: #eb9a9c !default; +$passwordMediumBg: #ffcf91 !default; +$passwordStrongBg: #93deac !default; + +//button +$buttonPadding: 0.75rem 1.25rem !default; +$buttonIconOnlyWidth: 3rem !default; +$buttonIconOnlyPadding: 0.75rem 0 !default; +$buttonBg: $primaryColor !default; +$buttonTextColor: $primaryTextColor !default; +$buttonBorder: 1px solid $primaryColor !default; +$buttonHoverBg: $primaryLightColor !default; +$buttonTextHoverColor: $primaryTextColor !default; +$buttonHoverBorderColor: $primaryLightColor !default; +$buttonActiveBg: $primaryLighterColor !default; +$buttonTextActiveColor: $primaryTextColor !default; +$buttonActiveBorderColor: $primaryLighterColor !default; +$raisedButtonShadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), + 0px 1px 5px 0px rgba(0, 0, 0, 0.12) !default; +$roundedButtonBorderRadius: 2rem !default; + +$textButtonHoverBgOpacity: 0.04 !default; +$textButtonActiveBgOpacity: 0.16 !default; +$outlinedButtonBorder: 1px solid !default; +$plainButtonTextColor: $textSecondaryColor !default; +$plainButtonHoverBgColor: $hoverBg !default; +$plainButtonActiveBgColor: rgba(255, 255, 255, 0.16) !default; + +$secondaryButtonBg: #94a3b8 !default; +$secondaryButtonTextColor: #020617 !default; +$secondaryButtonBorder: 1px solid #94a3b8 !default; +$secondaryButtonHoverBg: #cbd5e1 !default; +$secondaryButtonTextHoverColor: $secondaryButtonTextColor !default; +$secondaryButtonHoverBorderColor: #cbd5e1 !default; +$secondaryButtonActiveBg: #e2e8f0 !default; +$secondaryButtonTextActiveColor: $secondaryButtonTextColor !default; +$secondaryButtonActiveBorderColor: #e2e8f0 !default; +$secondaryButtonFocusShadow: 0 0 0 1px scale-color($secondaryButtonBg, $lightness: 30%) !default; + +$infoButtonBg: #38bdf8 !default; +$infoButtonTextColor: #082f49 !default; +$infoButtonBorder: 1px solid #38bdf8 !default; +$infoButtonHoverBg: #7dd3fc !default; +$infoButtonTextHoverColor: $infoButtonTextColor !default; +$infoButtonHoverBorderColor: #7dd3fc !default; +$infoButtonActiveBg: #bae6fd !default; +$infoButtonTextActiveColor: $infoButtonTextColor !default; +$infoButtonActiveBorderColor: #bae6fd !default; +$infoButtonFocusShadow: 0 0 0 1px scale-color($infoButtonBg, $lightness: 30%) !default; + +$successButtonBg: #4ade80 !default; +$successButtonTextColor: #052e16 !default; +$successButtonBorder: 1px solid #4ade80 !default; +$successButtonHoverBg: #86efac !default; +$successButtonTextHoverColor: $successButtonTextColor !default; +$successButtonHoverBorderColor: #86efac !default; +$successButtonActiveBg: #bbf7d0 !default; +$successButtonTextActiveColor: $successButtonTextColor !default; +$successButtonActiveBorderColor: #bbf7d0 !default; +$successButtonFocusShadow: 0 0 0 1px scale-color($successButtonBg, $lightness: 30%) !default; + +$warningButtonBg: #fb923c !default; +$warningButtonTextColor: #431407 !default; +$warningButtonBorder: 1px solid #fb923c !default; +$warningButtonHoverBg: #fdba74 !default; +$warningButtonTextHoverColor: $warningButtonTextColor !default; +$warningButtonHoverBorderColor: #fdba74 !default; +$warningButtonActiveBg: #fed7aa !default; +$warningButtonTextActiveColor: $warningButtonTextColor !default; +$warningButtonActiveBorderColor: #fed7aa !default; +$warningButtonFocusShadow: 0 0 0 1px scale-color($warningButtonBg, $lightness: 30%) !default; + +$helpButtonBg: #c084fc !default; +$helpButtonTextColor: #3b0764 !default; +$helpButtonBorder: 1px solid #c084fc !default; +$helpButtonHoverBg: #d8b4fe !default; +$helpButtonTextHoverColor: $helpButtonTextColor !default; +$helpButtonHoverBorderColor: #d8b4fe !default; +$helpButtonActiveBg: #e9d5ff !default; +$helpButtonTextActiveColor: $helpButtonTextColor !default; +$helpButtonActiveBorderColor: #e9d5ff !default; +$helpButtonFocusShadow: 0 0 0 1px scale-color($helpButtonBg, $lightness: 30%) !default; + +$dangerButtonBg: #f87171 !default; +$dangerButtonTextColor: #450a0a !default; +$dangerButtonBorder: 1px solid #f87171 !default; +$dangerButtonHoverBg: #fca5a5 !default; +$dangerButtonTextHoverColor: $dangerButtonTextColor !default; +$dangerButtonHoverBorderColor: #fca5a5 !default; +$dangerButtonActiveBg: #fecaca !default; +$dangerButtonTextActiveColor: $dangerButtonTextColor !default; +$dangerButtonActiveBorderColor: #fecaca !default; +$dangerButtonFocusShadow: 0 0 0 1px scale-color($dangerButtonBg, $lightness: 30%) !default; + +$contrastButtonBg: #ffffff !default; +$contrastButtonTextColor: $shade900 !default; +$contrastButtonBorder: 1px solid $contrastButtonBg !default; +$contrastButtonHoverBg: #f3f4f6 !default; +$contrastButtonTextHoverColor: $contrastButtonTextColor !default; +$contrastButtonHoverBorderColor: #f3f4f6 !default; +$contrastButtonActiveBg: #e5e7eb !default; +$contrastButtonTextActiveColor: $contrastButtonTextColor !default; +$contrastButtonActiveBorderColor: #e5e7eb !default; +$contrastButtonFocusShadow: none !default; + +$linkButtonColor: $primaryColor !default; +$linkButtonHoverColor: $primaryColor !default; +$linkButtonTextHoverDecoration: underline !default; +$linkButtonFocusShadow: 0 0 0 1px $focusOutlineColor !default; + +//checkbox +$checkboxWidth: 22px !default; +$checkboxHeight: 22px !default; +$checkboxBorder: 2px solid $shade600 !default; +$checkboxIconFontSize: 14px !default; +$checkboxActiveBorderColor: $primaryColor !default; +$checkboxActiveBg: $primaryColor !default; +$checkboxIconActiveColor: $primaryTextColor !default; +$checkboxActiveHoverBg: $primaryLighterColor !default; +$checkboxIconActiveHoverColor: $primaryTextColor !default; +$checkboxActiveHoverBorderColor: $primaryLighterColor !default; + +//radiobutton +$radiobuttonWidth: 22px !default; +$radiobuttonHeight: 22px !default; +$radiobuttonBorder: 2px solid $shade600 !default; +$radiobuttonIconSize: 12px !default; +$radiobuttonActiveBorderColor: $primaryColor !default; +$radiobuttonActiveBg: $primaryColor !default; +$radiobuttonIconActiveColor: $primaryTextColor !default; +$radiobuttonActiveHoverBg: $primaryLighterColor !default; +$radiobuttonIconActiveHoverColor: $primaryTextColor !default; +$radiobuttonActiveHoverBorderColor: $primaryLighterColor !default; + +//colorpicker +$colorPickerPreviewWidth: 2rem !default; +$colorPickerPreviewHeight: 2rem !default; +$colorPickerBg: $shade800 !default; +$colorPickerBorder: 1px solid $shade600 !default; +$colorPickerHandleColor: $shade000 !default; + +//togglebutton +$toggleButtonBg: $shade800 !default; +$toggleButtonBorder: 1px solid $shade600 !default; +$toggleButtonTextColor: $shade000 !default; +$toggleButtonIconColor: $shade100 !default; +$toggleButtonHoverBg: $hoverBg !default; +$toggleButtonHoverBorderColor: $shade600 !default; +$toggleButtonTextHoverColor: $shade000 !default; +$toggleButtonIconHoverColor: $shade100 !default; +$toggleButtonActiveBg: $primaryColor !default; +$toggleButtonActiveBorderColor: $primaryColor !default; +$toggleButtonTextActiveColor: $primaryTextColor !default; +$toggleButtonIconActiveColor: $primaryTextColor !default; +$toggleButtonActiveHoverBg: $primaryLightColor !default; +$toggleButtonActiveHoverBorderColor: $primaryLightColor !default; +$toggleButtonTextActiveHoverColor: $primaryTextColor !default; +$toggleButtonIconActiveHoverColor: $primaryTextColor !default; + +//inplace +$inplacePadding: $inputPadding !default; +$inplaceHoverBg: $hoverBg !default; +$inplaceTextHoverColor: $shade000 !default; + +//rating +$ratingIconFontSize: 1.143rem !default; +$ratingCancelIconColor: #f48fb1 !default; +$ratingCancelIconHoverColor: #f48fb1 !default; +$ratingStarIconOffColor: $shade000 !default; +$ratingStarIconOnColor: $primaryColor !default; +$ratingStarIconHoverColor: $primaryColor !default; + +//slider +$sliderBg: $shade600 !default; +$sliderBorder: 0 none !default; +$sliderHorizontalHeight: 0.286rem !default; +$sliderVerticalWidth: 0.286rem !default; +$sliderHandleWidth: 1.143rem !default; +$sliderHandleHeight: 1.143rem !default; +$sliderHandleBg: $shade600 !default; +$sliderHandleBorder: 2px solid $primaryColor !default; +$sliderHandleBorderRadius: 50% !default; +$sliderHandleHoverBorderColor: $primaryColor !default; +$sliderHandleHoverBg: $primaryColor !default; +$sliderRangeBg: $primaryColor !default; + +//calendar +$calendarTableMargin: 0.5rem 0 !default; +$calendarPadding: 0.5rem !default; +$calendarBg: $shade800 !default; +$calendarInlineBg: $calendarBg !default; +$calendarTextColor: $shade000 !default; +$calendarBorder: $inputListBorder !default; +$calendarOverlayBorder: $inputOverlayBorder !default; + +$calendarHeaderPadding: 0.5rem !default; +$calendarHeaderBg: $shade800 !default; +$calendarInlineHeaderBg: $calendarBg !default; +$calendarHeaderBorder: 1px solid $shade600 !default; +$calendarHeaderTextColor: $shade000 !default; +$calendarHeaderFontWeight: 700 !default; +$calendarHeaderCellPadding: 0.5rem !default; +$calendarMonthYearHeaderHoverTextColor: $primaryColor !default; + +$calendarCellDatePadding: 0.5rem !default; +$calendarCellDateWidth: 2.5rem !default; +$calendarCellDateHeight: 2.5rem !default; +$calendarCellDateBorderRadius: 50% !default; +$calendarCellDateBorder: 1px solid transparent !default; +$calendarCellDateHoverBg: $hoverBg !default; +$calendarCellDateTodayBg: transparent !default; +$calendarCellDateTodayBorderColor: transparent !default; +$calendarCellDateTodayTextColor: $primaryColor !default; + +$calendarButtonBarPadding: 1rem 0 !default; +$calendarTimePickerPadding: 0.5rem !default; +$calendarTimePickerElementPadding: 0 0.5rem !default; +$calendarTimePickerTimeFontSize: 1.25rem !default; + +$calendarBreakpoint: 769px !default; +$calendarCellDatePaddingSM: 0 !default; + +//input switch +$inputSwitchWidth: 3rem !default; +$inputSwitchHeight: 1.75rem !default; +$inputSwitchBorderRadius: 30px !default; +$inputSwitchHandleWidth: 1.25rem !default; +$inputSwitchHandleHeight: 1.25rem !default; +$inputSwitchHandleBorderRadius: 50% !default; +$inputSwitchSliderPadding: 0.25rem !default; +$inputSwitchSliderOffBg: $shade500 !default; +$inputSwitchHandleOffBg: $shade100 !default; +$inputSwitchSliderOffHoverBg: $shade600 !default; +$inputSwitchSliderOnBg: $primaryColor !default; +$inputSwitchSliderOnHoverBg: $primaryLightColor !default; +$inputSwitchHandleOnBg: $primaryTextColor !default; + +//panel +$panelHeaderBorderColor: $shade600 !default; +$panelHeaderBorder: 1px solid $shade600 !default; +$panelHeaderBg: $shade800 !default; +$panelHeaderTextColor: $shade000 !default; +$panelHeaderFontWeight: 700 !default; +$panelHeaderPadding: 1.25rem !default; +$panelToggleableHeaderPadding: 0.75rem 1.25rem !default; + +$panelHeaderHoverBg: $hoverBg !default; +$panelHeaderHoverBorderColor: $shade600 !default; +$panelHeaderTextHoverColor: $shade000 !default; + +$panelContentBorderColor: $shade600 !default; +$panelContentBorder: 1px solid $shade600 !default; +$panelContentBg: $shade800 !default; +$panelContentEvenRowBg: #1c2532 !default; +$panelContentTextColor: $shade000 !default; +$panelContentPadding: 1.25rem !default; + +$panelFooterBorder: 1px solid $shade600 !default; +$panelFooterBg: $shade800 !default; +$panelFooterTextColor: $shade000 !default; +$panelFooterPadding: 0.75rem 1.25rem !default; + +//accordion +$accordionSpacing: 4px !default; +$accordionHeaderBorder: $panelHeaderBorder !default; +$accordionHeaderBg: $panelHeaderBg !default; +$accordionHeaderTextColor: $panelHeaderTextColor !default; +$accordionHeaderFontWeight: $panelHeaderFontWeight !default; +$accordionHeaderPadding: $panelHeaderPadding !default; + +$accordionHeaderHoverBg: $hoverBg !default; +$accordionHeaderHoverBorderColor: $shade600 !default; +$accordionHeaderTextHoverColor: $shade000 !default; + +$accordionHeaderActiveBg: $panelHeaderBg !default; +$accordionHeaderActiveBorderColor: $shade600 !default; +$accordionHeaderTextActiveColor: $shade000 !default; + +$accordionHeaderActiveHoverBg: $hoverBg !default; +$accordionHeaderActiveHoverBorderColor: $shade600 !default; +$accordionHeaderTextActiveHoverColor: $shade000 !default; + +$accordionContentBorder: $panelContentBorder !default; +$accordionContentBg: $panelContentBg !default; +$accordionContentTextColor: $panelContentTextColor !default; +$accordionContentPadding: $panelContentPadding !default; + +//tabview +$tabviewNavBorder: 1px solid $shade600 !default; +$tabviewNavBorderWidth: 0 0 2px 0 !default; +$tabviewNavBg: transparent !default; + +$tabviewHeaderSpacing: 0 !default; +$tabviewHeaderBorder: solid $shade600 !default; +$tabviewHeaderBorderWidth: 0 0 2px 0 !default; +$tabviewHeaderBorderColor: transparent transparent $shade600 transparent !default; +$tabviewHeaderBg: $shade800 !default; +$tabviewHeaderTextColor: $shade100 !default; +$tabviewHeaderFontWeight: $panelHeaderFontWeight !default; +$tabviewHeaderPadding: $panelHeaderPadding !default; +$tabviewHeaderMargin: 0 0 -2px 0 !default; + +$tabviewHeaderHoverBg: $shade800 !default; +$tabviewHeaderHoverBorderColor: $primaryColor !default; +$tabviewHeaderTextHoverColor: $shade000 !default; + +$tabviewHeaderActiveBg: $shade800 !default; +$tabviewHeaderActiveBorderColor: $primaryColor !default; +$tabviewHeaderTextActiveColor: $primaryColor !default; + +$tabviewContentBorder: 0 none !default; +$tabviewContentBg: $shade800 !default; +$tabviewContentTextColor: $shade000 !default; +$tabviewContentPadding: $panelContentPadding !default; + +//upload +$fileUploadProgressBarHeight: 0.25rem !default; +$fileUploadContentPadding: 2rem 1rem !default; +$fileUploadContentHoverBorder: 1px dashed $primaryColor !default; +$fileUploadFileBorder: 1px solid $shade600 !default; +$fileUploadFilePadding: 1rem !default; + +//scrollpanel +$scrollPanelTrackBorder: 0 none !default; +$scrollPanelTrackBg: $shade600 !default; + +//card +$cardBodyPadding: 1.25rem !default; +$cardTitleFontSize: 1.5rem !default; +$cardTitleFontWeight: 700 !default; +$cardSubTitleFontWeight: 400 !default; +$cardSubTitleColor: $shade100 !default; +$cardContentPadding: 1.25rem 0 !default; +$cardFooterPadding: 1.25rem 0 0 0 !default; +$cardShadow: 0 2px 1px -1px rgba(0, 0, 0, 0.2), 0 1px 1px 0 rgba(0, 0, 0, 0.14), 0 1px 3px 0 rgba(0, 0, 0, 0.12) !default; + +//editor +$editorToolbarBg: $panelHeaderBg !default; +$editorToolbarBorder: $panelHeaderBorder !default; +$editorToolbarPadding: $panelHeaderPadding !default; +$editorToolbarIconColor: $textSecondaryColor !default; +$editorToolbarIconHoverColor: $textColor !default; +$editorIconActiveColor: $primaryColor !default; +$editorContentBorder: $panelContentBorder !default; +$editorContentBg: $panelContentBg !default; + +//paginator +$paginatorBg: $shade800 !default; +$paginatorTextColor: $shade100 !default; +$paginatorBorder: solid $shade600 !default; +$paginatorBorderWidth: 1px !default; +$paginatorPadding: 0.5rem 1rem !default; +$paginatorElementWidth: $buttonIconOnlyWidth !default; +$paginatorElementHeight: $buttonIconOnlyWidth !default; +$paginatorElementBg: transparent !default; +$paginatorElementBorder: 0 none !default; +$paginatorElementIconColor: $shade100 !default; +$paginatorElementHoverBg: $hoverBg !default; +$paginatorElementHoverBorderColor: transparent !default; +$paginatorElementIconHoverColor: $shade000 !default; +$paginatorElementBorderRadius: $borderRadius !default; +$paginatorElementMargin: 0.143rem !default; +$paginatorElementPadding: 0 !default; + +//table +$tableHeaderBorder: 1px solid $shade600 !default; +$tableHeaderBorderWidth: 0 0 1px 0 !default; +$tableHeaderBg: $shade800 !default; +$tableHeaderTextColor: $shade100 !default; +$tableHeaderFontWeight: 700 !default; +$tableHeaderPadding: 1rem 1rem !default; + +$tableHeaderCellPadding: 1rem 1rem !default; +$tableHeaderCellBg: $shade800 !default; +$tableHeaderCellTextColor: $shade000 !default; +$tableHeaderCellFontWeight: 700 !default; +$tableHeaderCellBorder: 1px solid $shade600 !default; +$tableHeaderCellBorderWidth: 0 0 1px 0 !default; +$tableHeaderCellHoverBg: $hoverBg !default; +$tableHeaderCellTextHoverColor: $shade000 !default; +$tableHeaderCellIconColor: $shade100 !default; +$tableHeaderCellIconHoverColor: $shade000 !default; +$tableHeaderCellHighlightBg: $highlightBg !default; +$tableHeaderCellHighlightTextColor: $highlightTextColor !default; +$tableHeaderCellHighlightHoverBg: $highlightBg !default; +$tableHeaderCellHighlightTextHoverColor: $highlightTextColor !default; +$tableSortableColumnBadgeSize: 1.143rem !default; + +$tableBodyRowBg: $shade800 !default; +$tableBodyRowTextColor: $shade000 !default; +$tableBodyRowEvenBg: #1c2532 !default; +$tableBodyRowHoverBg: $hoverBg !default; +$tableBodyRowTextHoverColor: $shade000 !default; +$tableBodyCellBorder: 1px solid $shade600 !default; +$tableBodyCellBorderWidth: 0 0 1px 0 !default; +$tableBodyCellPadding: 1rem 1rem !default; + +$tableFooterCellPadding: 1rem 1rem !default; +$tableFooterCellBg: $shade800 !default; +$tableFooterCellTextColor: $shade000 !default; +$tableFooterCellFontWeight: 700 !default; +$tableFooterCellBorder: 1px solid $shade600 !default; +$tableFooterCellBorderWidth: 0 0 1px 0 !default; +$tableResizerHelperBg: $primaryColor !default; + +$tableFooterBorder: 1px solid $shade600 !default; +$tableFooterBorderWidth: 0 0 1px 0 !default; +$tableFooterBg: $shade800 !default; +$tableFooterTextColor: $shade000 !default; +$tableFooterFontWeight: 700 !default; +$tableFooterPadding: 1rem 1rem !default; + +$tableCellContentAlignment: left !default; +$tableTopPaginatorBorderWidth: 1px 0 1px 0 !default; +$tableBottomPaginatorBorderWidth: 0 0 1px 0 !default; + +$tableScaleSM: 0.5 !default; +$tableScaleLG: 1.25 !default; + +//dataview +$dataViewContentPadding: 0 !default; +$dataViewContentBorder: 0 none !default; + +//tree +$treeContainerPadding: 0.286rem !default; +$treeNodePadding: 0.143rem !default; +$treeNodeContentPadding: 0.5rem !default; +$treeNodeChildrenPadding: 0 0 0 1rem !default; +$treeNodeIconColor: $shade100 !default; + +//timeline +$timelineVerticalEventContentPadding: 0 1rem !default; +$timelineHorizontalEventContentPadding: 1rem 0 !default; +$timelineEventMarkerWidth: 1rem !default; +$timelineEventMarkerHeight: 1rem !default; +$timelineEventMarkerBorderRadius: 50% !default; +$timelineEventMarkerBorder: 2px solid $primaryColor !default; +$timelineEventMarkerBackground: $primaryTextColor !default; +$timelineEventConnectorSize: 2px !default; +$timelineEventColor: $shade600 !default; + +//org chart +$organizationChartConnectorColor: $shade600 !default; + +//message +$messageMargin: 1rem 0 !default; +$messagePadding: 1.25rem 1.75rem !default; +$messageBorderWidth: 0 0 0 6px !default; +$messageIconFontSize: 1.5rem !default; +$messageTextFontSize: 1rem !default; +$messageTextFontWeight: 500 !default; + +//inline message +$inlineMessagePadding: $inputPadding !default; +$inlineMessageMargin: 0 !default; +$inlineMessageIconFontSize: 1rem !default; +$inlineMessageTextFontSize: 1rem !default; +$inlineMessageBorderWidth: 1px !default; + +//toast +$toastIconFontSize: 2rem !default; +$toastMessageTextMargin: 0 0 0 1rem !default; +$toastMargin: 0 0 1rem 0 !default; +$toastPadding: 1rem !default; +$toastBorderWidth: 0 0 0 6px !default; +$toastShadow: none !default; +$toastOpacity: 1 !default; +$toastTitleFontWeight: 700 !default; +$toastDetailMargin: $inlineSpacing 0 0 0 !default; + +//severities +$infoMessageBg: rgba(59, 130, 246, 0.2) !default; +$infoMessageBorder: solid #3b82f6 !default; +$infoMessageTextColor: #93c5fd !default; +$infoMessageIconColor: #93c5fd !default; +$successMessageBg: rgba(16, 185, 129, 0.2) !default; +$successMessageBorder: solid #10b981 !default; +$successMessageTextColor: #6ee7b7 !default; +$successMessageIconColor: #6ee7b7 !default; +$warningMessageBg: rgba(234, 179, 8, 0.2) !default; +$warningMessageBorder: solid #eab308 !default; +$warningMessageTextColor: #fde047 !default; +$warningMessageIconColor: #fde047 !default; +$errorMessageBg: rgba(239, 68, 68, 0.2) !default; +$errorMessageBorder: solid #ef4444 !default; +$errorMessageTextColor: #fca5a5 !default; +$errorMessageIconColor: #fca5a5 !default; +$secondaryMessageBg: $secondaryButtonBg !default; +$secondaryMessageBorder: solid $secondaryButtonBg !default; +$secondaryMessageTextColor: $secondaryButtonTextColor !default; +$secondaryMessageIconColor: $secondaryButtonTextColor !default; +$contrastMessageBg: $contrastButtonBg !default; +$contrastMessageBorder: solid $contrastButtonBg !default; +$contrastMessageTextColor: $contrastButtonTextColor !default; +$contrastMessageIconColor: $contrastButtonTextColor !default; + +//overlays +$overlayContentBorder: 1px solid $shade600 !default; +$overlayContentBg: $panelContentBg !default; +$overlayContainerShadow: 0px 11px 15px -7px rgba(0, 0, 0, 0.2), 0px 24px 38px 3px rgba(0, 0, 0, 0.14), + 0px 9px 46px 8px rgba(0, 0, 0, 0.12) !default; + +//dialog +$dialogHeaderBg: $shade800 !default; +$dialogHeaderBorder: 0 none !default; +$dialogHeaderTextColor: $shade000 !default; +$dialogHeaderFontWeight: 700 !default; +$dialogHeaderFontSize: 1.25rem !default; +$dialogHeaderPadding: 1.5rem !default; +$dialogContentPadding: 0 1.5rem 2rem 1.5rem !default; +$dialogFooterBorder: 0 none !default; +$dialogFooterPadding: 0 1.5rem 1.5rem 1.5rem !default; + +//confirmpopup +$confirmPopupContentPadding: $panelContentPadding !default; +$confirmPopupFooterPadding: 0 1.25rem 1.25rem 1.25rem !default; + +//tooltip +$tooltipBg: $shade600 !default; +$tooltipTextColor: $shade000 !default; +$tooltipPadding: $inputPadding !default; + +//steps +$stepsItemBg: transparent !default; +$stepsItemBorder: 0 none !default; +$stepsItemTextColor: $shade100 !default; +$stepsItemNumberWidth: 2rem !default; +$stepsItemNumberHeight: 2rem !default; +$stepsItemNumberFontSize: 1.143rem !default; +$stepsItemNumberColor: $shade000 !default; +$stepsItemNumberBorderRadius: 50% !default; +$stepsItemActiveFontWeight: 700 !default; + +//progressbar, progressspinner +$progressBarHeight: 1.5rem !default; +$progressBarBorder: 0 none !default; +$progressBarBg: $shade600 !default; +$progressBarValueBg: $primaryColor !default; +$progressBarValueTextColor: $primaryTextColor !default; + +$progressSpinnerStrokeColor: $errorMessageTextColor !default; +$progressSpinnerColorOne: $errorMessageTextColor !default; +$progressSpinnerColorTwo: $infoMessageTextColor !default; +$progressSpinnerColorThree: $successMessageTextColor !default; +$progressSpinnerColorFour: $warningMessageTextColor !default; + +//menu (e.g. menu, menubar, tieredmenu) +$menuWidth: 12.5rem !default; +$menuBg: $shade700 !default; +$menuBorder: 1px solid $shade600 !default; +$menuTextColor: $shade000 !default; +$menuitemPadding: 0.75rem 1.25rem !default; +$menuitemBorderRadius: 0 !default; +$menuitemTextColor: $shade000 !default; +$menuitemIconColor: $shade100 !default; +$menuitemTextHoverColor: $shade000 !default; +$menuitemIconHoverColor: $shade000 !default; +$menuitemHoverBg: $hoverBg !default; +$menuitemTextFocusColor: $shade000 !default; +$menuitemIconFocusColor: $shade000 !default; +$menuitemFocusBg: $shade600 !default; +$menuitemTextActiveColor: $highlightTextColor !default; +$menuitemIconActiveColor: $highlightTextColor !default; +$menuitemActiveBg: $highlightBg !default; +$menuitemActiveFocusBg: $highlightFocusBg !default; +$menuitemSubmenuIconFontSize: 0.875rem !default; +$submenuHeaderMargin: 0 !default; +$submenuHeaderPadding: 0.75rem 1.25rem !default; +$submenuHeaderBg: $shade700 !default; +$submenuHeaderTextColor: $shade000 !default; +$submenuHeaderBorderRadius: 0 !default; +$submenuHeaderFontWeight: 700 !default; +$overlayMenuBg: $menuBg !default; +$overlayMenuBorder: 1px solid $shade600 !default; +$overlayMenuShadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12) !default; +$verticalMenuPadding: 0.25rem 0 !default; +$menuSeparatorMargin: 0.25rem 0 !default; + +$breadcrumbPadding: 1rem !default; +$breadcrumbBg: $menuBg !default; +$breadcrumbBorder: $menuBorder !default; +$breadcrumbItemTextColor: $menuitemTextColor !default; +$breadcrumbItemIconColor: $menuitemIconColor !default; +$breadcrumbLastItemTextColor: $menuitemTextColor !default; +$breadcrumbLastItemIconColor: $menuitemIconColor !default; +$breadcrumbSeparatorColor: $menuitemTextColor !default; + +$horizontalMenuPadding: 0.5rem !default; +$horizontalMenuBg: $shade700 !default; +$horizontalMenuBorder: $menuBorder !default; +$horizontalMenuTextColor: $menuTextColor !default; +$horizontalMenuRootMenuitemPadding: $menuitemPadding !default; +$horizontalMenuRootMenuitemBorderRadius: $borderRadius !default; +$horizontalMenuRootMenuitemTextColor: $menuitemTextColor !default; +$horizontalMenuRootMenuitemIconColor: $menuitemIconColor !default; +$horizontalMenuRootMenuitemTextHoverColor: $menuitemTextHoverColor !default; +$horizontalMenuRootMenuitemIconHoverColor: $menuitemIconHoverColor !default; +$horizontalMenuRootMenuitemHoverBg: $menuitemHoverBg !default; +$horizontalMenuRootMenuitemTextActiveColor: $menuitemTextActiveColor !default; +$horizontalMenuRootMenuitemIconActiveColor: $menuitemIconActiveColor !default; +$horizontalMenuRootMenuitemActiveBg: $menuitemActiveBg !default; + +//badge and tag +$badgeBg: $primaryColor !default; +$badgeTextColor: $primaryTextColor !default; +$badgeMinWidth: 1.5rem !default; +$badgeHeight: 1.5rem !default; +$badgeFontWeight: 700 !default; +$badgeFontSize: 0.75rem !default; + +$tagPadding: 0.25rem 0.4rem !default; + +//carousel +$carouselIndicatorsPadding: 1rem !default; +$carouselIndicatorBg: $shade600 !default; +$carouselIndicatorHoverBg: $hoverBg !default; +$carouselIndicatorBorderRadius: 0 !default; +$carouselIndicatorWidth: 2rem !default; +$carouselIndicatorHeight: 0.5rem !default; + +//galleria +$galleriaMaskBg: rgba(0, 0, 0, 0.9) !default; +$galleriaCloseIconMargin: 0.5rem !default; +$galleriaCloseIconFontSize: 2rem !default; +$galleriaCloseIconBg: transparent !default; +$galleriaCloseIconColor: #f8f9fa !default; +$galleriaCloseIconHoverBg: rgba(255, 255, 255, 0.1) !default; +$galleriaCloseIconHoverColor: #f8f9fa !default; +$galleriaCloseIconWidth: 4rem !default; +$galleriaCloseIconHeight: 4rem !default; +$galleriaCloseIconBorderRadius: 50% !default; + +$galleriaItemNavigatorBg: transparent !default; +$galleriaItemNavigatorColor: #f8f9fa !default; +$galleriaItemNavigatorMargin: 0 0.5rem !default; +$galleriaItemNavigatorFontSize: 2rem !default; +$galleriaItemNavigatorHoverBg: rgba(255, 255, 255, 0.1) !default; +$galleriaItemNavigatorHoverColor: #f8f9fa !default; +$galleriaItemNavigatorWidth: 4rem !default; +$galleriaItemNavigatorHeight: 4rem !default; +$galleriaItemNavigatorBorderRadius: $borderRadius !default; + +$galleriaCaptionBg: rgba(0, 0, 0, 0.5) !default; +$galleriaCaptionTextColor: #f8f9fa !default; +$galleriaCaptionPadding: 1rem !default; + +$galleriaIndicatorsPadding: 1rem !default; +$galleriaIndicatorBg: $shade600 !default; +$galleriaIndicatorHoverBg: rgba(255, 255, 255, 0.1) !default; +$galleriaIndicatorBorderRadius: 50% !default; +$galleriaIndicatorWidth: 1rem !default; +$galleriaIndicatorHeight: 1rem !default; +$galleriaIndicatorsBgOnItem: rgba(0, 0, 0, 0.5) !default; +$galleriaIndicatorBgOnItem: rgba(255, 255, 255, 0.4) !default; +$galleriaIndicatorHoverBgOnItem: rgba(255, 255, 255, 0.6) !default; + +$galleriaThumbnailContainerBg: rgba(0, 0, 0, 0.9) !default; +$galleriaThumbnailContainerPadding: 1rem 0.25rem !default; +$galleriaThumbnailNavigatorBg: transparent !default; +$galleriaThumbnailNavigatorColor: #f8f9fa !default; +$galleriaThumbnailNavigatorHoverBg: rgba(255, 255, 255, 0.1) !default; +$galleriaThumbnailNavigatorHoverColor: #f8f9fa !default; +$galleriaThumbnailNavigatorBorderRadius: 50% !default; +$galleriaThumbnailNavigatorWidth: 2rem !default; +$galleriaThumbnailNavigatorHeight: 2rem !default; + +//divider +$dividerHorizontalMargin: 1.25rem 0 !default; +$dividerHorizontalPadding: 0 1.25rem !default; +$dividerVerticalMargin: 0 1.25rem !default; +$dividerVerticalPadding: 1.25rem 0 !default; +$dividerSize: 1px !default; +$dividerColor: $shade600 !default; + +//avatar +$avatarBg: $shade600 !default; +$avatarTextColor: $textColor !default; + +//chip +$chipBg: $shade600 !default; +$chipTextColor: $textColor !default; +$chipBorderRadius: 16px !default; +$chipFocusBg: $shade500 !default; +$chipFocusTextColor: $textColor !default; + +//scrollTop +$scrollTopBg: $highlightBg !default; +$scrollTopHoverBg: scale-color($highlightBg, $alpha: 24%) !default; +$scrollTopWidth: 3rem !default; +$scrollTopHeight: 3rem !default; +$scrollTopBorderRadius: 50% !default; +$scrollTopFontSize: 1.5rem !default; +$scrollTopTextColor: $highlightTextColor !default; + +//skeleton +$skeletonBg: rgba(255, 255, 255, 0.06) !default; +$skeletonAnimationBg: rgba(255, 255, 255, 0.04) !default; + +//splitter +$splitterGutterBg: rgba(255, 255, 255, 0.03) !default; +$splitterGutterHandleBg: $shade600 !default; + +//speeddial +$speedDialButtonWidth: 4rem !default; +$speedDialButtonHeight: 4rem !default; +$speedDialButtonIconFontSize: 1.3rem !default; +$speedDialActionWidth: 3rem !default; +$speedDialActionHeight: 3rem !default; +$speedDialActionBg: $shade000 !default; +$speedDialActionHoverBg: $shade100 !default; +$speedDialActionTextColor: $shade900 !default; +$speedDialActionTextHoverColor: $shade900 !default; + +//dock +$dockActionWidth: 4rem !default; +$dockActionHeight: 4rem !default; +$dockItemPadding: 0.5rem !default; +$dockItemBorderRadius: $borderRadius !default; +$dockCurrentItemMargin: 1.5rem !default; +$dockFirstItemsMargin: 1.3rem !default; +$dockSecondItemsMargin: 0.9rem !default; +$dockBg: rgba(255, 255, 255, 0.1) !default; +$dockBorder: 1px solid rgba(255, 255, 255, 0.2) !default; +$dockPadding: 0.5rem 0.5rem !default; +$dockBorderRadius: 0.5rem !default; + +//image +$imageMaskBg: rgba(0, 0, 0, 0.9) !default; +$imagePreviewToolbarPadding: 1rem !default; +$imagePreviewIndicatorColor: #f8f9fa !default; +$imagePreviewIndicatorBg: rgba(0, 0, 0, 0.5) !default; +$imagePreviewActionIconBg: transparent !default; +$imagePreviewActionIconColor: #f8f9fa !default; +$imagePreviewActionIconHoverBg: rgba(255, 255, 255, 0.1) !default; +$imagePreviewActionIconHoverColor: #f8f9fa !default; +$imagePreviewActionIconWidth: 3rem !default; +$imagePreviewActionIconHeight: 3rem !default; +$imagePreviewActionIconFontSize: 1.5rem !default; +$imagePreviewActionIconBorderRadius: 50% !default; + +:root { + font-family: "Inter var", sans-serif; + font-feature-settings: "cv02", "cv03", "cv04", "cv11"; + font-variation-settings: normal; + --font-family: "Inter var", sans-serif; + --font-feature-settings: "cv02", "cv03", "cv04", "cv11"; + --surface-a: #{$shade800}; + --surface-b: #{$shade900}; + --surface-c: #{$hoverBg}; + --surface-d: #{$shade600}; + --surface-e: #{$shade800}; + --surface-f: #{$shade800}; + --text-color: #{$shade000}; + --text-color-secondary: #{$shade100}; + --primary-color: #{$primaryColor}; + --primary-color-text: #{$primaryTextColor}; + --success-color: #{$successButtonBg}; + --surface-0: #0e1315; + --surface-50: #262b2c; + --surface-100: #3e4244; + --surface-200: #565a5b; + --surface-300: #6e7173; + --surface-400: #87898a; + --surface-500: #9fa1a1; + --surface-600: #b7b8b9; + --surface-700: #cfd0d0; + --surface-800: #e7e7e8; + --surface-900: #ffffff; + --gray-50: #e7e7e8; + --gray-100: #cfd0d0; + --gray-200: #b7b8b9; + --gray-300: #9fa1a1; + --gray-400: #87898a; + --gray-500: #6e7173; + --gray-600: #565a5b; + --gray-700: #3e4244; + --gray-800: #262b2c; + --gray-900: #0e1315; + --content-padding: #{$panelContentPadding}; + --inline-spacing: #{$inlineSpacing}; + --border-radius: #{$borderRadius}; + --surface-ground: #121212; + --surface-section: #232323; + --surface-card: #161616; + --surface-overlay: #1d1d1d; + --surface-border: rgba(255, 255, 255, 0.1); + --surface-hover: rgba(255, 255, 255, 0.03); + --focus-ring: #{$focusShadow}; + --maskbg: #{$maskBg}; + --highlight-bg: #{$highlightBg}; + --highlight-text-color: #{$highlightTextColor}; + color-scheme: dark; +} diff --git a/packages/castmate-satellite/src/renderer/theme/castmate/_fonts.scss b/packages/castmate-satellite/src/renderer/theme/castmate/_fonts.scss new file mode 100644 index 00000000..963c1cdb --- /dev/null +++ b/packages/castmate-satellite/src/renderer/theme/castmate/_fonts.scss @@ -0,0 +1,16 @@ +@font-face { + font-family: 'Inter var'; + font-weight: 100 900; + font-display: swap; + font-style: normal; + font-named-instance: 'Regular'; + src: url("./fonts/Inter-roman.var.woff2?v=3.19") format("woff2"); +} +@font-face { + font-family: 'Inter var'; + font-weight: 100 900; + font-display: swap; + font-style: italic; + font-named-instance: 'Italic'; + src: url("./fonts/Inter-italic.var.woff2?v=3.19") format("woff2"); +} \ No newline at end of file diff --git a/packages/castmate-satellite/src/renderer/theme/castmate/fonts/Inter-italic.var.woff2 b/packages/castmate-satellite/src/renderer/theme/castmate/fonts/Inter-italic.var.woff2 new file mode 100644 index 00000000..b826d5af Binary files /dev/null and b/packages/castmate-satellite/src/renderer/theme/castmate/fonts/Inter-italic.var.woff2 differ diff --git a/packages/castmate-satellite/src/renderer/theme/castmate/fonts/Inter-roman.var.woff2 b/packages/castmate-satellite/src/renderer/theme/castmate/fonts/Inter-roman.var.woff2 new file mode 100644 index 00000000..6a256a06 Binary files /dev/null and b/packages/castmate-satellite/src/renderer/theme/castmate/fonts/Inter-roman.var.woff2 differ diff --git a/packages/castmate-satellite/src/renderer/theme/castmate/theme.scss b/packages/castmate-satellite/src/renderer/theme/castmate/theme.scss new file mode 100644 index 00000000..ec34b488 --- /dev/null +++ b/packages/castmate-satellite/src/renderer/theme/castmate/theme.scss @@ -0,0 +1,22 @@ +$primaryColor: #e9aaff !default; +$primaryLightColor: #e9aaff !default; +$primaryLighterColor: #e9aaff !default; +$primaryLightestColor: rgba(96, 165, 250, 0.2) !default; +$primaryTextColor: #030712 !default; + +$highlightBg: rgba(96, 165, 250, 0.16) !default; +$highlightTextColor: rgba(255, 255, 255, 0.87) !default; +$highlightFocusBg: rgba($primaryColor, 0.24) !default; + +$shade000: rgba(255, 255, 255, 0.87) !default; //text color +$shade100: rgba(255, 255, 255, 0.6) !default; //text secondary color +$shade500: #6b7280 !default; +$shade600: #3c3c3c !default; //input bg, border, divider +$shade700: #3c3c3c !default; //menu bg +$shade800: #212121 !default; //elevated surface +$shade900: #121212 !default; //ground surface + +@import "../_variables"; +@import "./_fonts"; +@import "../theme-base/_components"; +@import "../_extensions"; diff --git a/packages/castmate-satellite/src/renderer/theme/theme-base/_colors.scss b/packages/castmate-satellite/src/renderer/theme/theme-base/_colors.scss new file mode 100644 index 00000000..de705905 --- /dev/null +++ b/packages/castmate-satellite/src/renderer/theme/theme-base/_colors.scss @@ -0,0 +1,18 @@ +:root { + @if variable-exists(colors) { + @each $name, $color in $colors { + @for $i from 0 through 5 { + @if ($i == 0) { + --#{$name}-50:#{tint($color, (5 - $i) * 19%)}; + } + @else { + --#{$name}-#{$i * 100}:#{tint($color, (5 - $i) * 19%)}; + } + } + + @for $i from 1 through 4 { + --#{$name}-#{($i + 5) * 100}:#{shade($color, $i * 15%)}; + } + } + } +} \ No newline at end of file diff --git a/packages/castmate-satellite/src/renderer/theme/theme-base/_common.scss b/packages/castmate-satellite/src/renderer/theme/theme-base/_common.scss new file mode 100644 index 00000000..c33bdc2a --- /dev/null +++ b/packages/castmate-satellite/src/renderer/theme/theme-base/_common.scss @@ -0,0 +1,198 @@ +// core +.p-component, .p-component * { + box-sizing: border-box; +} + +.p-hidden-space { + visibility: hidden; +} + +.p-reset { + margin: 0; + padding: 0; + border: 0; + outline: 0; + text-decoration: none; + font-size: 100%; + list-style: none; +} + +.p-disabled, .p-disabled * { + cursor: default; + pointer-events: none; + user-select: none; +} + +.p-component-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.p-unselectable-text { + user-select: none; +} + +.p-sr-only { + border: 0; + clip: rect(1px, 1px, 1px, 1px); + clip-path: inset(50%); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; + word-wrap: normal; +} + +.p-link { + text-align: left; + background-color: transparent; + margin: 0; + padding: 0; + border: none; + cursor: pointer; + user-select: none; +} + +.p-link:disabled { + cursor: default; +} + +/* Non vue overlay animations */ +.p-connected-overlay { + opacity: 0; + transform: scaleY(0.8); + transition: transform .12s cubic-bezier(0, 0, 0.2, 1), opacity .12s cubic-bezier(0, 0, 0.2, 1); +} + +.p-connected-overlay-visible { + opacity: 1; + transform: scaleY(1); +} + +.p-connected-overlay-hidden { + opacity: 0; + transform: scaleY(1); + transition: opacity .1s linear; +} + +/* Vue based overlay animations */ +.p-connected-overlay-enter-from { + opacity: 0; + transform: scaleY(0.8); +} + +.p-connected-overlay-leave-to { + opacity: 0; +} + +.p-connected-overlay-enter-active { + transition: transform .12s cubic-bezier(0, 0, 0.2, 1), opacity .12s cubic-bezier(0, 0, 0.2, 1); +} + +.p-connected-overlay-leave-active { + transition: opacity .1s linear; +} + +/* Toggleable Content */ +.p-toggleable-content-enter-from, +.p-toggleable-content-leave-to { + max-height: 0; +} + +.p-toggleable-content-enter-to, +.p-toggleable-content-leave-from { + max-height: 1000px; +} + +.p-toggleable-content-leave-active { + overflow: hidden; + transition: max-height 0.45s cubic-bezier(0, 1, 0, 1); +} + +.p-toggleable-content-enter-active { + overflow: hidden; + transition: max-height 1s ease-in-out; +} + +// theme +* { + box-sizing: border-box; +} + +.p-component { + font-family: var(--font-family); + font-feature-settings: var(--font-feature-settings, normal); + font-size: $fontSize; + font-weight: $fontWeight; +} + +.p-component-overlay { + background-color: $maskBg; + transition-duration: $transitionDuration; +} + +.p-disabled, .p-component:disabled { + opacity: $disabledOpacity; +} + +.p-error { + color: $errorColor; +} + +.p-text-secondary { + color: $textSecondaryColor; +} + +.pi { + font-size: $primeIconFontSize; +} + +.p-icon { + width: $primeIconFontSize; + height: $primeIconFontSize; +} + +.p-link { + font-family: var(--font-family); + font-feature-settings: var(--font-feature-settings, normal); + font-size: $fontSize; + border-radius: $borderRadius; + outline-color: transparent; + + &:focus-visible { + @include focused(); + } +} + +.p-component-overlay-enter { + animation: p-component-overlay-enter-animation 150ms forwards; +} + +.p-component-overlay-leave { + animation: p-component-overlay-leave-animation 150ms forwards; +} + +.p-component-overlay { + @keyframes p-component-overlay-enter-animation { + from { + background-color: transparent; + } + to { + background-color: var(--maskbg); + } + } + + @keyframes p-component-overlay-leave-animation { + from { + background-color: var(--maskbg); + } + to { + background-color: transparent; + } + } +} diff --git a/packages/castmate-satellite/src/renderer/theme/theme-base/_components.scss b/packages/castmate-satellite/src/renderer/theme/theme-base/_components.scss new file mode 100644 index 00000000..2648ed83 --- /dev/null +++ b/packages/castmate-satellite/src/renderer/theme/theme-base/_components.scss @@ -0,0 +1,111 @@ +@import '_mixins'; +@import '_colors'; + +@import './components/input/_editor'; + +@layer primevue { + @import '_common'; + + //Input + @import './components/input/_autocomplete'; + @import './components/input/_calendar'; + @import './components/input/_cascadeselect'; + @import './components/input/_checkbox'; + @import './components/input/_chips'; + @import './components/input/_colorpicker'; + @import './components/input/_dropdown'; + @import './components/input/_floatlabel'; + @import './components/input/_iconfield'; + @import './components/input/_inputgroup'; + @import './components/input/_inputicon'; + @import './components/input/_inputnumber'; + @import './components/input/_inputswitch'; + @import './components/input/_inputtext'; + @import './components/input/_knob'; + @import './components/input/_listbox'; + @import './components/input/_multiselect'; + @import './components/input/_password'; + @import './components/input/_radiobutton'; + @import './components/input/_rating'; + @import './components/input/_selectbutton'; + @import './components/input/_slider'; + @import './components/input/_textarea'; + @import './components/input/_treeselect'; + @import './components/input/_togglebutton'; + + //Button + @import './components/button/_button'; + @import './components/button/_speeddial'; + @import './components/button/_splitbutton'; + + //Data + @import './components/data/_carousel'; + @import './components/data/_datatable'; + @import './components/data/_dataview'; + @import './components/data/_filter'; + @import './components/data/_orderlist'; + @import './components/data/_organizationchart'; + @import './components/data/_paginator'; + @import './components/data/_picklist'; + @import './components/data/_timeline'; + @import './components/data/_tree'; + @import './components/data/_treetable'; + + //Panel + @import './components/panel/_accordion'; + @import './components/panel/_card'; + @import './components/panel/_fieldset'; + @import './components/panel/_divider'; + @import './components/panel/_panel'; + @import './components/panel/_scrollpanel'; + @import './components/panel/_splitter'; + @import './components/panel/_stepper'; + @import './components/panel/_tabview'; + @import './components/panel/_toolbar'; + + //Overlay + @import './components/overlay/_confirmpopup'; + @import './components/overlay/_dialog'; + @import './components/overlay/_overlaypanel'; + @import './components/overlay/_sidebar'; + @import './components/overlay/_tooltip'; + + //File + @import './components/file/_fileupload'; + + //Menu + @import './components/menu/_breadcrumb'; + @import './components/menu/_contextmenu'; + @import './components/menu/_dock'; + @import './components/menu/_megamenu'; + @import './components/menu/_menu'; + @import './components/menu/_menubar'; + @import './components/menu/_panelmenu'; + @import './components/menu/_steps'; + @import './components/menu/_tabmenu'; + @import './components/menu/_tieredmenu'; + + //Messages + @import './components/messages/_inlinemessage'; + @import './components/messages/_message'; + @import 'components/messages/toast'; + + //MultiMedia + @import './components/multimedia/_galleria'; + @import './components/multimedia/_image'; + + //Misc + @import './components/misc/_avatar'; + @import './components/misc/_badge'; + @import './components/misc/_blockui'; + @import './components/misc/_chip'; + @import './components/misc/_inplace'; + @import './components/misc/_metergroup'; + @import './components/misc/_progressbar'; + @import './components/misc/_progressspinner'; + @import './components/misc/_ripple'; + @import './components/misc/_scrolltop'; + @import './components/misc/_skeleton'; + @import './components/misc/_tag'; + @import './components/misc/_terminal'; +} \ No newline at end of file diff --git a/packages/castmate-satellite/src/renderer/theme/theme-base/_mixins.scss b/packages/castmate-satellite/src/renderer/theme/theme-base/_mixins.scss new file mode 100644 index 00000000..0a63f64b --- /dev/null +++ b/packages/castmate-satellite/src/renderer/theme/theme-base/_mixins.scss @@ -0,0 +1,278 @@ +@mixin icon-override($icon) { + &:before { + content: $icon; + } +} + +@mixin focused() { + outline: $focusOutline; + outline-offset: $focusOutlineOffset; + box-shadow: $focusShadow; +} + +@mixin focused-inset() { + outline: $focusOutline; + outline-offset: -1 * $focusOutlineOffset; + box-shadow: inset $focusShadow; +} + +@mixin focused-input() { + outline: $focusOutline; + outline-offset: $inputFocusOutlineOffset; + box-shadow: $focusShadow; + border-color: $inputFocusBorderColor; +} + +@mixin focused-listitem() { + outline: $focusOutline; + outline-offset: $focusOutlineOffset; + box-shadow: $inputListItemFocusShadow; +} + +@mixin invalid-input() { + border-color: $inputErrorBorderColor; +} + +@mixin menuitem { + margin: $inputListItemMargin; + + &:first-child { + margin-top: 0; + } + + &:last-child { + margin-bottom: 0; + } + + > .p-menuitem-content { + color: $menuitemTextColor; + transition: $listItemTransition; + border-radius: $menuitemBorderRadius; + + .p-menuitem-link { + color: $menuitemTextColor; + padding: $menuitemPadding; + user-select: none; + + .p-menuitem-text { + color: $menuitemTextColor; + } + + .p-menuitem-icon { + color: $menuitemIconColor; + margin-right: $inlineSpacing; + } + + .p-submenu-icon { + color: $menuitemIconColor; + } + } + } + + &.p-highlight { + > .p-menuitem-content { + color: $menuitemTextActiveColor; + background: $menuitemActiveBg; + + .p-menuitem-link { + .p-menuitem-text { + color: $menuitemTextActiveColor; + } + + .p-menuitem-icon, .p-submenu-icon { + color: $menuitemIconActiveColor; + } + } + } + + &.p-focus { + > .p-menuitem-content { + background: $menuitemActiveFocusBg; + } + } + } + + &:not(.p-highlight):not(.p-disabled) { + &.p-focus { + > .p-menuitem-content { + color: $menuitemTextHoverColor; + background: $menuitemHoverBg; + + .p-menuitem-link { + .p-menuitem-text { + color: $menuitemTextHoverColor; + } + + .p-menuitem-icon, .p-submenu-icon { + color: $menuitemTextHoverColor; + } + } + + &:hover { + color: $menuitemTextHoverColor; + background: $menuitemHoverBg; + + .p-menuitem-link { + .p-menuitem-text { + color: $menuitemTextHoverColor; + } + + .p-menuitem-icon, .p-submenu-icon { + color: $menuitemIconHoverColor; + } + } + } + } + } + + > .p-menuitem-content { + &:hover { + color: $menuitemTextHoverColor; + background: $menuitemHoverBg; + + .p-menuitem-link { + .p-menuitem-text { + color: $menuitemTextHoverColor; + } + + .p-menuitem-icon, .p-submenu-icon { + color: $menuitemIconHoverColor; + } + } + } + } + } +} + +@mixin horizontal-rootmenuitem { + > .p-menuitem-content { + color: $horizontalMenuRootMenuitemTextColor; + transition: $listItemTransition; + border-radius: $horizontalMenuRootMenuitemBorderRadius; + + .p-menuitem-link { + padding: $horizontalMenuRootMenuitemPadding; + user-select: none; + + .p-menuitem-text { + color: $horizontalMenuRootMenuitemTextColor; + } + + .p-menuitem-icon { + color: $horizontalMenuRootMenuitemIconColor; + margin-right: $inlineSpacing; + } + + .p-submenu-icon { + color: $horizontalMenuRootMenuitemIconColor; + margin-left: $inlineSpacing; + } + } + } + + &:not(.p-highlight):not(.p-disabled) { + > .p-menuitem-content { + &:hover { + color: $horizontalMenuRootMenuitemTextHoverColor; + background: $horizontalMenuRootMenuitemHoverBg; + + .p-menuitem-link { + .p-menuitem-text { + color: $horizontalMenuRootMenuitemTextHoverColor; + } + + .p-menuitem-icon, .p-submenu-icon { + color: $horizontalMenuRootMenuitemIconHoverColor; + } + } + } + } + } +} + +@mixin placeholder { + ::-webkit-input-placeholder { + @content + } + :-moz-placeholder { + @content + } + ::-moz-placeholder { + @content + } + :-ms-input-placeholder { + @content + } +} + +@mixin scaledPadding($val, $scale) { + padding: nth($val, 1) * $scale nth($val, 2) * $scale; +} + +@mixin scaledFontSize($val, $scale) { + font-size: $val * $scale; +} + +@mixin nested-submenu-indents($val, $index, $length) { + .p-submenu-list { + .p-menuitem { + .p-menuitem-content { + .p-menuitem-link { + padding-left: $val * ($index + 1); + } + + } + @if $index < $length { + @include nested-submenu-indents($val, $index + 2, $length); + } + } + } +} + +@mixin action-icon($enabled: true) { + width: $actionIconWidth; + height: $actionIconHeight; + color: $actionIconColor; + border: $actionIconBorder; + background: $actionIconBg; + border-radius: $actionIconBorderRadius; + transition: $actionIconTransition; + outline-color: transparent; + + @if $enabled { + &:enabled:hover { + @include action-icon-hover(); + } + } @else { + &:hover { + @include action-icon-hover(); + } + } + + &:focus-visible { + @include focused(); + } +} + +@mixin action-icon-hover() { + color: $actionIconHoverColor; + border-color: $actionIconHoverBorderColor; + background: $actionIconHoverBg; +} + +@mixin button-states { + //