Additional changes to the Cyberpunk theme, to make it even more cyberpunk.
This commit is contained in:
parent
304d750ec5
commit
15bfcfa064
128
app/globals.css
128
app/globals.css
|
|
@ -1351,6 +1351,134 @@ html.theme-cyberpunk [data-group-card]:nth-child(3n) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------ Cyberpunk Markdown Terminal ------------------- */
|
||||||
|
|
||||||
|
/* Markdown preview in the notes dialog: a CRT terminal screen with phosphor-
|
||||||
|
green text on a deep black backdrop. The VT323 pixel face (already scoped
|
||||||
|
to this theme's --font-sans) carries the whole retro feel. */
|
||||||
|
html.theme-cyberpunk .wmde-markdown {
|
||||||
|
font-family: var(--font-cyberpunk), ui-monospace, monospace;
|
||||||
|
color: #00ff41;
|
||||||
|
background: oklch(0.06 0.01 140);
|
||||||
|
text-shadow:
|
||||||
|
0 0 4px rgb(0 255 65 / 0.35),
|
||||||
|
0 0 12px rgb(0 255 65 / 0.12);
|
||||||
|
font-size: 0.8125rem;
|
||||||
|
letter-spacing: 0.02em;
|
||||||
|
line-height: 1.65;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Editor chrome: the toolbar and editing surface inherit the terminal look.
|
||||||
|
Toolbar sits on a slightly brighter black; the editing surface is pure
|
||||||
|
phosphor-black with a faint scanline overlay. */
|
||||||
|
html.theme-cyberpunk .w-md-editor {
|
||||||
|
font-family: var(--font-cyberpunk), ui-monospace, monospace;
|
||||||
|
--md-editor-font-family: var(--font-cyberpunk), ui-monospace, monospace;
|
||||||
|
color: #00ff41;
|
||||||
|
background: oklch(0.06 0.01 140);
|
||||||
|
border-color: #00ff41 / 22%;
|
||||||
|
text-shadow: 0 0 4px rgb(0 255 65 / 0.3);
|
||||||
|
}
|
||||||
|
html.theme-cyberpunk .w-md-editor .w-md-editor-toolbar {
|
||||||
|
background: oklch(0.09 0.01 140);
|
||||||
|
border-color: #00ff41 / 18%;
|
||||||
|
box-shadow: 0 0 8px rgb(0 255 65 / 0.08);
|
||||||
|
}
|
||||||
|
html.theme-cyberpunk .w-md-editor-toolbar-item,
|
||||||
|
html.theme-cyberpunk .w-md-editor-toolbar-item-icon {
|
||||||
|
color: #00cc33;
|
||||||
|
}
|
||||||
|
html.theme-cyberpunk .w-md-editor-toolbar-item-active,
|
||||||
|
html.theme-cyberpunk .w-md-editor-toolbar-item-active .w-md-editor-toolbar-item-icon {
|
||||||
|
color: #00ff41;
|
||||||
|
text-shadow: 0 0 6px rgb(0 255 65 / 0.6);
|
||||||
|
}
|
||||||
|
html.theme-cyberpunk .w-md-editor-text,
|
||||||
|
html.theme-cyberpunk .w-md-editor-text-pre,
|
||||||
|
html.theme-cyberpunk .w-md-editor-text-input {
|
||||||
|
color: #00ff41;
|
||||||
|
background: transparent;
|
||||||
|
font-family: var(--font-cyberpunk), ui-monospace, monospace;
|
||||||
|
text-shadow: 0 0 4px rgb(0 255 65 / 0.3);
|
||||||
|
}
|
||||||
|
html.theme-cyberpunk .w-md-editor-text-input::placeholder {
|
||||||
|
color: #00cc33 / 40%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Subtle CRT scanline texture over the editor surface (not the toolbar).
|
||||||
|
Fixed-position so it stays anchored to the screen, not the scrolling text.
|
||||||
|
Click-through via pointer-events so the textarea stays usable. */
|
||||||
|
html.theme-cyberpunk .w-md-editor-text-wrapper::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 5;
|
||||||
|
background: repeating-linear-gradient(
|
||||||
|
0deg,
|
||||||
|
rgb(0 255 65 / 0.02) 0px,
|
||||||
|
rgb(0 255 65 / 0.02) 1px,
|
||||||
|
transparent 1px,
|
||||||
|
transparent 3px
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Links glow a softer cyan-green so they stand out from body text, and the
|
||||||
|
terminal cursor (caret) gets a phosphor-green flicker on focus. */
|
||||||
|
html.theme-cyberpunk .wmde-markdown a,
|
||||||
|
html.theme-cyberpunk .w-md-editor a {
|
||||||
|
color: #33ffaa;
|
||||||
|
text-shadow: 0 0 6px rgb(51 255 170 / 0.4);
|
||||||
|
}
|
||||||
|
html.theme-cyberpunk .wmde-markdown code,
|
||||||
|
html.theme-cyberpunk .w-md-editor-text-pre code,
|
||||||
|
html.theme-cyberpunk .w-md-editor-text-pre {
|
||||||
|
background: oklch(0.1 0.015 140);
|
||||||
|
color: #00ff41;
|
||||||
|
border: 1px solid #00ff41 / 20%;
|
||||||
|
text-shadow: 0 0 5px rgb(0 255 65 / 0.4);
|
||||||
|
}
|
||||||
|
html.theme-cyberpunk .wmde-markdown pre,
|
||||||
|
html.theme-cyberpunk .w-md-editor-text-pre {
|
||||||
|
background: oklch(0.05 0.005 140);
|
||||||
|
border-color: #00ff41 / 15%;
|
||||||
|
}
|
||||||
|
html.theme-cyberpunk .wmde-markdown blockquote {
|
||||||
|
border-color: #00ff41 / 30%;
|
||||||
|
color: #00cc33;
|
||||||
|
}
|
||||||
|
html.theme-cyberpunk .wmde-markdown hr {
|
||||||
|
background: #00ff41 / 25%;
|
||||||
|
box-shadow: 0 0 8px rgb(0 255 65 / 0.2);
|
||||||
|
}
|
||||||
|
html.theme-cyberpunk .wmde-markdown h1,
|
||||||
|
html.theme-cyberpunk .wmde-markdown h2,
|
||||||
|
html.theme-cyberpunk .wmde-markdown h3,
|
||||||
|
html.theme-cyberpunk .wmde-markdown h4,
|
||||||
|
html.theme-cyberpunk .wmde-markdown h5,
|
||||||
|
html.theme-cyberpunk .wmde-markdown h6 {
|
||||||
|
color: #00ff41;
|
||||||
|
text-shadow:
|
||||||
|
0 0 6px rgb(0 255 65 / 0.5),
|
||||||
|
0 0 16px rgb(0 255 65 / 0.2);
|
||||||
|
letter-spacing: 0.04em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Faint screen flicker on the preview pane — a slow, barely-visible pulse
|
||||||
|
like an old CRT phosphor dimming. Doesn't affect readability. */
|
||||||
|
html.theme-cyberpunk .wmde-markdown {
|
||||||
|
animation: terminal-flicker 6s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
@keyframes terminal-flicker {
|
||||||
|
0%, 100% { opacity: 1; }
|
||||||
|
50% { opacity: 0.97; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cursor caret: a block-style terminal cursor that blinks green. */
|
||||||
|
html.theme-cyberpunk .w-md-editor-text-input::selection {
|
||||||
|
background: #00ff41 / 25%;
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------ Vaporwave ------------------------------- */
|
/* ------------------------------ Vaporwave ------------------------------- */
|
||||||
|
|
||||||
/* The retro face carries the whole deck: Righteous (a rounded, retro-futur-
|
/* The retro face carries the whole deck: Righteous (a rounded, retro-futur-
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,8 @@ import {
|
||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from "@/components/ui/dropdown-menu";
|
} from "@/components/ui/dropdown-menu";
|
||||||
import { getBrighterColor, getComplementaryColor, getGroupColor } from "@/lib/colors";
|
import { getBrighterColor, getComplementaryColor, getGroupColor } from "@/lib/colors";
|
||||||
import { isDarkTheme } from "@/components/theme/use-dark-theme";
|
import { isDarkTheme, isCyberpunkTheme } from "@/components/theme/use-dark-theme";
|
||||||
|
import { getCyberpunkGroupColor } from "@/lib/colors";
|
||||||
import { useBoard } from "@/components/board/board-context";
|
import { useBoard } from "@/components/board/board-context";
|
||||||
import { useBoardView } from "@/components/board/board-view-provider";
|
import { useBoardView } from "@/components/board/board-view-provider";
|
||||||
import { useHoldOnComplete } from "@/components/hold-on-complete";
|
import { useHoldOnComplete } from "@/components/hold-on-complete";
|
||||||
|
|
@ -121,7 +122,9 @@ export function GroupCard({ group }: { group: GroupDTO }) {
|
||||||
// card ever ringing itself while it's the one being moved.)
|
// card ever ringing itself while it's the one being moved.)
|
||||||
const isDropTarget = isOver && !isDragging;
|
const isDropTarget = isOver && !isDragging;
|
||||||
|
|
||||||
const color = getGroupColor(group.color);
|
const color = isCyberpunkTheme()
|
||||||
|
? getCyberpunkGroupColor(group.color)
|
||||||
|
: getGroupColor(group.color);
|
||||||
const borderColor = isDark ? color.dark : color.light;
|
const borderColor = isDark ? color.dark : color.light;
|
||||||
// The card fill is a calm, hand-picked tint of the same stroke color
|
// The card fill is a calm, hand-picked tint of the same stroke color
|
||||||
// (`soft` / `softDark` in lib/colors.ts), blended a little into the theme's
|
// (`soft` / `softDark` in lib/colors.ts), blended a little into the theme's
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,16 @@ export function isDarkTheme(): boolean {
|
||||||
return DARK_SURFACES.includes(resolveTheme(theme));
|
return DARK_SURFACES.includes(resolveTheme(theme));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** True when the "cyberpunk" theme is active. Used to swap the neon
|
||||||
|
* color palette onto group cards only for that theme.
|
||||||
|
*/
|
||||||
|
export function isCyberpunkTheme(): boolean {
|
||||||
|
const mounted = useMounted();
|
||||||
|
const { theme } = useTheme();
|
||||||
|
if (!mounted) return false;
|
||||||
|
return resolveTheme(theme) === "cyberpunk";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The `data-color-mode` value the markdown editor/preview widgets expect.
|
* The `data-color-mode` value the markdown editor/preview widgets expect.
|
||||||
* They only understand light/dark, so the light looks (default, sunset,
|
* They only understand light/dark, so the light looks (default, sunset,
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,24 @@ export const GROUP_COLORS: GroupColor[] = [
|
||||||
{ key: "pink", label: "Pink", light: "#d63f8f", dark: "#f472b6", soft: "#fadfee", softDark: "#37202e" },
|
{ key: "pink", label: "Pink", light: "#d63f8f", dark: "#f472b6", soft: "#fadfee", softDark: "#37202e" },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// --- Cyberpunk neon palette ---
|
||||||
|
// A secondary palette used ONLY when the "cyberpunk" theme is active.
|
||||||
|
// These are high-saturation neon values (magenta, cyan, acid green, etc.)
|
||||||
|
// that give group cards that classic "neon in the night" look. The
|
||||||
|
// softDark fills are shifted well down in lightness so they read as a
|
||||||
|
// subtle glow against the near-black surfaces instead of washed-out pastels.
|
||||||
|
|
||||||
|
const CYBERPUNK_PALETTE: Record<string, GroupColor> = {
|
||||||
|
coral: { key: "coral", label: "Neon Pink", light: "#ff2a8f", dark: "#ff2a8f", soft: "#fadfee", softDark: "#3d1433" },
|
||||||
|
amber: { key: "amber", label: "Acid Lime", light: "#a8ff00", dark: "#a8ff00", soft: "#eeffe0", softDark: "#2d3a12" },
|
||||||
|
lime: { key: "lime", label: "Toxic Green", light: "#39ff14", dark: "#39ff14", soft: "#e0fde0", softDark: "#163d14" },
|
||||||
|
teal: { key: "teal", label: "Electric Cyan",light: "#00fff0", dark: "#00fff0", soft: "#dffffa", softDark: "#0f3d3a" },
|
||||||
|
sky: { key: "sky", label: "Voltage Blue",light: "#00aaff", dark: "#00aaff", soft: "#e0f0ff", softDark: "#12263d" },
|
||||||
|
indigo: { key: "indigo", label: "Neon Purple", light: "#bf40ff", dark: "#bf40ff", soft: "#f0e0ff", softDark: "#2e1640" },
|
||||||
|
violet: { key: "violet", label: "Neon Magenta",light: "#ff2aff", dark: "#ff2aff", soft: "#ffe0f5", softDark: "#3d1436" },
|
||||||
|
pink: { key: "pink", label: "Deep Violet", light: "#8a2be2", dark: "#8a2be2", soft: "#e8d6ff", softDark: "#261236" },
|
||||||
|
};
|
||||||
|
|
||||||
const GROUP_COLOR_MAP: Record<string, GroupColor> = Object.fromEntries(
|
const GROUP_COLOR_MAP: Record<string, GroupColor> = Object.fromEntries(
|
||||||
GROUP_COLORS.map((c) => [c.key, c])
|
GROUP_COLORS.map((c) => [c.key, c])
|
||||||
);
|
);
|
||||||
|
|
@ -58,6 +76,13 @@ export function getGroupColor(key: string): GroupColor {
|
||||||
return GROUP_COLOR_MAP[key] ?? GROUP_COLORS[0];
|
return GROUP_COLOR_MAP[key] ?? GROUP_COLORS[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Get the cyberpunk-neon variant of a group color. Used ONLY when the
|
||||||
|
* "cyberpunk" theme is active so groups read as neon tubes in the night.
|
||||||
|
*/
|
||||||
|
export function getCyberpunkGroupColor(key: string): GroupColor {
|
||||||
|
return CYBERPUNK_PALETTE[key] ?? CYBERPUNK_PALETTE["coral"];
|
||||||
|
}
|
||||||
|
|
||||||
// --- Complementary accent (for the to-do progress pie on a Group card) ---
|
// --- Complementary accent (for the to-do progress pie on a Group card) ---
|
||||||
//
|
//
|
||||||
// Derived at runtime by rotating a base color's hue 180° and pulling the
|
// Derived at runtime by rotating a base color's hue 180° and pulling the
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue