Enhance styling and functionality: add scrollbar styles, update iframe source, adjust project section width, implement MagicalGirl toggle, and create ASCII art HTML page.
This commit is contained in:
parent
217f115069
commit
deca6506a9
8 changed files with 178 additions and 22 deletions
99
public/ascii-art.html
Normal file
99
public/ascii-art.html
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
|
||||
<meta name="theme-color" content="#0C0C0C">
|
||||
<meta name="date" content="2025-10-21T13:11:07.098Z">
|
||||
<link href="https://fonts.cdnfonts.com/css/cascadia-code" rel="stylesheet">
|
||||
<title>imnyang</title>
|
||||
<style>
|
||||
:root {
|
||||
--color-primary-light: #FFD7D7;
|
||||
--color-secondary-light: #EEEEEE;
|
||||
--color-tertiary-light: #FFFFFF;
|
||||
--color-quaternary-light: #E4E4E4;
|
||||
--color-quinary-light: #DADADA;
|
||||
--color-senary-light: #D7D7D7;
|
||||
--color-septenary-light: #D0D0D0;
|
||||
--color-text: #fcf8f9;
|
||||
--background: #191017;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
--color-primary-light: #FFD7D7;
|
||||
--color-secondary-light: #EEEEEE;
|
||||
--color-tertiary-light: #FFFFFF;
|
||||
--color-quaternary-light: #E4E4E4;
|
||||
--color-quinary-light: #DADADA;
|
||||
--color-senary-light: #D7D7D7;
|
||||
--color-septenary-light: #D0D0D0;
|
||||
--color-text: #fcf8f9;
|
||||
--background: #191017;
|
||||
}
|
||||
}
|
||||
|
||||
* {
|
||||
font-variant-ligatures: none;
|
||||
font-feature-settings: 'liga' 0, 'clig' 0;
|
||||
}
|
||||
html, body {
|
||||
background: var(--background);
|
||||
color: var(--color-text);
|
||||
margin: 0;
|
||||
}
|
||||
pre {
|
||||
font-family: 'Cascadia Code', sans-serif;
|
||||
font-size: 6pt;
|
||||
line-height: 1.2;
|
||||
margin: 0px 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body><pre><span style="color: var(--color-primary-light);"> @@@@@@@@ @@@@@@@@@
|
||||
@@ @@ @@@ @@
|
||||
@@ @@@ @ @@ @@
|
||||
@@ @@ @@ @ @@ @@ @@
|
||||
@@ @@ @ @@ @@ @@ @
|
||||
@ @@@ @ @@ @@@ @ @
|
||||
@@ @@ @ @ @@ @@ @@
|
||||
@@ @@ @ @@ @@ @@
|
||||
@ @@ @ @@@@@ @@ @@
|
||||
@ @@ @@@@ @@ @@ @@@@@@ @@
|
||||
@ @@ @@@ @@@ @@ @@
|
||||
@@ @@@ @ @@@ @ @@ @@ @@
|
||||
@@@ @@@@@ @@@@ @@@ @@ @@ @@@@ @@
|
||||
@@ @ @@ @@@@@ @@@ @ @
|
||||
@@ @@@@ @ @ @
|
||||
@@ @@ @ @ @ @@ @@
|
||||
@@ @@ @ @ @@ @@ @@
|
||||
@@ @@@@@ @ @ @@ @
|
||||
@ @@@ @ @@ @ @@ @
|
||||
@@ @@@ @ @ @ @@ @@ @
|
||||
@@@ @@ @@ @@ @@
|
||||
@@ @ @ @ @ @
|
||||
@ @ @ @ @@
|
||||
@@ @@ @ @@ @ @
|
||||
@ @@@@@@ @@@ @@ @ @@
|
||||
@ @ @ @@ @ @@ @@ @ @@ @@
|
||||
@@@ @ @ @@@@@@ @ @ @@
|
||||
@ @ @ @ @@@ @@ @@@@ @@
|
||||
@@ @@@@@@@@@@@@@ @@@@ @@@ @@ @@@@@ @
|
||||
@@ @ @ @ @@@ @@@@@@@@@@@ @ @@ @
|
||||
@@ @ @ @ @@ @ @ @@@@ @@ @@
|
||||
@@ @@ @ @@ @ @ @@ @@ @@ @@
|
||||
@@ @ @@ @@@ @ @@ @ @@@@@ @@ @@
|
||||
@@ @@ @@@ @ @@ @@@ @@ @
|
||||
@@ @ @@@ @@ @ @@
|
||||
@ @ @@@ @ @ @@
|
||||
@ @@ @ @ @
|
||||
@@ @@ @ @ @@
|
||||
@ @@ @@ @@@@@@@@
|
||||
@@ @@ @@@@@@@@@@@@@@@@@@@ @@@@@@@@
|
||||
@@ @@@@ @@@@@ @@@ @ @@
|
||||
@@@ @ @@@@ @ @ @@@ @@
|
||||
@@@ @@ @@@ @ @@ @ @@@@@@@@@@@@@@@ @@
|
||||
@@ @@ @@@ @ @@ @ @@@@@@ @@
|
||||
</span></pre></body>
|
||||
</html>
|
||||
|
|
@ -48,6 +48,9 @@
|
|||
--sidebar-accent-foreground: hsl(240 5.9% 10%);
|
||||
--sidebar-border: hsl(340 20% 90%);
|
||||
--sidebar-ring: hsl(217.2 91.2% 59.8%);
|
||||
|
||||
--scrollbar: hsla(340 10% 60% / 0.5);
|
||||
--scrollbar-hover: hsla(340 10% 60% / 0.8);
|
||||
}
|
||||
|
||||
.dark {
|
||||
|
|
@ -84,6 +87,9 @@
|
|||
--sidebar-border: hsl(296, 18%, 15%);
|
||||
--sidebar-ring: hsl(217.2 91.2% 59.8%);
|
||||
--sidebar: hsl(240 5.9% 10%);
|
||||
|
||||
--scrollbar: hsla(340 10% 60% / 0.5);
|
||||
--scrollbar-hover: hsla(340 10% 60% / 0.8);
|
||||
}
|
||||
|
||||
@theme inline {
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@
|
|||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--muted-foreground);
|
||||
background: var(--scrollbar);
|
||||
border: 5px solid var(--background);
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--foreground);
|
||||
background: var(--scrollbar-hover);
|
||||
}
|
||||
|
||||
/* ::-webkit-scrollbar:not(.highlighttable, .highlight table, .gist .highlight) {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ export default function NeoFetch() {
|
|||
<div className="w-full bg-[#191017] text-[#fcf8f9] font-[Google Sans Code] rounded-b-4xl">
|
||||
<div className="flex flex-col md:flex-row">
|
||||
<iframe
|
||||
src="/art.html"
|
||||
src="/ascii-art.html"
|
||||
className="border-0 min-w-[430px] min-h-[430px] scale-75"
|
||||
></iframe>
|
||||
<div className="px-12 md:py-12 text-lg">
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ const projects = [
|
|||
|
||||
export default function Projects() {
|
||||
return (
|
||||
<section className="break-keep break-words w-full md:w-1/2">
|
||||
<section className="break-keep break-words w-full lg:w-1/2">
|
||||
<div className="space-y-8">
|
||||
{projects.map((project, idx) => (
|
||||
<div className="space-y-2" key={idx}>
|
||||
|
|
|
|||
|
|
@ -78,7 +78,14 @@ export default function SUPERCOMMAND() {
|
|||
</DialogDescription>
|
||||
<DialogFooter className="px-6 py-6 sm:justify-start fixed bottom-0 left-0 w-full bg-background/80 backdrop-blur-sm">
|
||||
<Button type="button" onClick={() => {
|
||||
document.cookie = "MagicalGirl=true; path=/";
|
||||
const existingCookie = document.cookie.split('; ').find(row => row.startsWith('MagicalGirl='));
|
||||
if (existingCookie) {
|
||||
document.cookie = "MagicalGirl=; path=/; expires=Thu, 01 Jan 1970 00:00:00 UTC";
|
||||
window.location.reload();
|
||||
} else {
|
||||
document.cookie = "MagicalGirl=true; path=/; expires=Fri, 31 Dec 9999 23:59:59 GMT";
|
||||
window.location.reload();
|
||||
}
|
||||
setShowDialog(false);
|
||||
}}>Okay</Button>
|
||||
</DialogFooter>
|
||||
|
|
|
|||
|
|
@ -1,14 +1,21 @@
|
|||
"use client";
|
||||
import Sidebar from "@/components/sidebar";
|
||||
import Image from "next/image";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import Sidebar from "@/components/sidebar";
|
||||
import { useIsMobile } from "@/hooks/use-mobile";
|
||||
|
||||
export default function Top() {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const [randomBg, setRandomBg] = useState(1);
|
||||
const isMobile = useIsMobile();
|
||||
const [clickCount, setClickCount] = useState(0);
|
||||
const clickTimeoutRef = useRef<NodeJS.Timeout | null>(null);
|
||||
const [isMagicalGirlEnabled, setIsMagicalGirlEnabled] = useState(false);
|
||||
const REQUIRED_CLICKS = 6;
|
||||
|
||||
useEffect(() => {
|
||||
setRandomBg(Math.floor(Math.random() * 14) + 1);
|
||||
setIsMagicalGirlEnabled(document.cookie.includes('MagicalGirl=true'));
|
||||
}, []);
|
||||
|
||||
const requestPermission = async () => {
|
||||
|
|
@ -18,8 +25,8 @@ export default function Top() {
|
|||
window.addEventListener("deviceorientation", handleDeviceOrientation);
|
||||
|
||||
try {
|
||||
const res = await (DeviceOrientationEvent as any).requestPermission();
|
||||
if (res === "granted") {
|
||||
const permission = await (DeviceOrientationEvent as unknown as { requestPermission: () => Promise<string> }).requestPermission();
|
||||
if (permission === "granted") {
|
||||
window.addEventListener("devicemotion", handleDeviceMotion);
|
||||
window.addEventListener("deviceorientation", handleDeviceOrientation);
|
||||
}
|
||||
|
|
@ -51,6 +58,36 @@ export default function Top() {
|
|||
bg.style.backgroundPosition = `${50 - x * 3}% ${50 - y * 3}%`;
|
||||
};
|
||||
|
||||
const handleBackgroundTouchClick = () => {
|
||||
if (!isMobile) return;
|
||||
|
||||
setClickCount((prev) => {
|
||||
const newCount = prev + 1;
|
||||
|
||||
// Clear existing timeout
|
||||
if (clickTimeoutRef.current) {
|
||||
clearTimeout(clickTimeoutRef.current);
|
||||
}
|
||||
|
||||
// Check if required clicks reached
|
||||
if (newCount >= REQUIRED_CLICKS) {
|
||||
const newValue = !isMagicalGirlEnabled;
|
||||
setIsMagicalGirlEnabled(newValue);
|
||||
|
||||
document.cookie = `MagicalGirl=${newValue}; path=/; max-age=${60 * 60 * 24 * 365}`;
|
||||
window.location.reload();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Reset click count after 1 second if not enough clicks
|
||||
clickTimeoutRef.current = setTimeout(() => {
|
||||
setClickCount(0);
|
||||
}, 1000);
|
||||
|
||||
return newCount;
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
window.removeEventListener("deviceorientation", handleDeviceOrientation);
|
||||
|
|
@ -74,6 +111,10 @@ export default function Top() {
|
|||
style={{
|
||||
backgroundImage: `url('/background/${randomBg}.avif')`,
|
||||
}}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
aria-label="Toggle MagicalGirl mode on mobile"
|
||||
onClick={handleBackgroundTouchClick}
|
||||
onMouseMove={(e) => {
|
||||
const { clientX, clientY } = e;
|
||||
const { innerWidth, innerHeight } = window;
|
||||
|
|
@ -90,15 +131,17 @@ export default function Top() {
|
|||
}
|
||||
}}
|
||||
>
|
||||
{/* <Image
|
||||
{isMagicalGirlEnabled && (
|
||||
<Image
|
||||
src={"/char.avif"}
|
||||
alt="character"
|
||||
width={4096}
|
||||
height={4096}
|
||||
width={4740}
|
||||
height={7584}
|
||||
className="w-[50vh] lg:w-[30vw] translate-y-[10%] transition-transform duration-100 ease-out"
|
||||
unoptimized
|
||||
onClick={requestPermission}
|
||||
/> */} {/* 이제 그런 애는 없어 */}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ export default function TimelineComponent() {
|
|||
return (
|
||||
<div
|
||||
id="timeline"
|
||||
className="w-full md:w-1/2 flex flex-col items-center justify-center px-12 mt-8"
|
||||
className="w-full lg:w-1/2 flex flex-col items-center justify-center px-12 mt-8"
|
||||
>
|
||||
<div className="w-full">
|
||||
<h1 className="text-2xl font-bold mb-4 w-full">🌠 수상 및 교육</h1>
|
||||
|
|
@ -36,6 +36,7 @@ export default function TimelineComponent() {
|
|||
{years.map((year) => (
|
||||
<button
|
||||
key={year}
|
||||
type="button"
|
||||
onClick={() => setSelectedYear(year)}
|
||||
className={`px-4 py-2 rounded-lg font-semibold transition-all text-sm ${
|
||||
selectedYear === year
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue