From a14df3f3b3239ab6ae76bb8fc51ec1a9cf871a66 Mon Sep 17 00:00:00 2001 From: dvorakmortonxd Date: Tue, 22 Sep 2026 15:36:04 +0200 Subject: [PATCH] FULL ON WEBSITE REMAKE --- public/gentoo.svg | 81 ++ src/app/components/AndroidHome.tsx | 90 +++ src/app/components/Clock.tsx | 41 +- src/app/components/IosHome.tsx | 77 -- src/app/components/TerminalLayout.tsx | 131 +-- src/app/components/ThemeRoot.tsx | 6 +- src/app/components/WinWindow.tsx | 73 +- src/app/components/WindowsDesktop.tsx | 251 ++++-- src/app/components/apps.tsx | 99 ++- src/app/page.css | 83 +- src/app/skeuo.css | 1056 ++++++++++++++++--------- 11 files changed, 1149 insertions(+), 839 deletions(-) create mode 100644 public/gentoo.svg create mode 100644 src/app/components/AndroidHome.tsx delete mode 100644 src/app/components/IosHome.tsx diff --git a/public/gentoo.svg b/public/gentoo.svg new file mode 100644 index 0000000..8e674a0 --- /dev/null +++ b/public/gentoo.svg @@ -0,0 +1,81 @@ + + + Gentoo Logo Vector + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Gentoo Logo Vector + + + Matteo 'Peach' Pescarin + + + + + + + Daniel Robbins as creator of the original logo + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/app/components/AndroidHome.tsx b/src/app/components/AndroidHome.tsx new file mode 100644 index 0000000..93f5dd6 --- /dev/null +++ b/src/app/components/AndroidHome.tsx @@ -0,0 +1,90 @@ +"use client"; + +import { useState } from "react"; +import { APPS, APP_BY_ID } from "./apps"; +import Clock from "./Clock"; +import { useTheme } from "./useTheme"; +import { WALLPAPER } from "../data"; + +const DOCK_IDS = ["projects", "services", "socials", "contributions"]; + +export default function AndroidHome() { + const { theme, toggle } = useTheme(); + const [openId, setOpenId] = useState(null); + const openApp = openId ? APP_BY_ID[openId] : null; + + const renderIcon = (appId: string, inDock = false) => { + const app = APP_BY_ID[appId]; + if (!app) return null; + return ( + + ); + }; + + return ( +
+ {openApp ? ( +
+
+ + {openApp.title} +
+
{openApp.content}
+
+ ) : ( +
+
+ + + + +
+ + + +
+
+ +
+
dvorakmortonxd.dev
+
+ +
{APPS.map((app) => renderIcon(app.id))}
+ +
{DOCK_IDS.map((id) => renderIcon(id, true))}
+ +
+ +
+
+ )} +
+ ); +} diff --git a/src/app/components/Clock.tsx b/src/app/components/Clock.tsx index 814afe5..2d9012b 100644 --- a/src/app/components/Clock.tsx +++ b/src/app/components/Clock.tsx @@ -1,9 +1,20 @@ "use client"; -import { useEffect, useState } from "react"; +import { useSyncExternalStore } from "react"; -function format(date: Date) { - return date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }); +function getTime(withSeconds: boolean) { + const now = new Date(); + return now.toLocaleTimeString( + [], + withSeconds + ? { hour: "2-digit", minute: "2-digit", second: "2-digit" } + : { hour: "2-digit", minute: "2-digit" } + ); +} + +function subscribe(callback: () => void) { + const id = window.setInterval(callback, 1000); + return () => window.clearInterval(id); } export default function Clock({ @@ -13,28 +24,12 @@ export default function Clock({ className?: string; withSeconds?: boolean; }) { - const [now, setNow] = useState(() => - typeof window === "undefined" ? null : new Date() + const text = useSyncExternalStore( + subscribe, + () => getTime(withSeconds), + () => "" ); - useEffect(() => { - const id = window.setInterval( - () => setNow(new Date()), - withSeconds ? 1000 : 10000 - ); - return () => window.clearInterval(id); - }, [withSeconds]); - - const text = now - ? withSeconds - ? now.toLocaleTimeString([], { - hour: "2-digit", - minute: "2-digit", - second: "2-digit", - }) - : format(now) - : ""; - return ( {text} diff --git a/src/app/components/IosHome.tsx b/src/app/components/IosHome.tsx deleted file mode 100644 index 54d70b7..0000000 --- a/src/app/components/IosHome.tsx +++ /dev/null @@ -1,77 +0,0 @@ -"use client"; - -import { useState } from "react"; -import { APPS, APP_BY_ID } from "./apps"; -import Clock from "./Clock"; -import { useTheme } from "./useTheme"; -import { WALLPAPER } from "../data"; - -export default function IosHome() { - const { theme, toggle } = useTheme(); - const [openId, setOpenId] = useState(null); - const openApp = openId ? APP_BY_ID[openId] : null; - - return ( -
- {/* iOS app view */} - {openApp ? ( -
-
- - {openApp.title} - -
-
{openApp.content}
-
- ) : ( -
-
- - - - -
- - - -
- {APPS.map((app) => ( - - ))} -
- -
-
-
- )} -
- ); -} diff --git a/src/app/components/TerminalLayout.tsx b/src/app/components/TerminalLayout.tsx index c5d3ab2..3870c06 100644 --- a/src/app/components/TerminalLayout.tsx +++ b/src/app/components/TerminalLayout.tsx @@ -4,7 +4,6 @@ import SlBackground from "./SlBackground"; import JokerLogo from "./JokerLogo"; import ServiceButton from "./ServiceButton"; import ContributionHeatmap from "./ContributionHeatmap"; -import Clock from "./Clock"; import { useTheme } from "./useTheme"; import { socials, codingProjects, techProjects, friends } from "../data"; @@ -16,7 +15,7 @@ const panelStyle = (color: string, style: CSSProperties = {}): PanelStyle => ({ }); export default function TerminalLayout() { - const { theme, toggle } = useTheme(); + const { toggle } = useTheme(); return ( <> @@ -26,6 +25,9 @@ export default function TerminalLayout() {

dvorakmortonxd.dev

+
@@ -44,31 +46,6 @@ export default function TerminalLayout() {

-
-
- - SEARXNG.C - -
- -
-
-
-
))}
- -
-

- Quipee by Bukovina Filip & Vlk Tomรกลก -

-
- Quipee Thumbnail -
- -
@@ -712,15 +598,6 @@ export default function TerminalLayout() { the GPL3.0 License) - -
- theme: terminal - - - -
); } diff --git a/src/app/components/ThemeRoot.tsx b/src/app/components/ThemeRoot.tsx index bc40e42..e6d1eae 100644 --- a/src/app/components/ThemeRoot.tsx +++ b/src/app/components/ThemeRoot.tsx @@ -3,7 +3,7 @@ import { useTheme } from "./useTheme"; import TerminalLayout from "./TerminalLayout"; import WindowsDesktop from "./WindowsDesktop"; -import IosHome from "./IosHome"; +import AndroidHome from "./AndroidHome"; export default function ThemeRoot() { const { theme } = useTheme(); @@ -17,8 +17,8 @@ export default function ThemeRoot() {
-
- +
+
); diff --git a/src/app/components/WinWindow.tsx b/src/app/components/WinWindow.tsx index 6f29396..d3bc6c8 100644 --- a/src/app/components/WinWindow.tsx +++ b/src/app/components/WinWindow.tsx @@ -1,6 +1,6 @@ "use client"; -import { useRef, type CSSProperties } from "react"; +import { type CSSProperties, type PointerEvent as ReactPointerEvent } from "react"; import type { AppDef } from "./apps"; export interface WinState { @@ -13,6 +13,7 @@ export interface WinState { z: number; minimized: boolean; maximized: boolean; + centered: boolean; } interface Props { @@ -36,17 +37,52 @@ export default function WinWindow({ onToggleMaximize, onMove, }: Props) { - const drag = useRef<{ sx: number; sy: number; ox: number; oy: number } | null>(null); - + const centered = win.centered && !win.maximized; const style: CSSProperties = win.maximized ? { left: 0, top: 0, width: "100%", height: "100%", zIndex: win.z } - : { left: win.x, top: win.y, width: win.w, height: win.h, zIndex: win.z }; + : centered + ? { width: win.w, height: win.h, zIndex: win.z } + : { left: win.x, top: win.y, width: win.w, height: win.h, zIndex: win.z }; + + const startDrag = (e: ReactPointerEvent) => { + onFocus(); + if (win.maximized) return; + if ((e.target as HTMLElement).closest(".win-controls")) return; + + e.preventDefault(); + let ox = win.x; + let oy = win.y; + if (win.centered) { + const node = e.currentTarget.closest(".win-window") as HTMLElement | null; + const rect = node?.getBoundingClientRect(); + if (rect) { + ox = rect.left; + oy = rect.top; + } + } + const sx = e.clientX; + const sy = e.clientY; + + const handleMove = (ev: PointerEvent) => { + onMove(ox + (ev.clientX - sx), oy + (ev.clientY - sy)); + }; + const handleUp = () => { + window.removeEventListener("pointermove", handleMove); + window.removeEventListener("pointerup", handleUp); + window.removeEventListener("pointercancel", handleUp); + }; + + window.addEventListener("pointermove", handleMove); + window.addEventListener("pointerup", handleUp); + window.addEventListener("pointercancel", handleUp); + }; return (
-
{ - onFocus(); - if (win.maximized) return; - if ((e.target as HTMLElement).closest(".win-controls")) return; - drag.current = { sx: e.clientX, sy: e.clientY, ox: win.x, oy: win.y }; - e.currentTarget.setPointerCapture(e.pointerId); - }} - onPointerMove={(e) => { - const d = drag.current; - if (!d) return; - onMove(d.ox + (e.clientX - d.sx), d.oy + (e.clientY - d.sy)); - }} - onPointerUp={(e) => { - drag.current = null; - try { - e.currentTarget.releasePointerCapture(e.pointerId); - } catch { - /* ignore */ - } - }} - > - +
{app.title} -
+
e.stopPropagation()}>
+ {/* Services - top right */} +
e.stopPropagation()} + > + {SERVICE_SHORTCUTS.map((s) => + s.appId ? ( + + ) : ( + + {s.icon} + {s.label} + + ) + )} +
+ + {/* Friends - bottom right */} +
e.stopPropagation()} + > + {FRIEND_SHORTCUTS.map((f) => ( + + + {f.label} + + {f.label} + + ))} +
+ {/* Windows */}
{wins.map((w) => ( @@ -163,52 +251,84 @@ export default function WindowsDesktop() { ))}
- {/* Start menu */} + {/* Application launcher */} {startOpen && ( -
e.stopPropagation()}> -
- ๐Ÿง‘โ€๐Ÿ’ป - Martin Dvoล™รกk -
-
- {APPS.map((app) => ( - - ))} -
-
- +
e.stopPropagation()}> +
+
Applications
+
+ {LEFT_APPS.map((app) => ( + + ))} + {SERVICE_SHORTCUTS.map((s) => + s.appId ? ( + + ) : ( + + {s.icon} + {s.label} + + ) + )} + {FRIEND_SHORTCUTS.map((f) => ( + + + {f.label} + + {f.label} + + ))} +
)} - {/* Taskbar */} + {/* Plasma panel */}
e.stopPropagation()}>
@@ -236,37 +356,24 @@ export default function WindowsDesktop() {
-
- - -
- -
diff --git a/src/app/components/apps.tsx b/src/app/components/apps.tsx index 00d4b3e..a44b4ed 100644 --- a/src/app/components/apps.tsx +++ b/src/app/components/apps.tsx @@ -12,6 +12,7 @@ import { import ServiceButton from "./ServiceButton"; import ContributionHeatmap from "./ContributionHeatmap"; import JokerLogo from "./JokerLogo"; +import { setTheme } from "./useTheme"; export interface AppDef { id: string; @@ -30,7 +31,7 @@ function WelcomeApp() {

Welcome to dvorakmortonxd.dev

-

A Windows 7 desktop edition of my personal website.

+

A KDE Plasma desktop edition of my personal website.

@@ -41,15 +42,27 @@ function WelcomeApp() {

  • Drag windows around by their title bar.
  • Use the buttons at the top-right to minimize, maximize or close.
  • -
  • Search the web from the taskbar at the bottom.
  • -
  • Switch back to the terminal theme from the tray, bottom-right.
  • +
  • Open apps from the Gentoo launcher, bottom-left.
  • +
  • Switch back to the Gruvbox theme from the panel tray, bottom-right.
+

+ If you'd prefer a normal website{" "} + + . +

Wallpaper from{" "} wallpaperaccess.com/open-source - . + . Gentoo logo by Matteo 'Peach' Pescarin (CC BY-SA 2.5), via Wikimedia + Commons.

); @@ -255,38 +268,6 @@ function FriendsApp() { /> ))}
- -
-

Quipee by Bukovina Filip & Vlk Tomรกลก

-
- Quipee Thumbnail -
- -
); } @@ -405,6 +386,50 @@ function RustyWolfApp() { ); } +const SIKE_ART = [ + " โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„ โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„ โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„ โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„ โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„", + " โ–„โ–€โ–€ โ–‘ โ–„ โ–“ โ–„ โ–“ โ–„ โ–ˆ โ–„โ–€ โ–‘ โ–‘โ–’โ–“โ–‘", + "โ–โ–Œ โ–„โ–„โ–„โ–„ โ–’โ–’ โ–ˆ โ–’ โ–ˆ โ–’ โ–’ โ–’โ–‘ โ–โ–Œ โ–‘โ–’โ–’", + "โ–ˆ โ–‘ โ–‘ โ–‘โ–“ โ–“ โ–‘ โ–“ โ–‘ โ–‘ โ–‘โ–’ โ–ˆ โ–‘โ–“", + "โ–’ โ–’ โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€ โ–’ โ–ˆ โ–’ โ–ˆ โ–ˆ โ–โ–Œ โ–“ โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–ˆ", + "โ–โ–Œ โ–€โ–„โ–„โ–„โ–„โ–„โ–„ โ–‘ โ–ˆ โ–‘ โ–ˆโ–„โ–„โ–ˆ โ–„โ–€ โ–‘ โ–“โ–„โ–„โ–„โ–„ ยท ", + " โ–€โ–„โ–„ โ”ผโ”ผโ–€โ–„ โ–ˆโ”ผ โ–ˆ โ–ˆโ”ผ โ–’ โ–ˆ โ”ผ โ–„โ–„โ–„โ–„โ–’ ยท", + " โ–€โ–€โ–€โ–€โ–€โ–„โ–„โ”ผโ”œโ”œโ”ผโ”œโ”œโ–Œ โ–ˆโ”ผ โ”ผโ–ˆ โ–ˆโ”ผ โ”ผโ–ˆโ–€โ–€โ–ˆโ”ผ โ–€โ–„ โ–ˆโ”ผโ”ผโ”ผ โ”ผโ–“โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„", + "โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–‘ โ–’โ”ผโ”œโ”œโ”ผโ”œโ”œโ–“ โ–ˆโ”ผโ”ผ โ”ผโ”ผโ–‘ โ–ˆโ”ผโ”ผ โ”ผโ”ผโ–‘ โ–ˆโ”ผ โ–โ–Œ โ–ˆโ”ผโ”ผโ”ผ โ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ–‘", + "โ–’โ”ผโ”ผโ”œโ”ผโ”ผโ”ผโ–’โ–„โ–„โ–“โ”ผโ”ผโ”œโ”ผโ”ผโ–โ–Œ โ–ˆโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ–’ โ–ˆโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ–’ โ–ˆโ”ผโ”ผโ”ผ โ”ผโ”ผโ–’ โ–โ–Œโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ–’", + "โ–‘โ”ผโ”œโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ–„โ–€ โ–ˆโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ–“ โ–ˆโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ–“ โ–ˆโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ–“ ยทโ–€โ–„โ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ”ผโ–“", + "โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€ โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€ โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€ โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€ โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€", +].join("\n"); + +function SikeTerminal() { + return ( +
+
+ martin@gentoo + ~ + $ ssh root@proxmox.dvorakmortonxd.dev +
+
{SIKE_ART}
+
+ martin@gentoo + ~ + $ +
+
+ ); +} + +export const ALACRITTY_APP: AppDef = { + id: "alacritty", + title: "Alacritty", + icon: ">_", + color: "#1d1f21", + width: 760, + height: 440, + content: , +}; + export const APPS: AppDef[] = [ { id: "welcome", title: "Welcome", icon: "๐Ÿ‘‹", color: "#2f7fc4", width: 620, height: 430, content: }, { id: "about", title: "About Me", icon: "๐Ÿง‘โ€๐Ÿ’ป", color: "#0d5aa7", width: 720, height: 470, content: }, @@ -422,5 +447,5 @@ export const APPS: AppDef[] = [ ]; export const APP_BY_ID: Record = Object.fromEntries( - APPS.map((a) => [a.id, a]) + [...APPS, ALACRITTY_APP].map((a) => [a.id, a]) ); diff --git a/src/app/page.css b/src/app/page.css index fef888d..826c6af 100644 --- a/src/app/page.css +++ b/src/app/page.css @@ -931,41 +931,6 @@ body { } } -/* ============================================ - SEARCH BAR - ============================================ */ -.search-section { - margin-top: 20px; -} - -.search-form { - display: flex; - padding: 20px 24px; -} - -.search-bar { - width: 100%; - padding: 12px 16px; - background: rgba(255, 255, 255, 0.05); /* very transparent */ - backdrop-filter: blur(10px) saturate(120%); - -webkit-backdrop-filter: blur(10px) saturate(120%); - border: 1px solid var(--tui-border); - color: var(--fg); - font-family: var(--font-custom-mono), monospace; - font-size: 1rem; - outline: none; - transition: all 0.3s ease; -} - -.search-bar:focus { - border-color: var(--red); - box-shadow: 0 0 10px rgba(74, 233, 52, 0.3); -} - -.search-bar::placeholder { - color: var(--gray); -} - /* Joker Animation */ .joker-flash-overlay { position: fixed; @@ -1270,56 +1235,22 @@ body { } /* ============================================ - TUI STATUS BAR (terminal theme) + HEADER THEME SWITCH (terminal theme) ============================================ */ -body { - padding-bottom: 44px; -} - -.tui-statusbar { - position: fixed; - left: 0; - right: 0; - bottom: 0; - z-index: 5000; - display: flex; - align-items: center; - gap: 12px; - padding: 8px 16px; - background: rgba(29, 32, 33, 0.92); - border-top: 1px solid var(--tui-border); - backdrop-filter: blur(12px); - -webkit-backdrop-filter: blur(12px); - font-family: var(--font-custom-mono), 'JetBrains Mono', monospace; - font-size: 0.75rem; - color: var(--gray); -} - -.tui-statusbar-item { - color: var(--gray); -} - -.tui-statusbar-btn { - padding: 3px 8px; +.header-theme-btn { + margin-left: auto; + padding: 4px 12px; background: transparent; border: 1px solid var(--gray); color: var(--fg); - font-family: inherit; - font-size: 0.72rem; + font-family: var(--font-custom-mono), 'JetBrains Mono', monospace; + font-size: 0.75rem; cursor: pointer; transition: all 0.15s ease; } -.tui-statusbar-btn:hover { +.header-theme-btn:hover { border-color: var(--accent); color: var(--accent); box-shadow: 0 0 8px rgba(250, 189, 47, 0.35); } - -.tui-statusbar-spacer { - flex: 1; -} - -.tui-statusbar-clock { - color: var(--gray); -} diff --git a/src/app/skeuo.css b/src/app/skeuo.css index 44947e3..d783e52 100644 --- a/src/app/skeuo.css +++ b/src/app/skeuo.css @@ -1,52 +1,52 @@ /* ============================================================ SKEUOMORPHIC THEME ------------------------------------------------------------ - Desktop -> Windows 7 Aero desktop shell - Mobile -> early iOS home screen + Desktop -> KDE Plasma (Breeze) + Mobile -> modern Android (Material You / Material 3) Active when . The terminal theme is - the alternate, reachable from the tray / Start menu / iOS app. + the alternate, reachable from the tray / launcher / Android chip. ============================================================ */ html[data-theme="skeuo"] { - --bg: #082a4c; - --white: #0e3355; - --gray: #4a6480; - --accent: #0d5aa7; - --accent2: #0a7cc1; - --green: #157347; - --blue: #1257a0; - --purple: #6a4fb3; - --fg: #10263a; - --font-custom-mono: "Segoe UI", "Segoe UI Variable Text", Tahoma, Verdana, Geneva, sans-serif; + --bg: #1b1e20; + --white: #31363b; + --gray: #5c6167; + --accent: #3daee9; + --accent2: #2980b9; + --green: #27ae60; + --blue: #3daee9; + --purple: #9b59b6; + --fg: #31363b; + --font-custom-mono: "Noto Sans", "Segoe UI", Ubuntu, Cantarell, "Helvetica Neue", Arial, sans-serif; } html[data-theme="skeuo"] body { overflow: hidden; - background: #082a4c; + background: #1b1e20; color: var(--fg); font-family: var(--font-custom-mono); } .skeuo-desktop-root { display: block; } -.skeuo-ios-root { display: none; } +.skeuo-mobile-root { display: none; } @media (max-width: 640px) { .skeuo-desktop-root { display: none; } - .skeuo-ios-root { display: block; } + .skeuo-mobile-root { display: block; } } /* ============================================================ - DESKTOP + DESKTOP (Plasma) ============================================================ */ .win-desktop { position: fixed; inset: 0; overflow: hidden; - background-color: #0a3a66; + background-color: #1b1e20; background-size: cover; background-position: center; background-repeat: no-repeat; - color: #eaf3ff; + color: #eff0f1; user-select: none; } @@ -56,61 +56,87 @@ html[data-theme="skeuo"] body { pointer-events: none; background: linear-gradient( to bottom, - rgba(6, 20, 40, 0.35), - rgba(6, 20, 40, 0) 22%, - rgba(6, 20, 40, 0) 70%, - rgba(6, 20, 40, 0.28) + rgba(0, 0, 0, 0.3), + rgba(0, 0, 0, 0) 22%, + rgba(0, 0, 0, 0) 70%, + rgba(0, 0, 0, 0.35) ); } -/* Desktop icons */ +/* Desktop icons (Folder View) */ .win-icons { position: absolute; - top: 14px; - left: 14px; + top: 12px; + left: 10px; display: flex; flex-direction: column; flex-wrap: wrap; align-content: flex-start; - gap: 6px; - max-height: calc(100% - 70px); + gap: 4px; + max-height: calc(100% - 68px); } .win-icon { width: 92px; - padding: 6px 4px; + padding: 6px 4px 7px; display: flex; flex-direction: column; align-items: center; - gap: 5px; + gap: 4px; border: 1px solid transparent; border-radius: 4px; background: transparent; - color: #fff; + color: #ffffff; cursor: default; text-shadow: 0 1px 3px rgba(0, 0, 0, 0.95); } +.win-icon:hover, .win-icon.selected { - background: rgba(125, 185, 255, 0.28); - border-color: rgba(170, 212, 255, 0.65); + background: rgba(61, 174, 233, 0.16); + border-color: rgba(61, 174, 233, 0.4); } .win-icon-glyph { - width: 44px; - height: 44px; - border-radius: 9px; + width: 48px; + height: 48px; display: grid; place-items: center; - font-size: 24px; - border: 1px solid rgba(255, 255, 255, 0.55); - box-shadow: - inset 0 1px 0 rgba(255, 255, 255, 0.65), - inset 0 -8px 14px rgba(0, 0, 0, 0.25), - 0 2px 7px rgba(0, 0, 0, 0.55); + font-size: 40px; + background: transparent !important; + border: none; + box-shadow: none; + filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.75)); } .win-icon-label { font-size: 0.72rem; line-height: 1.2; text-align: center; } +a.win-icon { + text-decoration: none; +} +.win-icons-tr { + top: 12px; + right: 10px; + left: auto; + align-items: flex-end; + flex-wrap: nowrap; + max-height: none; +} +.win-icons-br { + top: auto; + bottom: 62px; + right: 10px; + left: auto; + align-items: flex-end; + flex-wrap: nowrap; + max-height: none; +} +.win-icon-img { + width: 38px; + height: 38px; + object-fit: contain; + filter: brightness(0) invert(1); + opacity: 0.92; +} /* Window layer */ .win-layer { @@ -122,106 +148,102 @@ html[data-theme="skeuo"] body { pointer-events: auto; } -/* Windows */ +/* ============================================================ + BREEZE WINDOWS + ============================================================ */ .win-window { position: absolute; display: flex; flex-direction: column; min-width: 260px; min-height: 150px; - border-radius: 7px 7px 0 0; - background: #eef4fb; - border: 1px solid rgba(255, 255, 255, 0.85); - box-shadow: - 0 0 0 1px rgba(45, 95, 145, 0.55), - 0 20px 45px -14px rgba(0, 15, 40, 0.75); + border-radius: 8px; + background: #232629; + border: 1px solid #17191c; + box-shadow: 0 10px 32px rgba(0, 0, 0, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.04); overflow: hidden; + user-select: text; +} +.win-window.active { + border-color: #3a444d; + box-shadow: 0 18px 48px rgba(0, 0, 0, 0.66), inset 0 1px 0 rgba(255, 255, 255, 0.06); } .win-window.minimized { display: none; } .win-window.maximized { border-radius: 0; - height: calc(100% - 40px) !important; + height: calc(100% - 54px) !important; } -.win-window { - user-select: text; +.win-window.centered { + left: 50%; + top: calc(50% - 27px); + transform: translate(-50%, -50%); } .win-titlebar { + position: relative; flex: 0 0 30px; height: 30px; display: flex; align-items: center; - gap: 8px; - padding: 0 5px 0 10px; + padding: 0 8px; cursor: default; touch-action: none; - background: linear-gradient( - to bottom, - rgba(255, 255, 255, 0.92), - rgba(206, 226, 245, 0.68) 46%, - rgba(150, 188, 224, 0.58) 50%, - rgba(220, 236, 250, 0.82) - ); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.95), inset 0 -1px 0 rgba(255, 255, 255, 0.4); + user-select: none; + -webkit-user-select: none; + background: #26292e; + border-bottom: 1px solid #1a1d20; } .win-window.active .win-titlebar { - background: linear-gradient( - to bottom, - #eaf6ff, - #aacfef 46%, - #7fb4e0 50%, - #cfe6fa - ); -} -.win-titlebar-icon { - width: 18px; - height: 18px; - border-radius: 4px; - display: grid; - place-items: center; - font-size: 11px; - border: 1px solid rgba(255, 255, 255, 0.6); - flex-shrink: 0; + background: #2d3540; + border-bottom-color: rgba(61, 174, 233, 0.5); } .win-titlebar-text { - flex: 1; - font-size: 0.8rem; + position: absolute; + left: 50%; + transform: translateX(-50%); + max-width: calc(100% - 110px); + font-size: 0.79rem; font-weight: 600; - color: #0b3660; - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.9); + color: #eff0f1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .win-controls { + position: absolute; + right: 5px; + top: 0; + height: 30px; display: flex; - gap: 2px; - flex-shrink: 0; + align-items: center; + gap: 1px; } .win-ctl { position: relative; - width: 27px; - height: 20px; + width: 24px; + height: 22px; padding: 0; - border: 1px solid rgba(255, 255, 255, 0.7); - border-radius: 3px; - background: linear-gradient(to bottom, #fefefe, #dfeaf5 48%, #c4d6e8 52%, #eef4fb); + border: none; + border-radius: 4px; + background: transparent; + color: #d3dae3; cursor: default; } .win-ctl:hover { - background: linear-gradient(to bottom, #ffffff, #cfe2f4 48%, #b3cde6 52%, #e2eefa); + background: rgba(255, 255, 255, 0.16); } .win-ctl-min::before { content: ""; position: absolute; left: 50%; - bottom: 5px; - width: 9px; - height: 2px; - background: #39516b; - transform: translateX(-50%); + top: 50%; + width: 10px; + height: 1.5px; + border-radius: 1px; + background: currentColor; + transform: translate(-50%, -50%); } .win-ctl-max::before { content: ""; @@ -229,36 +251,37 @@ html[data-theme="skeuo"] body { left: 50%; top: 50%; width: 9px; - height: 8px; - border: 1px solid #39516b; + height: 9px; + border: 1.5px solid currentColor; + border-radius: 1px; transform: translate(-50%, -50%); } -.win-ctl-close::before { - content: "โœ•"; +.win-ctl-close::before, +.win-ctl-close::after { + content: ""; position: absolute; - inset: 0; - display: grid; - place-items: center; - font-size: 10px; - font-weight: 700; - color: #7a1f1f; + left: 50%; + top: 50%; + width: 10px; + height: 1.5px; + border-radius: 1px; + background: currentColor; } -.win-ctl-close:hover { - background: linear-gradient(to bottom, #f6a48c, #d84a2f 48%, #c0371d 52%, #ef7a5c); - border-color: #ffffff; +.win-ctl-close::before { + transform: translate(-50%, -50%) rotate(45deg); } -.win-ctl-close:hover::before { - color: #ffffff; +.win-ctl-close::after { + transform: translate(-50%, -50%) rotate(-45deg); } .win-body { flex: 1; overflow: auto; - background: linear-gradient(to bottom, #ffffff, #f1f5fb); + background: #232629; } /* ============================================================ - APP CONTENT SURFACE (shared by desktop windows + iOS apps) + APP CONTENT SURFACE (shared by desktop windows + Android apps) ============================================================ */ .app-surface { --white: #0e3355; @@ -279,7 +302,6 @@ html[data-theme="skeuo"] body { padding: 16px; } -/* Strip the terminal panel chrome inside app windows */ .app-surface .tui-panel, .app-surface .hero-panel, .app-surface .subsection-panel { @@ -297,7 +319,6 @@ html[data-theme="skeuo"] body { display: none; } -/* Social buttons */ .app-surface .social-button { margin: 3px 4px; border: 1px solid rgba(0, 0, 0, 0.16); @@ -326,7 +347,6 @@ html[data-theme="skeuo"] body { color: var(--accent2); } -/* Service buttons */ .app-surface .service-button { margin: 3px; border: 1px solid rgba(0, 0, 0, 0.16); @@ -354,7 +374,6 @@ html[data-theme="skeuo"] body { color: #1d3e5c; } -/* Project cards */ .app-surface .project-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); @@ -391,7 +410,6 @@ html[data-theme="skeuo"] body { color: #1d3e5c; } -/* Gym */ .app-surface .gym-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; @@ -416,7 +434,6 @@ html[data-theme="skeuo"] body { color: #6b8299; } -/* Heatmap */ .app-surface .heatmap-container { border-color: rgba(90, 150, 205, 0.6); border-radius: 5px; @@ -440,14 +457,14 @@ html[data-theme="skeuo"] body { } .app-surface .contribution-command, .app-surface .contribution-entry, -.app-surface .contribution-total-title { - color: #10263a; -} +.app-surface .contribution-total-title, .app-surface .contribution-message { color: #10263a; } +.app-surface .contribution-date { + color: #157347; +} -/* Text / typography inside apps */ .app-surface .about-content { padding: 0; color: #10263a; @@ -472,6 +489,27 @@ html[data-theme="skeuo"] body { .app-surface a { color: #0a6bb0; } +.app-inline-link { + padding: 0; + border: none; + background: none; + color: var(--accent); + font: inherit; + text-decoration: underline; + cursor: pointer; +} +.app-inline-link:hover { + color: var(--accent2); +} +.app-preference { + margin-top: 14px; + font-size: 0.95rem; + font-weight: 600; + color: var(--fg); +} +.app-preference .app-inline-link { + font-weight: 700; +} .app-surface .app-center { text-align: center; } @@ -554,91 +592,313 @@ html[data-theme="skeuo"] body { text-decoration: none; } +/* Dark app content inside Breeze Dark windows */ +.win-window .app-surface { + --white: #eff0f1; + --gray: #9aa0a6; + --accent: #3daee9; + --accent2: #3daee9; + --accent3: #3daee9; + --green: #27ae60; + --aqua: #16a085; + --blue: #3daee9; + --purple: #9b59b6; + --red: #da4453; + --darkpink: #e84393; + --fg: #eff0f1; + color: #eff0f1; +} +.win-body .about-content, +.win-body .about-content > div { + color: #c7cdd3 !important; +} +.win-body .app-cmd { + color: #b0b6bc; +} +.win-body .app-text { + color: #c7cdd3; +} +.win-body .app-list { + color: #c7cdd3; +} +.win-body .app-user { + color: #2ecc71; +} +.win-body .app-path { + color: #3daee9; +} +.win-body .app-muted { + color: #9aa0a6; +} +.win-body .app-h1, +.win-body .app-h2, +.win-body .app-welcome-head h2 { + color: #eff0f1; +} +.win-body a { + color: #3daee9; +} +.win-body .mail-contact { + color: #c7cdd3; +} +.win-body .mail-contact a { + color: #3daee9; +} +.win-body .app-welcome-head img { + border-color: #1b1e20; +} + +.win-body .social-button { + border-color: #1b1e20; + background: linear-gradient(to bottom, #3b4147, #31363b); + color: #eff0f1; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06), 0 1px 2px rgba(0, 0, 0, 0.4); +} +.win-body .social-button:hover { + border-color: #3daee9; + background: linear-gradient(to bottom, #2c6e93, #234f68); + color: #ffffff; + box-shadow: 0 0 0 1px #3daee9, 0 0 10px rgba(61, 174, 233, 0.5); +} +.win-body .social-icon { + filter: none; + opacity: 0.95; +} + +.win-body .service-button { + border-color: #1b1e20; + background: linear-gradient(to bottom, #3b4147, #31363b); + color: #eff0f1; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06), 0 1px 3px rgba(0, 0, 0, 0.4); +} +.win-body .service-button:hover { + border-color: #3daee9; + background: linear-gradient(to bottom, #2c6e93, #234f68); + box-shadow: 0 0 0 1px #3daee9, 0 0 12px rgba(61, 174, 233, 0.5); +} +.win-body .service-name { + color: #eff0f1; +} +.win-body .service-desc { + color: #9aa0a6; +} +.win-body .service-button:hover .service-desc { + color: #d3dae3; +} +.win-body .friend-icon { + filter: invert(1) brightness(1.5); +} + +.win-body .project-card { + border-color: #1b1e20; + background: linear-gradient(to bottom, #31363b, #2a2e32); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4); +} +.win-body .project-card:hover { + border-color: #3daee9; + background: #353b40; + box-shadow: 0 0 0 1px #3daee9, 0 0 14px rgba(61, 174, 233, 0.45); +} +.win-body .project-image { + border-color: #1b1e20; +} +.win-body .project-title { + color: #eff0f1; +} +.win-body .project-card:hover .project-title { + color: #3daee9; +} +.win-body .project-desc { + color: #b0b6bc; +} +.win-body .project-card:hover .project-desc { + color: #d3dae3; +} + +.win-body .gym-item { + border-color: #1b1e20; + background: linear-gradient(to bottom, #31363b, #2a2e32); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4); +} +.win-body .gym-label, +.win-body .gym-date { + color: #9aa0a6; +} +.win-body .gym-weight { + color: #eff0f1; +} + +.win-body .heatmap-container { + border-color: #3daee9; + background: rgba(255, 255, 255, 0.04); +} +.win-body .heatmap-cell, +.win-body .heatmap-legend-cell { + background-color: #31363b; +} +.win-body .heatmap-cell[data-level="1"], +.win-body .heatmap-legend-cell[data-level="1"] { background-color: rgba(61, 174, 233, 0.35); } +.win-body .heatmap-cell[data-level="2"], +.win-body .heatmap-legend-cell[data-level="2"] { background-color: rgba(61, 174, 233, 0.6); } +.win-body .heatmap-cell[data-level="3"], +.win-body .heatmap-legend-cell[data-level="3"] { background-color: rgba(61, 174, 233, 0.85); } +.win-body .heatmap-cell[data-level="4"], +.win-body .heatmap-legend-cell[data-level="4"] { background-color: #3daee9; } +.win-body .heatmap-cell:hover { + box-shadow: 0 0 6px #3daee9; +} +.win-body .contribution-command, +.win-body .contribution-entry, +.win-body .contribution-total-title, +.win-body .contribution-message { + color: #eff0f1; +} +.win-body .contribution-date { + color: #27ae60; +} + +.win-body .app-shot { + border-color: #1b1e20; +} +.win-body .app-linkrow a { + border-color: #1b1e20; + background: linear-gradient(to bottom, #3b4147, #31363b); + color: #eff0f1; +} +.win-body .friends-extra h3 { + color: #3daee9; +} + +/* Alacritty easter egg */ +.alacritty { + min-height: 100%; + box-sizing: border-box; + background: #1d1f21; + color: #c5c8c6; + font-family: "JetBrains Mono", "Fira Code", ui-monospace, SFMono-Regular, Menlo, + Consolas, monospace; + padding: 16px; + overflow: auto; +} +.alacritty-line { + margin-bottom: 12px; + font-size: 0.85rem; +} +.alacritty-prompt { color: #b8bb26; } +.alacritty-path { color: #83a598; } +.alacritty-cmd { color: #ebdbb2; } +.alacritty-art { + margin: 0 0 12px; + font-family: inherit; + font-size: 0.6rem; + line-height: 1.05; + color: #ebdbb2; + white-space: pre; +} +.alacritty-cursor { + display: inline-block; + width: 8px; + height: 1em; + background: #ebdbb2; + vertical-align: text-bottom; + margin-left: 2px; + animation: cursorBlink 1s step-end infinite; +} + /* ============================================================ - TASKBAR + PLASMA PANEL ============================================================ */ .win-taskbar { position: absolute; - left: 0; - right: 0; - bottom: 0; - height: 40px; + left: 10px; + right: 10px; + bottom: 10px; + height: 44px; z-index: 9000; display: flex; align-items: stretch; - gap: 4px; - background: linear-gradient( - to bottom, - rgba(62, 92, 132, 0.78), - rgba(16, 38, 68, 0.9) 45%, - rgba(6, 20, 40, 0.95) - ); - border-top: 1px solid rgba(170, 212, 252, 0.6); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.32); - backdrop-filter: blur(16px) saturate(160%); - -webkit-backdrop-filter: blur(16px) saturate(160%); - color: #eaf3ff; + gap: 2px; + border-radius: 8px; + background: rgba(35, 38, 41, 0.85); + border: 1px solid rgba(255, 255, 255, 0.08); + box-shadow: 0 6px 22px rgba(0, 0, 0, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.06); + -webkit-backdrop-filter: blur(24px) saturate(140%); + backdrop-filter: blur(24px) saturate(140%); + color: #eff0f1; } .win-start { display: flex; align-items: center; - padding: 0 10px; + justify-content: center; + padding: 0 8px; border: none; - border-right: 1px solid rgba(255, 255, 255, 0.14); + border-radius: 8px 0 0 8px; background: transparent; cursor: pointer; } +.win-start:hover, +.win-start.open { + background: rgba(61, 174, 233, 0.28); +} .win-start-orb { - width: 28px; - height: 28px; - border-radius: 50%; + width: 34px; + height: 34px; display: grid; place-items: center; - font-size: 14px; - color: #fff; - text-shadow: 0 1px 1px rgba(0, 30, 70, 0.65); - background: radial-gradient(circle at 35% 28%, #c8ecff, #3d92d6 55%, #0b4f8f 100%); - border: 1px solid rgba(255, 255, 255, 0.75); - box-shadow: - 0 0 10px rgba(120, 200, 255, 0.85), - inset 0 2px 4px rgba(255, 255, 255, 0.7), - inset 0 -3px 6px rgba(0, 30, 70, 0.6); } -.win-start.open .win-start-orb { - box-shadow: - 0 0 16px rgba(150, 215, 255, 1), - inset 0 2px 4px rgba(255, 255, 255, 0.8), - inset 0 -3px 6px rgba(0, 30, 70, 0.6); +.gentoo-logo { + width: 26px; + height: 27px; + object-fit: contain; + filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.6)); } .win-tb-buttons { display: flex; align-items: stretch; - gap: 3px; - padding: 3px 6px; + gap: 2px; + padding: 4px 4px; min-width: 0; overflow: hidden; } .win-tb-btn { + position: relative; display: flex; align-items: center; gap: 7px; - max-width: 176px; + max-width: 172px; padding: 0 10px; - border: 1px solid rgba(255, 255, 255, 0.22); - border-radius: 3px; - background: linear-gradient(to bottom, rgba(255, 255, 255, 0.16), rgba(255, 255, 255, 0.04)); - color: #eaf3ff; + border: 1px solid transparent; + border-radius: 5px; + background: transparent; + color: #eff0f1; cursor: pointer; } +.win-tb-btn::after { + content: ""; + position: absolute; + left: 50%; + bottom: 2px; + width: 0; + height: 2px; + border-radius: 1px; + background: #3daee9; + transform: translateX(-50%); + transition: width 0.15s ease; +} +.win-tb-btn.active::after { + width: 24px; +} +.win-tb-btn:hover { + background: rgba(255, 255, 255, 0.1); +} .win-tb-btn.active { - background: linear-gradient(to bottom, rgba(160, 215, 255, 0.5), rgba(60, 140, 220, 0.35)); - border-color: rgba(205, 236, 255, 0.9); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5), 0 0 10px rgba(120, 200, 255, 0.5); + background: rgba(61, 174, 233, 0.32); + border-color: rgba(61, 174, 233, 0.55); } .win-tb-btn.minimized { - opacity: 0.72; + opacity: 0.7; } .win-tb-btn-icon { width: 18px; @@ -661,155 +921,123 @@ html[data-theme="skeuo"] body { align-items: center; gap: 8px; margin-left: auto; - padding: 0 6px 0 4px; + padding: 0 4px 0 4px; flex-shrink: 0; } -.win-search { - display: flex; - align-items: center; - gap: 5px; - height: 24px; - padding: 0 8px; - border: 1px solid rgba(255, 255, 255, 0.6); - border-radius: 3px; - background: rgba(255, 255, 255, 0.94); - box-shadow: inset 0 1px 2px rgba(0, 20, 45, 0.25); -} -.win-search-glyph { - color: #5b7590; - font-size: 0.85rem; -} -.win-search input { - width: 168px; - border: none; - outline: none; - background: transparent; - font-size: 0.75rem; - color: #12314d; -} .win-theme-toggle { display: inline-flex; align-items: center; gap: 6px; - height: 24px; - padding: 0 10px; - border: 1px solid rgba(255, 255, 255, 0.4); - border-radius: 3px; - background: linear-gradient(to bottom, rgba(255, 255, 255, 0.28), rgba(255, 255, 255, 0.06)); - color: #eaf3ff; + height: 26px; + padding: 0 12px; + border-radius: 13px; + border: 1px solid rgba(255, 255, 255, 0.15); + background: rgba(255, 255, 255, 0.06); + color: #eff0f1; font-size: 0.72rem; cursor: pointer; } .win-theme-toggle:hover { - background: linear-gradient(to bottom, rgba(152, 210, 255, 0.6), rgba(60, 140, 220, 0.4)); - border-color: rgba(205, 236, 255, 0.95); - box-shadow: 0 0 12px rgba(120, 200, 255, 0.7); + background: rgba(61, 174, 233, 0.3); + border-color: rgba(61, 174, 233, 0.6); } .win-clock { - font-size: 0.74rem; - color: #eaf3ff; + font-size: 0.75rem; + color: #eff0f1; white-space: nowrap; } .win-showdesktop { - width: 12px; - margin-left: 2px; + width: 10px; border: none; - border-left: 1px solid rgba(255, 255, 255, 0.55); - background: linear-gradient(to bottom, rgba(255, 255, 255, 0.22), rgba(255, 255, 255, 0.02)); + border-left: 1px solid rgba(255, 255, 255, 0.15); + background: transparent; cursor: pointer; } +.win-showdesktop:hover { + background: rgba(255, 255, 255, 0.12); +} /* ============================================================ - START MENU + KICKOFF LAUNCHER ============================================================ */ -.win-startmenu { +.kickoff { position: absolute; - left: 0; - bottom: 40px; + left: 10px; + bottom: 62px; z-index: 9500; - width: 340px; - max-height: 72vh; - display: flex; - flex-direction: column; - border: 1px solid rgba(60, 110, 160, 0.6); - border-bottom: none; - border-radius: 6px 6px 0 0; - background: linear-gradient(to bottom, rgba(242, 248, 254, 0.99), rgba(214, 230, 246, 0.99)); - box-shadow: 0 -8px 34px rgba(0, 10, 25, 0.55), inset 0 1px 0 #ffffff; - backdrop-filter: blur(14px); - -webkit-backdrop-filter: blur(14px); + width: 320px; + max-width: calc(100vw - 20px); + border-radius: 8px; + background: rgba(35, 38, 41, 0.94); + border: 1px solid rgba(255, 255, 255, 0.1); + box-shadow: 0 18px 50px rgba(0, 0, 0, 0.6); + -webkit-backdrop-filter: blur(28px) saturate(150%); + backdrop-filter: blur(28px) saturate(150%); + color: #eff0f1; overflow: hidden; } -.win-startmenu-user { - display: flex; - align-items: center; - gap: 8px; - padding: 11px 14px; - font-weight: 600; - color: #0e3355; - background: linear-gradient(to bottom, rgba(255, 255, 255, 0.85), rgba(208, 227, 246, 0.65)); - border-bottom: 1px solid rgba(60, 110, 160, 0.3); -} -.win-startmenu-avatar { - font-size: 1.2rem; -} -.win-startmenu-list { +.kickoff-content { + max-height: 60vh; overflow: auto; - padding: 8px; - display: grid; - gap: 2px; + padding: 10px 12px; } -.win-startmenu-item { +.kickoff-section-title { + margin: 4px 2px 8px; + font-size: 0.7rem; + text-transform: uppercase; + letter-spacing: 0.06em; + color: rgba(239, 240, 241, 0.55); +} +.kickoff-icon { + width: 22px; + height: 22px; + display: grid; + place-items: center; + font-size: 15px; + flex-shrink: 0; +} +.kickoff-icon-img { + width: 20px; + height: 20px; + object-fit: contain; + filter: brightness(0) invert(1); + opacity: 0.92; +} +.kickoff-label { + font-size: 0.84rem; + line-height: 1.2; + text-align: left; +} +.kickoff-list { + display: grid; + gap: 1px; +} +.kickoff-item { display: flex; align-items: center; gap: 10px; - padding: 7px 10px; - border: 1px solid transparent; - border-radius: 4px; - background: transparent; - color: #123a5e; - font-size: 0.82rem; - text-align: left; - cursor: pointer; -} -.win-startmenu-item:hover { - background: linear-gradient(to bottom, #eaf5ff, #c9e2fa); - border-color: #9fc9ef; -} -.win-startmenu-icon { - width: 22px; - height: 22px; + padding: 7px 8px; + border: none; border-radius: 5px; - display: grid; - place-items: center; - font-size: 13px; - border: 1px solid rgba(255, 255, 255, 0.58); - flex-shrink: 0; -} -.win-startmenu-foot { - border-top: 1px solid rgba(60, 110, 160, 0.3); - padding: 8px; - display: flex; - justify-content: flex-end; -} -.win-startmenu-power { - padding: 5px 10px; - border: 1px solid rgba(60, 110, 160, 0.5); - border-radius: 4px; - background: linear-gradient(to bottom, #ffffff, #e9eff7); - color: #123a5e; - font-size: 0.76rem; + background: transparent; + color: #eff0f1; + font-size: 0.84rem; + text-align: left; + text-decoration: none; cursor: pointer; } -.win-startmenu-power:hover { - background: linear-gradient(to bottom, #eaf5ff, #c9e2fa); - border-color: #7db9e8; +.kickoff-item:hover { + background: rgba(61, 174, 233, 0.3); } /* ============================================================ - MOBILE -> early iOS + MOBILE -> modern Android (Material You) ============================================================ */ -.ios-home { +.android-root { + display: block; +} + +.android-home { position: fixed; inset: 0; overflow: hidden; @@ -817,192 +1045,234 @@ html[data-theme="skeuo"] body { background-size: cover; background-position: center; background-repeat: no-repeat; + color: #ffffff; + font-family: Roboto, "Helvetica Neue", Arial, sans-serif; } -.ios-home::before { +.android-home::before { content: ""; position: absolute; inset: 0; pointer-events: none; - background: linear-gradient(to bottom, rgba(0, 0, 0, 0.35), rgba(0, 0, 0, 0.28) 40%, rgba(0, 0, 0, 0.42)); + background: linear-gradient( + to bottom, + rgba(0, 0, 0, 0.4), + rgba(0, 0, 0, 0.12) 28%, + rgba(0, 0, 0, 0.25) 62%, + rgba(0, 0, 0, 0.6) + ); } -.ios-statusbar { +.android-statusbar { position: absolute; top: 0; left: 0; right: 0; - height: 24px; + height: 28px; z-index: 20; display: flex; align-items: center; justify-content: space-between; - padding: 0 14px; - color: #fff; - font-size: 0.72rem; - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8); + padding: 0 18px; + font-size: 0.75rem; + font-weight: 500; + letter-spacing: 0.02em; } -.ios-status-icons { - letter-spacing: 1px; +.android-status-icons { + letter-spacing: 2px; } -.ios-grid { +.android-theme-chip { position: absolute; - top: 92px; + top: 36px; + right: 14px; + z-index: 20; + display: inline-flex; + align-items: center; + gap: 6px; + height: 34px; + padding: 0 14px; + border-radius: 17px; + border: 1px solid rgba(255, 255, 255, 0.25); + background: rgba(255, 255, 255, 0.16); + color: #ffffff; + font-size: 0.75rem; + font-weight: 500; + -webkit-backdrop-filter: blur(10px); + backdrop-filter: blur(10px); + cursor: pointer; +} +.android-theme-chip:active { + background: rgba(255, 255, 255, 0.28); +} + +.android-glance { + position: absolute; + top: 58px; + left: 20px; + z-index: 10; +} +.android-glance-time { + font-size: 3.4rem; + font-weight: 300; + line-height: 1; + letter-spacing: -0.02em; + text-shadow: 0 2px 10px rgba(0, 0, 0, 0.6); +} +.android-glance-sub { + margin-top: 3px; + font-size: 0.78rem; + opacity: 0.92; + text-shadow: 0 1px 4px rgba(0, 0, 0, 0.7); +} + +.android-grid { + position: absolute; + top: 182px; left: 0; right: 0; - bottom: 78px; + bottom: 112px; z-index: 10; overflow-y: auto; - padding: 12px 14px; + padding: 8px 16px; display: grid; grid-template-columns: repeat(4, 1fr); - gap: 16px 8px; + gap: 18px 8px; align-content: start; } -.ios-app { +.android-app { display: flex; flex-direction: column; align-items: center; - gap: 5px; + gap: 6px; padding: 0; border: none; background: transparent; cursor: pointer; } -.ios-app-icon { +.android-app-icon { position: relative; - width: 60px; - height: 60px; - border-radius: 14px; + width: 58px; + height: 58px; + border-radius: 18px; display: grid; place-items: center; - font-size: 28px; + font-size: 27px; overflow: hidden; - border: 1px solid rgba(255, 255, 255, 0.75); - box-shadow: - inset 0 1px 0 rgba(255, 255, 255, 0.85), - inset 0 -10px 16px rgba(0, 0, 0, 0.28), - 0 3px 8px rgba(0, 0, 0, 0.55); + border: 1px solid rgba(255, 255, 255, 0.25); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.35), 0 3px 10px rgba(0, 0, 0, 0.45); } -.ios-app-icon::after { +.android-app-icon::after { content: ""; position: absolute; - top: 2px; - left: 6%; - right: 6%; - height: 42%; - border-radius: 12px 12px 50% 50%; - background: linear-gradient(to bottom, rgba(255, 255, 255, 0.72), rgba(255, 255, 255, 0.04)); + inset: 0; + background: linear-gradient(to bottom, rgba(255, 255, 255, 0.26), rgba(255, 255, 255, 0) 55%); pointer-events: none; } -.ios-app-label { +.android-app-label { max-width: 72px; - font-size: 0.64rem; + font-size: 0.68rem; line-height: 1.15; text-align: center; - color: #fff; - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.95); + text-shadow: 0 1px 3px rgba(0, 0, 0, 0.9); } -.ios-dock { +.android-dock { position: absolute; - left: 8px; - right: 8px; - bottom: 8px; - height: 62px; + left: 0; + right: 0; + bottom: 42px; z-index: 10; - border-radius: 16px; - border: 1px solid rgba(255, 255, 255, 0.4); - background: linear-gradient(to bottom, rgba(190, 205, 225, 0.4), rgba(120, 140, 170, 0.3)); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5), 0 4px 14px rgba(0, 0, 0, 0.5); - backdrop-filter: blur(14px); - -webkit-backdrop-filter: blur(14px); -} - -.ios-theme-app { - position: absolute; - top: 28px; - right: 12px; - z-index: 20; display: flex; - flex-direction: column; - align-items: center; - gap: 3px; - padding: 0; - border: none; - background: transparent; - cursor: pointer; + justify-content: center; + gap: 20px; + padding: 0 16px; } -.ios-theme-app-icon { - width: 46px; - height: 46px; - border-radius: 11px; - display: grid; - place-items: center; - font-size: 1.2rem; - color: #fff; - border: 1px solid rgba(255, 255, 255, 0.8); - background: linear-gradient(to bottom, #9ad4ff, #1f7fc4 50%, #0f5c9c 51%, #083a68); - box-shadow: - inset 0 1px 0 rgba(255, 255, 255, 0.9), - inset 0 -8px 14px rgba(0, 30, 70, 0.5), - 0 3px 8px rgba(0, 0, 0, 0.6); -} -.ios-theme-app-label { - font-size: 0.55rem; - color: #fff; - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.9); +.android-app.in-dock .android-app-icon { + width: 52px; + height: 52px; + border-radius: 16px; + font-size: 24px; } -/* iOS fullscreen app view */ -.ios-app-view { +.android-navbar { + position: absolute; + left: 0; + right: 0; + bottom: 0; + height: 22px; + z-index: 30; + display: flex; + align-items: center; + justify-content: center; +} +.android-navbar-pill { + width: 130px; + height: 5px; + border-radius: 3px; + background: rgba(255, 255, 255, 0.85); +} + +.android-app-view { position: fixed; inset: 0; z-index: 40; display: flex; flex-direction: column; - background: #eef1f6; + background: #fef7ff; + color: #1d1b20; + font-family: Roboto, "Helvetica Neue", Arial, sans-serif; } -.ios-navbar { - position: relative; - flex: 0 0 44px; - height: 44px; +.android-appbar { + flex: 0 0 auto; display: flex; align-items: center; - justify-content: space-between; - padding: 0 10px; - color: #fff; - background: linear-gradient(to bottom, #4e6282, #263044); - border-bottom: 1px solid rgba(0, 0, 0, 0.5); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25); + gap: 10px; + padding: 12px 12px 10px; + background: #fef7ff; + border-bottom: 1px solid #e7e0ec; } -.ios-back { - padding: 4px 6px; +.android-back { + width: 40px; + height: 40px; border: none; + border-radius: 50%; background: transparent; - color: #fff; - font-size: 0.9rem; + color: #1d1b20; + font-size: 1.2rem; cursor: pointer; } -.ios-navbar-title { - position: absolute; - left: 50%; - transform: translateX(-50%); - font-size: 0.95rem; - font-weight: 600; +.android-back:hover { + background: #eadcff; } -.ios-navbar-spacer { - width: 56px; +.android-appbar-title { + font-size: 1.1rem; + font-weight: 500; } -.ios-app-body { +.android-app-body { flex: 1; overflow-y: auto; - background: linear-gradient(to bottom, #fbfcff, #e7ebf2); + background: #fef7ff; +} +.android-app-body.app-surface { + --accent: #6750a4; + --accent2: #7d5260; + --accent3: #6750a4; + --blue: #6750a4; + --white: #1d1b20; + --gray: #49454f; + --fg: #1d1b20; + color: #1d1b20; +} +.android-app-body .project-card, +.android-app-body .service-button, +.android-app-body .social-button, +.android-app-body .gym-item { + border-radius: 14px; } @media (max-width: 640px) { .app-pad { - padding: 12px; + padding: 14px; } .app-surface .project-grid { grid-template-columns: 1fr; @@ -1023,7 +1293,7 @@ html[data-theme="skeuo"] body { } @media (max-width: 380px) { - .ios-grid { + .android-grid { grid-template-columns: repeat(3, 1fr); } }