mirror of
https://github.com/adam-benyekkou/my_portfolio.git
synced 2026-01-15 20:20:09 +00:00
Operational dark mode button added
This commit is contained in:
@@ -23,7 +23,8 @@
|
||||
"assets": [
|
||||
{
|
||||
"glob": "**/*",
|
||||
"input": "public"
|
||||
"input": "public",
|
||||
"output": "/"
|
||||
}
|
||||
],
|
||||
"styles": ["src/styles.css"],
|
||||
@@ -82,7 +83,8 @@
|
||||
"assets": [
|
||||
{
|
||||
"glob": "**/*",
|
||||
"input": "public"
|
||||
"input": "public",
|
||||
"output": "/"
|
||||
}
|
||||
],
|
||||
"styles": [
|
||||
|
||||
@@ -5,39 +5,52 @@
|
||||
transition: transform 0.2s ease;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
user-select: none;
|
||||
|
||||
/* Add these properties to match button-custom */
|
||||
border: 1px solid transparent;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
/* Add .svg-icon class to target just the SVGs */
|
||||
/* SVG icon styling */
|
||||
.svg-icon {
|
||||
transition: filter 0.3s ease;
|
||||
fill: var(--color-nier-dark, #5a5a50);
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
transition: fill 0.3s ease;
|
||||
}
|
||||
|
||||
/* Change SVG color on hover using filter */
|
||||
.svg-button-container:hover .svg-icon,
|
||||
.svg-button-container:active .svg-icon {
|
||||
/* This creates a light beige/sepia filter similar to nier-light */
|
||||
filter: invert(80%) sepia(12%) saturate(176%) hue-rotate(343deg)
|
||||
brightness(106%) contrast(97%);
|
||||
}
|
||||
|
||||
/* Background fill effect */
|
||||
/* Background fill effect - matching button-custom */
|
||||
.svg-button-container::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 3px;
|
||||
bottom: 3px;
|
||||
top: 3px; /* Space from top border */
|
||||
bottom: 3px; /* Space from bottom border */
|
||||
width: 0;
|
||||
height: auto;
|
||||
height: auto; /* This makes it respect top and bottom values */
|
||||
background-color: var(--color-nier-dark, rgba(30, 30, 30, 0.8));
|
||||
transition: width 0.2s ease;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.svg-button-container:hover::before {
|
||||
/* Hover state */
|
||||
.svg-button-container:hover,
|
||||
.svg-button-container:focus {
|
||||
border-color: var(--color-nier-dark);
|
||||
}
|
||||
|
||||
.svg-button-container:hover::before,
|
||||
.svg-button-container:focus::before {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Change SVG fill on hover */
|
||||
.svg-button-container:hover .svg-icon,
|
||||
.svg-button-container:active .svg-icon {
|
||||
fill: var(--color-nier-text-light, #dcd8c0);
|
||||
}
|
||||
|
||||
/* Glitch effect on hover */
|
||||
.svg-button-container::after {
|
||||
content: attr(data-label);
|
||||
@@ -81,8 +94,7 @@
|
||||
|
||||
/* The glitch effect animation */
|
||||
@keyframes nier-button-glitch {
|
||||
0%,
|
||||
100% {
|
||||
0%, 100% {
|
||||
opacity: 0;
|
||||
transform: translateX(0);
|
||||
clip-path: inset(0 0 0 0);
|
||||
@@ -130,7 +142,7 @@
|
||||
|
||||
/* Button click effect */
|
||||
.svg-button-container:active {
|
||||
transform: scale(0.95);
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
.svg-button-container:active::after {
|
||||
@@ -163,172 +175,126 @@
|
||||
.svg-button-container:active .scan-line {
|
||||
animation: nier-button-scan 0.3s ease forwards;
|
||||
}
|
||||
|
||||
.svg-button-container:active .svg-icon {
|
||||
fill: var(--color-nier-dark, #dcd8c0);
|
||||
}
|
||||
}
|
||||
|
||||
.nier-link {
|
||||
/* Styling for text links with NieR aesthetic */
|
||||
a[data-label] {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
color: var(--color-nier-dark, #333);
|
||||
transition: color 0.2s ease;
|
||||
overflow: hidden;
|
||||
display: inline-block;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
text-decoration: none;
|
||||
transition: color 0.3s ease;
|
||||
padding: 0 2px;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
user-select: none;
|
||||
border-bottom: 1px solid transparent;
|
||||
}
|
||||
|
||||
/* Underline effect */
|
||||
.nier-link::before {
|
||||
a[data-label]::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 0;
|
||||
height: 1px;
|
||||
background-color: var(--color-nier-darker, #111);
|
||||
transition: width 0.2s ease;
|
||||
background-color: var(--color-nier-dark, #5a5a50);
|
||||
transition: width 0.3s ease;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.nier-link:hover,
|
||||
.nier-link:focus {
|
||||
color: var(--color-nier-darker, #111);
|
||||
outline: none;
|
||||
font-weight: 600;
|
||||
/* Text color change on hover */
|
||||
a[data-label]:hover {
|
||||
color: var(--color-nier-dark, #dcd8c0);
|
||||
border-bottom-color: var(--color-nier-dark);
|
||||
}
|
||||
|
||||
.nier-link:hover::before,
|
||||
.nier-link:focus::before {
|
||||
/* Underline animation on hover */
|
||||
a[data-label]:hover::before {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
/* Glitch effect on hover */
|
||||
.nier-link::after {
|
||||
content: attr(data-label);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--color-nier-darker, #111);
|
||||
opacity: 0;
|
||||
z-index: 2;
|
||||
pointer-events: none;
|
||||
font-weight: 600;
|
||||
/* Glitch effect on hover (similar to buttons) */
|
||||
a[data-label]:hover span:first-child {
|
||||
animation: nier-text-glitch 0.6s ease;
|
||||
}
|
||||
|
||||
.nier-link:hover::after {
|
||||
animation: nier-link-glitch 0.6s ease forwards;
|
||||
}
|
||||
|
||||
/* Subtle scan line on hover */
|
||||
.nier-link .scan-line {
|
||||
/* Scan line for links */
|
||||
a[data-label] .scan-line {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background-color: var(--color-nier-darker, #111);
|
||||
background-color: var(--color-nier-dark, rgba(230, 230, 230, 0.9));
|
||||
opacity: 0;
|
||||
z-index: 3;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.nier-link:hover .scan-line {
|
||||
animation: nier-link-scan 0.3s ease forwards;
|
||||
a[data-label]:hover .scan-line {
|
||||
animation: nier-button-scan 0.3s ease forwards;
|
||||
}
|
||||
|
||||
/* Glitch effect animation */
|
||||
@keyframes nier-link-glitch {
|
||||
/* Text glitch animation for links */
|
||||
@keyframes nier-text-glitch {
|
||||
0%, 100% {
|
||||
opacity: 0;
|
||||
transform: translateX(0);
|
||||
clip-path: inset(0 0 0 0);
|
||||
}
|
||||
10% {
|
||||
opacity: 0.3;
|
||||
transform: translateX(-1px);
|
||||
clip-path: inset(10% 0 80% 0);
|
||||
transform: translateX(-2px);
|
||||
clip-path: inset(0 0 40% 0);
|
||||
}
|
||||
12% {
|
||||
opacity: 0;
|
||||
15% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
20% {
|
||||
opacity: 0.3;
|
||||
transform: translateX(1px);
|
||||
clip-path: inset(30% 0 50% 0);
|
||||
clip-path: inset(40% 0 0 0);
|
||||
}
|
||||
22% {
|
||||
opacity: 0;
|
||||
25% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
30% {
|
||||
opacity: 0.2;
|
||||
transform: translateX(-1px);
|
||||
clip-path: inset(50% 0 20% 0);
|
||||
clip-path: inset(20% 0 20% 0);
|
||||
}
|
||||
32% {
|
||||
opacity: 0;
|
||||
35% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Scan line animation */
|
||||
@keyframes nier-link-scan {
|
||||
0% {
|
||||
opacity: 0.6;
|
||||
left: -100%;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
left: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/* Click effect */
|
||||
.nier-link:active {
|
||||
transform: translateY(1px);
|
||||
color: #111;
|
||||
}
|
||||
|
||||
.nier-link:active::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
opacity: 0;
|
||||
animation: nier-link-flash 0.2s ease;
|
||||
}
|
||||
|
||||
@keyframes nier-link-flash {
|
||||
0% {
|
||||
opacity: 0.3;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
/* Active/click state for links */
|
||||
a[data-label]:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
/* Touch device optimization */
|
||||
@media (hover: none) {
|
||||
.nier-link:active::before {
|
||||
a[data-label]:active::before {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.nier-link:active {
|
||||
color: var(--color-nier-darker, #111);
|
||||
font-weight: 600;
|
||||
a[data-label]:active .scan-line {
|
||||
animation: nier-button-scan 0.3s ease forwards;
|
||||
}
|
||||
|
||||
.nier-link:active .scan-line {
|
||||
animation: nier-link-scan 0.3s ease forwards;
|
||||
a[data-label]:active {
|
||||
color: var(--color-nier-dark, #dcd8c0);
|
||||
}
|
||||
}
|
||||
|
||||
.icon-email {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
background-color: var(--color-nier-text-dark);
|
||||
-webkit-mask: url('/email_qr_black.svg') no-repeat center;
|
||||
mask: url('/email_qr_black.svg') no-repeat center;
|
||||
-webkit-mask-size: contain;
|
||||
mask-size: contain;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
<a href="https://github.com/adam-benyekkou" target="_blank">
|
||||
<div class="border-b-1 w-full h-full">
|
||||
<div class="flex items-center justify-center h-full w-full svg-button-container" data-label="GitHub">
|
||||
<img class="w-10 h-10 relative z-10 svg-icon" src="github_logo.svg" alt="GitHub Logo">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" class="w-10 h-10 svg-icon">
|
||||
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>
|
||||
</svg>
|
||||
<span class="scan-line"></span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -12,26 +14,31 @@
|
||||
<a href="https://www.linkedin.com/in/adambnk/" target="_blank">
|
||||
<div class="w-full h-full">
|
||||
<div class="flex items-center justify-center h-full w-full svg-button-container" data-label="LinkedIn">
|
||||
<img class="w-8 h-8 relative z-10 svg-icon" src="linkedin_logo.svg" alt="LinkedIn Logo">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" class="w-8 h-8 svg-icon">
|
||||
<path d="M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z"/>
|
||||
</svg>
|
||||
<span class="scan-line"></span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="w-1/3 flex items-center justify-center h-full svg-button-container" data-label="Theme">
|
||||
<img class="w-10 h-10 relative z-10 svg-icon" src="theme_button.svg" alt="Theme Button">
|
||||
<div class="w-1/3 h-full">
|
||||
<div class="flex items-center justify-center h-full w-full svg-button-container" data-label="Theme">
|
||||
<app-header-switch-theme-button class="svg-icon" />
|
||||
<span class="scan-line"></span>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<!-- Rest of your layout remains unchanged -->
|
||||
<article class="border-r-0 md:border-r-1 grid grid-rows-2 w-full h-full my-4 md:my-0">
|
||||
<div class="border-b-1 w-full h-full">
|
||||
<p class="flex items-center justify-center h-full w-full">Operating from french tech-hideout</p>
|
||||
<p class="flex items-center justify-center h-full w-full">Operating from unknown french-hideout</p>
|
||||
</div>
|
||||
<div class="w-full h-full">
|
||||
<p class="flex items-center justify-center h-full w-full">
|
||||
Tech operative ready >
|
||||
<a href="https://www.linkedin.com/in/adambnk/" target="_blank" class="nier-link ml-2" data-label="Deploy my skills">
|
||||
<a href="https://www.linkedin.com/in/adambnk/" target="_blank" class="text-nier-mid ml-2" data-label="Deploy my skills">
|
||||
<span class="relative z-10">Deploy my skills</span>
|
||||
<span class="scan-line"></span>
|
||||
</a>
|
||||
@@ -41,7 +48,7 @@
|
||||
|
||||
<article class="flex items-center justify-center w-full h-full">
|
||||
<a href="mailto:your.email@example.com?subject=Initialize%20Connection%20-&body=System%20message%3A%20Your%20connection%20request%20has%20been%20received.%20Please%20provide%20your%20message%20to%20establish%20communication.">
|
||||
<img src="email_qr_black.svg" alt="Email QR Code" class="max-w-full h-auto">
|
||||
<div class="icon-email"></div>
|
||||
</a>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { Component } from '@angular/core';
|
||||
import {HeaderSwitchThemeButtonComponent} from './header-switch-theme-button/header-switch-theme-button.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-header-contact-links',
|
||||
imports: [],
|
||||
imports: [HeaderSwitchThemeButtonComponent],
|
||||
templateUrl: './header-contact-links.component.html',
|
||||
styleUrl: './header-contact-links.component.css'
|
||||
styleUrl: './header-contact-links.component.css',
|
||||
})
|
||||
export class HeaderContactLinksComponent {
|
||||
|
||||
}
|
||||
export class HeaderContactLinksComponent {}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/* header-switch-theme-button.component.scss */
|
||||
|
||||
/* Base styling for SVG elements */
|
||||
.svg-icon {
|
||||
transition: fill 0.3s ease, color 0.3s ease, transform 0.3s ease;
|
||||
}
|
||||
|
||||
/* Moon cutout styling - hidden by default in light mode */
|
||||
.moon-cutout {
|
||||
transition: fill 0.3s ease, transform 0.3s ease, opacity 0.3s ease;
|
||||
fill: #1a1a18; /* Default darker color */
|
||||
opacity: 0; /* Hidden in light mode */
|
||||
}
|
||||
|
||||
/* LIGHT MODE (default) - show sun */
|
||||
/* Base circle acts as the sun */
|
||||
.svg-icon circle[cx="12"][cy="12"][r="5"] {
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
/* DARK MODE - show moon */
|
||||
/* Show the moon cutout in dark mode */
|
||||
:host-context(.dark) .moon-cutout,
|
||||
body[data-theme="dark"] .moon-cutout {
|
||||
fill: var(--color-nier-dark-bg, #292925);
|
||||
opacity: 1; /* Visible in dark mode */
|
||||
}
|
||||
|
||||
/* HOVER STATE - always show moon with rotation */
|
||||
/* Rotation animation on hover */
|
||||
:host-context(.svg-button-container:hover) .svg-icon,
|
||||
.svg-button-container:hover .svg-icon {
|
||||
transform: rotate(45deg);
|
||||
color: var(--color-nier-text-light, #dcd8c0);
|
||||
fill: var(--color-nier-text-light, #dcd8c0);
|
||||
}
|
||||
|
||||
/* Always show moon cutout on hover */
|
||||
:host-context(.svg-button-container:hover) .moon-cutout,
|
||||
.svg-button-container:hover .moon-cutout {
|
||||
opacity: 1;
|
||||
fill: #3a3a34; /* Dark color for cutout on hover */
|
||||
}
|
||||
|
||||
/* ACTIVE STATE - same as hover */
|
||||
:host-context(.svg-button-container:active) .svg-icon,
|
||||
.svg-button-container:active .svg-icon {
|
||||
transform: rotate(45deg);
|
||||
color: var(--color-nier-text-light, #dcd8c0);
|
||||
fill: var(--color-nier-text-light, #dcd8c0);
|
||||
}
|
||||
|
||||
:host-context(.svg-button-container:active) .moon-cutout,
|
||||
.svg-button-container:active .moon-cutout {
|
||||
opacity: 1;
|
||||
fill: #3a3a34;
|
||||
}
|
||||
|
||||
/* Touch device support */
|
||||
@media (hover: none) {
|
||||
:host-context(.svg-button-container:active) .svg-icon,
|
||||
.svg-button-container:active .svg-icon {
|
||||
transform: rotate(45deg);
|
||||
color: var(--color-nier-text-light, #dcd8c0);
|
||||
fill: var(--color-nier-text-light, #dcd8c0);
|
||||
}
|
||||
|
||||
:host-context(.svg-button-container:active) .moon-cutout,
|
||||
.svg-button-container:active .moon-cutout {
|
||||
opacity: 1;
|
||||
fill: #3a3a34;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,37 @@
|
||||
<p-button
|
||||
label="Switch Theme"
|
||||
></p-button>
|
||||
<!-- header-switch-theme-button.component.html -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="w-10 h-10 svg-icon" (click)="toggleTheme()">
|
||||
<!-- Outer ring -->
|
||||
<circle cx="12" cy="12" r="11" fill="none" stroke="currentColor" stroke-width="0.8" />
|
||||
|
||||
<!-- Interface grid lines -->
|
||||
<line x1="2" y1="12" x2="22" y2="12" stroke="currentColor" stroke-width="0.4" />
|
||||
<line x1="12" y1="2" x2="12" y2="22" stroke="currentColor" stroke-width="0.4" />
|
||||
|
||||
<!-- Diagonal grid lines -->
|
||||
<line x1="4" y1="4" x2="20" y2="20" stroke="currentColor" stroke-width="0.3" />
|
||||
<line x1="20" y1="4" x2="4" y2="20" stroke="currentColor" stroke-width="0.3" />
|
||||
|
||||
<!-- Inner circle for sun/moon -->
|
||||
<circle cx="12" cy="12" r="5" fill="currentColor" />
|
||||
|
||||
<!-- Moon cutout (for dark mode) -->
|
||||
<circle cx="15" cy="9" r="5" fill="#5a5a50" class="moon-cutout" />
|
||||
|
||||
<!-- Small dot decorations -->
|
||||
<circle cx="5" cy="5" r="0.7" fill="currentColor" />
|
||||
<circle cx="19" cy="5" r="0.7" fill="currentColor" />
|
||||
<circle cx="5" cy="19" r="0.7" fill="currentColor" />
|
||||
<circle cx="19" cy="19" r="0.7" fill="currentColor" />
|
||||
|
||||
<!-- Interface dots -->
|
||||
<circle cx="12" cy="2" r="0.4" fill="currentColor" />
|
||||
<circle cx="12" cy="22" r="0.4" fill="currentColor" />
|
||||
<circle cx="2" cy="12" r="0.4" fill="currentColor" />
|
||||
<circle cx="22" cy="12" r="0.4" fill="currentColor" />
|
||||
|
||||
<!-- YoRHa-style logo elements -->
|
||||
<path d="M4,7 L8,7 L8,8 L4,8 Z" fill="currentColor" />
|
||||
<path d="M16,7 L20,7 L20,8 L16,8 Z" fill="currentColor" />
|
||||
<path d="M4,16 L8,16 L8,17 L4,17 Z" fill="currentColor" />
|
||||
<path d="M16,16 L20,16 L20,17 L16,17 Z" fill="currentColor" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 46 B After Width: | Height: | Size: 1.6 KiB |
@@ -1,10 +1,69 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { ButtonModule } from 'primeng/button';
|
||||
// header-switch-theme-button.component.ts
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-header-switch-theme-button',
|
||||
imports: [ButtonModule],
|
||||
templateUrl: './header-switch-theme-button.component.html',
|
||||
styleUrl: './header-switch-theme-button.component.css',
|
||||
styleUrls: ['./header-switch-theme-button.component.css'],
|
||||
})
|
||||
export class HeaderSwitchThemeButtonComponent {}
|
||||
export class HeaderSwitchThemeButtonComponent implements OnInit {
|
||||
isDarkMode = false;
|
||||
|
||||
constructor() {}
|
||||
|
||||
ngOnInit(): void {
|
||||
// Check initial theme on load
|
||||
this.isDarkMode = this.getCurrentTheme() === 'dark';
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle between light and dark themes
|
||||
*/
|
||||
toggleTheme(): void {
|
||||
this.isDarkMode = !this.isDarkMode;
|
||||
|
||||
// Update body data attribute
|
||||
document.body.setAttribute(
|
||||
'data-theme',
|
||||
this.isDarkMode ? 'dark' : 'light',
|
||||
);
|
||||
|
||||
// Add/remove dark class from body for :host-context
|
||||
if (this.isDarkMode) {
|
||||
document.body.classList.add('dark');
|
||||
} else {
|
||||
document.body.classList.remove('dark');
|
||||
}
|
||||
|
||||
// Store preference in localStorage
|
||||
localStorage.setItem('theme', this.isDarkMode ? 'dark' : 'light');
|
||||
|
||||
// Dispatch custom event for other components that might need to react
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('themeChanged', {
|
||||
detail: { theme: this.isDarkMode ? 'dark' : 'light' },
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current theme from localStorage or system preference
|
||||
*/
|
||||
private getCurrentTheme(): string {
|
||||
// First check localStorage
|
||||
const savedTheme = localStorage.getItem('theme');
|
||||
if (savedTheme) {
|
||||
return savedTheme;
|
||||
}
|
||||
|
||||
// Fallback to system preference
|
||||
if (
|
||||
window.matchMedia &&
|
||||
window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||
) {
|
||||
return 'dark';
|
||||
}
|
||||
|
||||
return 'light';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
/* This simpler approach uses your existing global variables directly */
|
||||
|
||||
.nier-logo-container {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
padding: 0.25rem;
|
||||
overflow: hidden;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.nier-logo {
|
||||
position: relative;
|
||||
color: var(--nier-dark, #2C2A21); /* Using nier-dark color with fallback */
|
||||
text-shadow: 0 0 2px rgba(44, 42, 33, 0.8);
|
||||
color: var(--color-nier-text-dark); /* Use your global variable */
|
||||
text-shadow: 0 0 2px var(--color-nier-text-dark);
|
||||
animation: nier-fade-in 2.5s ease-out forwards, nier-subtle-pulse 4s 2.5s infinite;
|
||||
transition: color 0.3s ease, text-shadow 0.3s ease;
|
||||
}
|
||||
|
||||
.nier-logo::before {
|
||||
@@ -19,9 +23,10 @@
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-shadow: 0 0 3px var(--nier-dark, #2C2A21);
|
||||
text-shadow: 0 0 3px var(--color-nier-text-dark);
|
||||
opacity: 0;
|
||||
animation: nier-glitch 6s 3s infinite;
|
||||
transition: text-shadow 0.3s ease;
|
||||
}
|
||||
|
||||
.nier-logo::after {
|
||||
@@ -31,9 +36,10 @@
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-shadow: -1px 0 1px rgba(44, 42, 33, 0.6);
|
||||
text-shadow: -1px 0 1px var(--color-nier-text-dark);
|
||||
opacity: 0;
|
||||
animation: nier-glitch-2 5s 3s infinite;
|
||||
transition: text-shadow 0.3s ease;
|
||||
}
|
||||
|
||||
.nier-scan-line {
|
||||
@@ -45,12 +51,13 @@
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
transparent 0%,
|
||||
rgba(44, 42, 33, 0.05) 50%,
|
||||
color-mix(in srgb, var(--color-nier-text-dark) 5%, transparent) 50%,
|
||||
transparent 100%
|
||||
);
|
||||
animation: nier-scan 3s linear infinite;
|
||||
z-index: 2;
|
||||
pointer-events: none;
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
|
||||
.nier-blocks {
|
||||
@@ -67,10 +74,11 @@
|
||||
.nier-blocks::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
background: rgba(44, 42, 33, 0.1);
|
||||
width: 10px;
|
||||
height: 6px;
|
||||
background: color-mix(in srgb, var(--color-nier-text-dark) 10%, transparent);
|
||||
animation: nier-blocks 10s linear infinite;
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
|
||||
.nier-blocks::before {
|
||||
@@ -87,153 +95,7 @@
|
||||
animation-delay: 3s;
|
||||
}
|
||||
|
||||
/* Animations */
|
||||
@keyframes nier-fade-in {
|
||||
0% {
|
||||
opacity: 0;
|
||||
clip-path: inset(0 100% 0 0);
|
||||
}
|
||||
20% {
|
||||
opacity: 0.3;
|
||||
clip-path: inset(0 80% 0 0);
|
||||
}
|
||||
40% {
|
||||
opacity: 0.5;
|
||||
clip-path: inset(0 60% 0 0);
|
||||
}
|
||||
60% {
|
||||
opacity: 0.7;
|
||||
clip-path: inset(0 40% 0 0);
|
||||
}
|
||||
80% {
|
||||
opacity: 0.9;
|
||||
clip-path: inset(0 20% 0 0);
|
||||
}
|
||||
95% {
|
||||
opacity: 1;
|
||||
clip-path: inset(0 5% 0 0);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
clip-path: inset(0 0 0 0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes nier-subtle-pulse {
|
||||
0%, 100% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes nier-glitch {
|
||||
0%, 100% {
|
||||
opacity: 0;
|
||||
transform: translateX(0);
|
||||
}
|
||||
10.5% {
|
||||
opacity: 0.5;
|
||||
transform: translateX(3px);
|
||||
}
|
||||
11% {
|
||||
opacity: 0;
|
||||
transform: translateX(0);
|
||||
}
|
||||
29.5% {
|
||||
opacity: 0;
|
||||
transform: translateX(0);
|
||||
}
|
||||
30% {
|
||||
opacity: 0.4;
|
||||
transform: translateX(-3px);
|
||||
}
|
||||
30.5% {
|
||||
opacity: 0;
|
||||
transform: translateX(0);
|
||||
}
|
||||
80% {
|
||||
opacity: 0;
|
||||
transform: translateX(0);
|
||||
}
|
||||
80.5% {
|
||||
opacity: 0.6;
|
||||
transform: translateX(5px);
|
||||
}
|
||||
81% {
|
||||
opacity: 0;
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes nier-glitch-2 {
|
||||
0%, 100% {
|
||||
opacity: 0;
|
||||
transform: translateX(0);
|
||||
}
|
||||
10.5% {
|
||||
opacity: 0;
|
||||
transform: translateX(0);
|
||||
}
|
||||
11% {
|
||||
opacity: 0.4;
|
||||
transform: translateX(-2px);
|
||||
}
|
||||
11.5% {
|
||||
opacity: 0;
|
||||
transform: translateX(0);
|
||||
}
|
||||
50% {
|
||||
opacity: 0;
|
||||
transform: translateX(0);
|
||||
}
|
||||
50.5% {
|
||||
opacity: 0.4;
|
||||
transform: translateX(2px);
|
||||
}
|
||||
51% {
|
||||
opacity: 0;
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes nier-scan {
|
||||
0% {
|
||||
transform: translateY(-100%);
|
||||
}
|
||||
100% {
|
||||
transform: translateY(100%);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes nier-blocks {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(0) translateX(0);
|
||||
}
|
||||
10% {
|
||||
opacity: 0.8;
|
||||
}
|
||||
30% {
|
||||
opacity: 0.6;
|
||||
transform: translateY(20px) translateX(10px);
|
||||
}
|
||||
50% {
|
||||
opacity: 0.4;
|
||||
transform: translateY(40px) translateX(20px);
|
||||
}
|
||||
70% {
|
||||
opacity: 0.2;
|
||||
transform: translateY(60px) translateX(30px);
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: translateY(100px) translateX(40px);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add this for the small border and interface details */
|
||||
/* Border and interface details */
|
||||
.nier-logo-container::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
@@ -241,11 +103,12 @@
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 1px solid rgba(44, 42, 33, 0.3);
|
||||
border: 1px solid var(--color-nier-border);
|
||||
pointer-events: none;
|
||||
transition: border-color 0.3s ease;
|
||||
}
|
||||
|
||||
/* Optional: Add small interface dots in the corner */
|
||||
/* Interface dots in the corner */
|
||||
.nier-logo-container::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
@@ -253,12 +116,65 @@
|
||||
right: 5px;
|
||||
width: 3px;
|
||||
height: 3px;
|
||||
background-color: rgba(44, 42, 33, 0.6);
|
||||
background-color: var(--color-nier-text-dark);
|
||||
box-shadow:
|
||||
-6px 0 0 rgba(44, 42, 33, 0.6),
|
||||
-12px 0 0 rgba(44, 42, 33, 0.6),
|
||||
0 6px 0 rgba(44, 42, 33, 0.6),
|
||||
-6px 6px 0 rgba(44, 42, 33, 0.6),
|
||||
-12px 6px 0 rgba(44, 42, 33, 0.6);
|
||||
-6px 0 0 var(--color-nier-text-dark),
|
||||
-12px 0 0 var(--color-nier-text-dark),
|
||||
0 6px 0 var(--color-nier-text-dark),
|
||||
-6px 6px 0 var(--color-nier-text-dark),
|
||||
-12px 6px 0 var(--color-nier-text-dark);
|
||||
pointer-events: none;
|
||||
transition: background-color 0.3s ease, box-shadow 0.3s ease;
|
||||
}
|
||||
|
||||
/* Animations unchanged */
|
||||
@keyframes nier-fade-in {
|
||||
0% { opacity: 0; clip-path: inset(0 100% 0 0); }
|
||||
20% { opacity: 0.3; clip-path: inset(0 80% 0 0); }
|
||||
40% { opacity: 0.5; clip-path: inset(0 60% 0 0); }
|
||||
60% { opacity: 0.7; clip-path: inset(0 40% 0 0); }
|
||||
80% { opacity: 0.9; clip-path: inset(0 20% 0 0); }
|
||||
95% { opacity: 1; clip-path: inset(0 5% 0 0); }
|
||||
100% { opacity: 1; clip-path: inset(0 0 0 0); }
|
||||
}
|
||||
|
||||
@keyframes nier-subtle-pulse {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.9; }
|
||||
}
|
||||
|
||||
@keyframes nier-glitch {
|
||||
0%, 100% { opacity: 0; transform: translateX(0); }
|
||||
10.5% { opacity: 0.5; transform: translateX(3px); }
|
||||
11% { opacity: 0; transform: translateX(0); }
|
||||
29.5% { opacity: 0; transform: translateX(0); }
|
||||
30% { opacity: 0.4; transform: translateX(-3px); }
|
||||
30.5% { opacity: 0; transform: translateX(0); }
|
||||
80% { opacity: 0; transform: translateX(0); }
|
||||
80.5% { opacity: 0.6; transform: translateX(5px); }
|
||||
81% { opacity: 0; transform: translateX(0); }
|
||||
}
|
||||
|
||||
@keyframes nier-glitch-2 {
|
||||
0%, 100% { opacity: 0; transform: translateX(0); }
|
||||
10.5% { opacity: 0; transform: translateX(0); }
|
||||
11% { opacity: 0.4; transform: translateX(-2px); }
|
||||
11.5% { opacity: 0; transform: translateX(0); }
|
||||
50% { opacity: 0; transform: translateX(0); }
|
||||
50.5% { opacity: 0.4; transform: translateX(2px); }
|
||||
51% { opacity: 0; transform: translateX(0); }
|
||||
}
|
||||
|
||||
@keyframes nier-scan {
|
||||
0% { transform: translateY(-100%); }
|
||||
100% { transform: translateY(100%); }
|
||||
}
|
||||
|
||||
@keyframes nier-blocks {
|
||||
0% { opacity: 0; transform: translateY(0) translateX(0); }
|
||||
10% { opacity: 0.8; }
|
||||
30% { opacity: 0.6; transform: translateY(20px) translateX(10px); }
|
||||
50% { opacity: 0.4; transform: translateY(40px) translateX(20px); }
|
||||
70% { opacity: 0.2; transform: translateY(60px) translateX(30px); }
|
||||
100% { opacity: 0; transform: translateY(100px) translateX(40px); }
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<div class="nier-logo-container">
|
||||
<p class="font-terminal-nier text-8xl nier-logo" data-text="AB">AB</p>
|
||||
<div class="nier-scan-line"></div>
|
||||
<div class="nier-blocks"></div>
|
||||
<p class="font-terminal-nier text-8xl nier-logo nier-dark" data-text="AB">AB</p>
|
||||
<div class="nier-scan-line nier-dark"></div>
|
||||
<div class="nier-blocks nier-dark"></div>
|
||||
</div>
|
||||
|
||||
@@ -24,9 +24,69 @@
|
||||
--color-nier-grid: #bfbcad; /* Grid lines */
|
||||
--color-nier-accent: #292925; /* Dark accent */
|
||||
--color-nier-highlight: #5a5a50; /* Highlight for selection */
|
||||
|
||||
/* Checkered background colors */
|
||||
--color-nier-checkered-bg: #d1cdb7; /* Slightly darker than main bg */
|
||||
--color-nier-checkered-grid: #ccc8b1; /* Grid lines for checkered pattern */
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
/* Inverted colors for dark mode */
|
||||
--color-nier-bg: #292925; /* Inverted from text-dark */
|
||||
--color-nier-dark: #adaba0; /* Inverted from mid */
|
||||
--color-nier-mid: #5a5a50; /* Inverted from dark */
|
||||
--color-nier-text-dark: #dcd8c0; /* Inverted from bg */
|
||||
--color-nier-text-light: #292925; /* Inverted from text-dark */
|
||||
--color-nier-border: #5a5a50; /* Darkened border */
|
||||
--color-nier-grid: #3f3e39; /* Darkened grid */
|
||||
--color-nier-accent: #dcd8c0; /* Inverted from accent */
|
||||
--color-nier-highlight: #adaba0; /* Inverted from highlight */
|
||||
|
||||
/* Inverted checkered background colors */
|
||||
--color-nier-checkered-bg: #121210; /* Dark background for checkered pattern */
|
||||
--color-nier-checkered-grid: #323232; /* Grid lines for dark checkered pattern */
|
||||
}
|
||||
}
|
||||
|
||||
/* Manual dark mode class for toggle functionality */
|
||||
.dark {
|
||||
/* Same inverted colors as media query */
|
||||
--color-nier-bg: #292925; /* Inverted from text-dark */
|
||||
--color-nier-dark: #adaba0; /* Inverted from mid */
|
||||
--color-nier-mid: #5a5a50; /* Inverted from dark */
|
||||
--color-nier-text-dark: #dcd8c0; /* Inverted from bg */
|
||||
--color-nier-text-light: #292925; /* Inverted from text-dark */
|
||||
--color-nier-border: #5a5a50; /* Darkened border */
|
||||
--color-nier-grid: #3f3e39; /* Darkened grid */
|
||||
--color-nier-accent: #dcd8c0; /* Inverted from accent */
|
||||
--color-nier-highlight: #adaba0; /* Inverted from highlight */
|
||||
|
||||
/* Inverted checkered background colors */
|
||||
--color-nier-checkered-bg: #121210; /* Dark background for checkered pattern */
|
||||
--color-nier-checkered-grid: #323232; /* Grid lines for dark checkered pattern */
|
||||
}
|
||||
|
||||
/* Light mode class to override system preference */
|
||||
.light {
|
||||
/* Original colors */
|
||||
--color-nier-bg: #dcd8c0; /* Main parchment background */
|
||||
--color-nier-dark: #5a5a50; /* Dark UI elements */
|
||||
--color-nier-mid: #adaba0; /* Medium gray UI elements */
|
||||
--color-nier-text-dark: #292925; /* Dark text */
|
||||
--color-nier-text-light: #dcd8c0; /* Light text */
|
||||
--color-nier-border: #a39e8c; /* Border color */
|
||||
--color-nier-grid: #bfbcad; /* Grid lines */
|
||||
--color-nier-accent: #292925; /* Dark accent */
|
||||
--color-nier-highlight: #5a5a50; /* Highlight for selection */
|
||||
|
||||
/* Checkered background colors */
|
||||
--color-nier-checkered-bg: #d1cdb7; /* Slightly darker than main bg */
|
||||
--color-nier-checkered-grid: #ccc8b1; /* Grid lines for checkered pattern */
|
||||
}
|
||||
|
||||
|
||||
@layer tailwind-utilities {
|
||||
/* Font utilities */
|
||||
.font-terminal {
|
||||
@@ -77,23 +137,24 @@
|
||||
border-color: var(--color-nier-accent);
|
||||
}
|
||||
|
||||
|
||||
.checkered-background{
|
||||
background-color: #d1cdb7;
|
||||
/* Checkered background using theme variables */
|
||||
.checkered-background {
|
||||
background-color: var(--color-nier-checkered-bg);
|
||||
background-size: 0.3rem 0.3rem;
|
||||
background-image: linear-gradient(to right, #ccc8b1 1px, rgba(204,200,177,0) 1px),
|
||||
linear-gradient(to bottom, #ccc8b1 1px, rgba(204,200,177,0) 1px);
|
||||
background-image: linear-gradient(to right, var(--color-nier-checkered-grid) 1px, rgba(0, 0, 0, 0) 1px),
|
||||
linear-gradient(to bottom, var(--color-nier-checkered-grid) 1px, rgba(0, 0, 0, 0) 1px);
|
||||
color: var(--color-nier-text-dark);
|
||||
transition: background-color 0.3s ease, background-image 0.3s ease, color 0.3s ease;
|
||||
}
|
||||
|
||||
.checkered-bg-dark {
|
||||
background-color: #121210; /* Almost black background */
|
||||
background-size: 4px 4px; /* Small grid pattern */
|
||||
background-image: linear-gradient(to right, rgba(50, 50, 50, 0.3) 1px, rgba(0, 0, 0, 0) 1px),
|
||||
linear-gradient(to bottom, rgba(50, 50, 50, 0.3) 1px, rgba(0, 0, 0, 0) 1px);
|
||||
color: #bbb9ad; /* Light gray with slight sepia tone for text */
|
||||
font-family: 'Major Mono Display', monospace; /* Using your terminal-nier font */
|
||||
min-height: 100vh;
|
||||
padding: 2rem;
|
||||
position: relative;
|
||||
/* Additional utility for grid-based layouts */
|
||||
.nier-grid {
|
||||
display: grid;
|
||||
background-color: var(--color-nier-bg);
|
||||
background-size: 2rem 2rem;
|
||||
background-image: linear-gradient(to right, var(--color-nier-grid) 1px, rgba(0, 0, 0, 0) 1px),
|
||||
linear-gradient(to bottom, var(--color-nier-grid) 1px, rgba(0, 0, 0, 0) 1px);
|
||||
border: 1px solid var(--color-nier-border);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user