import {defineSlotRecipe, createSystem, defaultConfig, defineConfig, defineRecipe} from "@chakra-ui/react"; // RECIPES const headerRecipe = defineRecipe({ base: { bg: "{transparent}", color: "text", width: "100%", height: "100%", display: "flex", flexDirection: "row", justifyContent: "space-between", alignItems: "center", } }); const sidebarRecipe = defineSlotRecipe({ slots: ["root", "logo", "footer", "button_text","buttons", "collapse_button"], base: { root: { // 1. Semi-transparent backgrounds bg: { base: "linear-gradient(to bottom right, #99000040 20%, #FF660040 60%, #EEEE0040 100%)", _dark: "linear-gradient(to bottom right, #9900003C 20%, #FF66003C 60%, #FFC0003C 100%)" }, // 2. The glass blur effect backdropFilter: "blur(12px)", WebkitBackdropFilter: "blur(12px)", // 3. Subtle semi-transparent borders border: "1px solid", borderColor: {base: "rgba(255, 255, 255, 0.8)", _dark: "rgba(255, 255, 255, 0.1)"}, // CRITICAL: Remove the right border so it doesn't draw a line through your cutout borderRight: "none", borderRadius: "2xl", // boxShadow: "0 4px 30px rgba(0, 0, 0, 0.1)", // boxShadow: "-10px 4px 30px rgba(0, 0, 0, 0.1)", width: "100%", height: "calc(100% - 16px)", margin: "8px", display: "flex", flexDirection: "column", position: "relative", justifyContent: "start", alignItems: "stretch", gap: 4, transition: "width 0.4s ease", // CRITICAL: Adjust padding and overflow to allow the button to touch the right edge pl: 2, // Keep left padding py: 2, // Keep top/bottom padding pr: 0, // Remove right padding pt: 4, // Added top padding to give the logo room to breathe overflow: "visible", // Allows the curved corner patches to render outside the button zIndex: 10, }, buttons: { position: "relative", // Required to anchor the corner patches bg: "transparent", justifyContent: "flex-start", transition: "background-color 0.4s ease, color 0.4s ease", "& svg": { transition: "stroke-width 0.4s ease", flexShrink: "0" }, _hover: { bg: "rgba(255, 255, 255, 0.1)", color: "{text}", fontWeight: "semibold", "& svg": { strokeWidth: "3" } }, fontSize: "l", color: {base: "{text}"}, variant: "ghost", width: "100%", // Flat on the right, rounded on the left borderRightRadius: "0", borderLeftRadius: "4xl", "&.active": { bg: "{MainBackground}", color: "{textInverted}", _hover: { bg: "{MainBackground}", color: "{textInverted}", fontWeight: "normal", "& svg": { strokeWidth: "2" // Keeps the active icon at normal thickness on hover } }, // The Top Inverted Curve _before: { content: '""', position: "absolute", right: "-1px", top: "-25px", width: "25px", height: "25px", bg: "inherit", WebkitMaskImage: "radial-gradient(circle at top left, transparent 25px, black 25.5px)", maskImage: "radial-gradient(circle at top left, transparent 25px, black 25.5px)", pointerEvents: "none", }, // The Bottom Inverted Curve _after: { content: '""', position: "absolute", right: "-1px", bottom: "-25px", width: "25px", height: "25px", bg: "inherit", WebkitMaskImage: "radial-gradient(circle at bottom left, transparent 25px, black 25.5px)", maskImage: "radial-gradient(circle at bottom left, transparent 25px, black 25.5px)", pointerEvents: "none", } }, }, logo: { width: "100%", height: "auto", overflow: "hidden", fontWeight: "bold", px: 0, }, footer: { mt: "auto", display: "flex", justifyContent: "center", alignItems: "center", pb: 4, pr: 2, transition: "opacity 0.3s ease, visibility 0.3s ease, margin 0.3s ease" }, button_text: { transition: "opacity 0.3s ease, visibility 0.3s ease, margin 0.3s ease", whiteSpace: "nowrap" }, collapse_button: { "& svg": { flexShrink: "0" }, }, }, variants: { state: { open: { root: { width: "190px" }, logo: { justifyContent: "flex-start", ml: 2, textStyle: "4xl" }, footer: { gap: 16, flexDirection: "row" }, button_text: {ml: 3, opacity: 1, visibility: "visible"}, }, closed: { root: { width: "71px" }, logo: { justifyContent: "center", ml: -1, textStyle: "3xl" }, footer: { gap: 2, flexDirection: "column-reverse" }, button_text: {ml: 0, opacity: 0, visibility: "hidden"}, } } } }); const dashboardRecipe = defineRecipe({ base: { bg: "{MainBackground}" } }); const canvasRecipe = defineRecipe({ base: { bg: "{transparent}", zIndex: "-1", color: "{text}" } }); const widgetRecipe = defineSlotRecipe({ slots: ["root", "header", "canvas"], base: { root: { flexDirection: "column", gap: "1", position: "relative", bg: "base100", borderRadius: "md", p: "1", paddingBottom: "2", border: "1px solid", borderColor: "{base300}", textAlign: "center", height: "100%", position: "fixed" }, header: { flexShrink: "0", bg: "{base300}", color: "{text}", cursor: "move", borderRadius: "sm", whiteSpace: "nowrap", textAlign: "left", pl: "2" }, canvas: { flex: "1 1 auto", bg: "transparent", color: "{text}", cursor: "default", borderRadius: "md", overflow: "auto", } } }); const glassPanelRecipe = defineSlotRecipe({ slots: ["root", "header", "body"], // 🧊 THE GLASS MATH (Applies to everything) base: { root: { display: "flex", flexDirection: "column", position: "relative", overflow: "hidden", bg: {base: "rgba(255, 255, 255, 0.4)", _dark: "rgba(255, 255, 255, 0.04)"}, backdropFilter: "blur(12px)", WebkitBackdropFilter: "blur(12px)", border: "1px solid", borderColor: {base: "gray.200", _dark: "whiteAlpha.200"}, boxShadow: "sm", } }, // 📏 THE LAYOUTS (Applies selectively) variants: { layout: { widget: { root: {width: "100%", height: "100%", borderRadius: "3xl"}, header: {display: "flex", justifyContent: "space-between", alignItems: "center", px: 3, pt: 2, pb: 0}, body: {flex: "1", overflow: "hidden", position: "relative", px: 1, pb: 1, pt: 0} }, dropdown: { root: {borderRadius: "xl", p: 1} // (Header and body slots are ignored here because dropdowns don't use them) }, popover: { root: { borderRadius: "2xl", p: 4, boxShadow: "xl", minW: "240px", // OVERRIDES: Make the background 85-90% opaque instead of 40% bg: { base: "rgba(255, 255, 255, 0.75)", _dark: "rgba(20, 22, 25, 0.8)" }, // OVERRIDES: Increase the blur just to smooth out any stubborn gridlines backdropFilter: "blur(15px)", WebkitBackdropFilter: "blur(15px)", } } }, mode: { editing: { root: { boxShadow: "outline", borderStyle: "dashed", borderWidth: "2px", borderColor: "orange.300", cursor: "grab", } } } }, defaultVariants: { layout: "widget" } }); const glassTabRecipe = defineRecipe({ base: { display: "flex", alignItems: "center", height: "40px", // The Circle State (Inactive) maxWidth: "40px", minWidth: "40px", px: "8px", gap: 2, // CRITICAL: Locks the shape to a perfect circle/pill borderRadius: "full", overflow: "hidden", whiteSpace: "nowrap", textDecoration: "none", fontWeight: "bold", color: "fg.muted", // --- THE GLASS EFFECT (Inactive) --- // Uses a highly transparent white/black depending on mode bg: {base: "rgba(255, 255, 255, 0.4)", _dark: "rgba(255, 255, 255, 0.03)"}, backdropFilter: "blur(12px)", WebkitBackdropFilter: "blur(12px)", border: "1px solid", borderColor: {base: "rgba(0, 0, 0, 0.05)", _dark: "rgba(255, 255, 255, 0.08)"}, boxShadow: "0 4px 6px rgba(0, 0, 0, 0.02)", // Tiny shadow to lift it off the canvas transition: "all 0.85s cubic-bezier(0.34, 1.56, 0.64, 1)", "&:hover, &[data-state='open'], &[aria-expanded='true']": { maxWidth: "250px", pr: "16px", // --- THE GLASS EFFECT (Hover) --- // Becomes slightly more opaque when you mouse over bg: {base: "rgba(255, 255, 255, 0.8)", _dark: "rgba(255, 255, 255, 0.1)"}, borderColor: {base: "rgba(0, 0, 0, 0.1)", _dark: "rgba(255, 255, 255, 0.15)"}, color: "fg", textDecoration: "none", }, "&.active": { maxWidth: "250px", pr: "16px", bg: "{gooeyButtonBackground}", borderColor: "transparent", color: "{textInverted}", boxShadow: "0 4px 12px rgba(0, 0, 0, 0.1)", // Stronger shadow for the active tab _hover: { bg: "{gooeyButtonBackground}", cursor: "default", textDecoration: "none", } } } }); const config = defineConfig({ globalCss: { ".react-grid-placeholder": { background: "#c0d2e3ff !important", borderColor: "#a9b6c2ff !important", boxShadow: "0 0 10px #c0d2e3ff !important", opacity: "1 !important", borderRadius: "5px", _dark: { background: "#393c3fff !important", borderColor: "#000000ff !important", boxShadow: "0 0 10px #16181bff !important", opacity: "1 !important", }, }, ".react-resizable-handle-se": { zIndex: "1", }, "*": { scrollbarWidth: "thin", scrollbarColor: "#a0aec0 transparent", _dark: { scrollbarColor: "#474747ff transparent", } }, "::-webkit-scrollbar": { width: "8px", }, "::-webkit-scrollbar-thumb": { backgroundColor: "rgba(100, 100, 100, 0.4)", borderRadius: "4px", _dark: { backgroundColor: "rgba(35, 35, 35, 0.81)", } }, "::-webkit-scrollbar-track": { background: "transparent", }, // '.leaflet-tile': { // _dark: { // filter: "invert(100%) hue-rotate(180deg) brightness(95%) contrast(90%)", // } // }, '.leaflet-control-zoom-in, .leaflet-control-zoom-out, .leaflet-control-attribution, .leaflet-container': { _dark: { filter: "invert(100%) hue-rotate(180deg) brightness(95%) contrast(90%)", } }, '.leaflet-control-attribution': { _dark: { filter: "invert(100%) hue-rotate(180deg) brightness(95%) contrast(90%)", } }, '.leaflet-container': { fontFamily: "system-ui, sans-serif !important", _dark: { filter: "invert(100%) hue-rotate(180deg) brightness(95%) contrast(90%)", } }, // ".leaflet-popup-content": { // fontFamily: "georgia, system-ui, sans-serif !important" // }, // ".leaflet-control a": { // fontFamily: "georgia, system-ui, sans-serif !important" // }, // ".leaflet-tooltip": { // fontFamily: "georgia, system-ui, sans-serif !important" // }, ".react-grid-item": { transition: "none !important" }, }, theme: { semanticTokens: { colors: { base100: {value: {base: "#f6f9faff", _dark: "#1617199e"}}, base200: {value: {base: "#e6ecf1ff", _dark: "#242424"}}, base300: {value: {base: "#d3dae4ff", _dark: "#0a0b0bff"}}, primary: {value: {base: "#2B98F8", _dark: "#2B98F8"}}, primaryLt: {value: {base: "#98cdffff", _dark: "#98cdffff"}}, secondaryBG: {value: {base: "#EDF1F1", _dark: "#121212"}}, border: {value: {base: "#000000", _dark: "#cbcbcb84"}}, text: {value: {base: "#000000", _dark: "#FFFFFF"}}, textInverted: {value: {base: "#000000", _dark: "#FFFFFF"}}, icon: {value: {base: "#000000", _dark: "#FFFFFF"}}, gooeyButtonBackground: {value: {base: "rgba(255, 255, 255, 0.1)", _dark: "rgba(255, 255, 255, 0.1)"}}, MainBackground: {value: {base: "#F9F9F9", _dark: "#141414"}}, titleColor: {value: {base: "gray.800", _dark: "#FFFFFF"}}, iconColor: {value: {base: "gray.600", _dark: "#000000"}}, glassSeperator: {value: {base: "#0000001A", _dark: "#FFFFFF3F"}}, }, }, tokens: { fonts: { body: {value: "system-ui, sans-serif"}, }, }, recipes: { header: headerRecipe, dashboard: dashboardRecipe, canvas: canvasRecipe, glassTab: glassTabRecipe }, slotRecipes: { sidebar: sidebarRecipe, widget: widgetRecipe, glassPanel: glassPanelRecipe, }, }, }); export const system = createSystem(defaultConfig, config);