diff --git a/projects/acg-website-showcase/multipage/css/styles.css b/projects/acg-website-showcase/multipage/css/styles.css index 6f12618..0b30688 100644 --- a/projects/acg-website-showcase/multipage/css/styles.css +++ b/projects/acg-website-showcase/multipage/css/styles.css @@ -27,6 +27,13 @@ --f-mono: "JetBrains Mono", ui-monospace, "Cascadia Mono", Consolas, monospace; --shadow: 0 1px 0 var(--rule), 0 24px 44px -30px rgba(22, 18, 15, 0.4); + + /* Timing & easing for controlled mechanical motion */ + --t-fast: 80ms; + --t-med: 140ms; + --t-slow: 220ms; + --ease: cubic-bezier(0.21, 0.92, 0.2, 1); + --ease-snap: cubic-bezier(0.23, 1, 0.32, 1); } [data-theme="dark"] { @@ -241,11 +248,27 @@ h3 { font-size: 1.5rem; font-weight: 600; } letter-spacing: 0.01em; display: inline-flex; align-items: center; gap: 0.6rem; padding: 0.7rem 1.4rem; border: 1px solid transparent; border-radius: 2px; - cursor: pointer; text-decoration: none; transition: transform 0.15s ease, background 0.2s ease; + cursor: pointer; text-decoration: none; + transition: + transform var(--t-fast) var(--ease-snap), + box-shadow var(--t-fast) ease, + background var(--t-med) ease, + border-color var(--t-med) ease, + filter var(--t-fast) ease; + will-change: transform; +} +.btn:hover { + transform: translateY(-1px); + box-shadow: 0 1px 0 var(--rule); +} +.btn:active { + transform: translateY(1px) scale(0.985); } -.btn:active { transform: translateY(1px); } .btn--primary { background: var(--accent); color: var(--on-accent); } -.btn--primary:hover { color: var(--on-accent); filter: brightness(1.05); } +.btn--primary:hover { + color: var(--on-accent); + filter: brightness(1.08); +} .btn--ghost { background: transparent; color: var(--ink); border-color: var(--rule); } .btn--ghost:hover { border-color: var(--accent); color: var(--ink); } .btn .arrow { font-family: var(--f-mono); } @@ -274,8 +297,24 @@ h3 { font-size: 1.5rem; font-weight: 600; } .nav a { font-family: var(--f-body); font-size: 0.92rem; color: var(--ink-2); text-decoration: none; } .nav a:hover { color: var(--ink); } +.nav__link { + position: relative; + transition: color var(--t-fast); +} +.nav__link::after { + content: ""; + position: absolute; + left: 0; bottom: -1px; + width: 0; height: 1px; + background: var(--accent); + transition: width var(--t-med) var(--ease); +} +.nav__link:hover::after { + width: 100%; +} .nav__link--cta { color: var(--accent-ink) !important; font-weight: 600; } .nav__link--cta:hover { color: var(--accent) !important; } +.nav__link--cta::after { background: var(--accent); } .nav__phone { font-family: var(--f-mono); color: var(--ink) !important; font-weight: 500; } .theme-toggle, .nav__toggle { background: transparent; border: 1px solid var(--rule); border-radius: 2px; @@ -367,9 +406,17 @@ h3 { font-size: 1.5rem; font-weight: 600; } .svc { display: grid; grid-template-columns: 2.4rem 1fr auto; gap: 1.25rem; align-items: baseline; padding-block: calc(var(--base) * 0.9); - border-bottom: 1px solid var(--rule); transition: background 0.2s ease; + border-bottom: 1px solid var(--rule); + transition: + background-color var(--t-med) ease, + border-color var(--t-fast) ease, + transform var(--t-fast) var(--ease-snap); +} +.svc:hover { + background: var(--surface); + border-color: var(--accent); + transform: translateY(-1px); } -.svc:hover { background: var(--surface); } .svc__no { font-family: var(--f-mono); font-size: 0.8rem; color: var(--ink-3); } .svc__name { font-family: var(--f-display); font-size: 1.5rem; font-weight: 600; } .svc__desc { color: var(--ink-2); font-size: 0.98rem; margin-top: 0.25rem; max-width: 60ch; } @@ -384,9 +431,25 @@ h3 { font-size: 1.5rem; font-weight: 600; } .pricing { background: var(--surface); border-block: 1px solid var(--rule); } .rate-card { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px; background: var(--rule); border: 1px solid var(--rule); border-radius: 2px; overflow: hidden; } -.tier { background: var(--paper); padding: calc(var(--base) * 1.5) 1.5rem; position: relative; - align-self: stretch; } -.tier--pop { background: var(--surface-2); box-shadow: inset 0 3px 0 var(--accent); } +.tier { + background: var(--paper); padding: calc(var(--base) * 1.5) 1.5rem; position: relative; + align-self: stretch; + transition: + background-color var(--t-med) ease, + border-color var(--t-fast) ease, + transform var(--t-fast) var(--ease-snap); +} +.tier:hover { + background: var(--surface); + transform: translateY(-1px); +} +.tier--pop { + background: var(--surface-2); + box-shadow: inset 0 3px 0 var(--accent); +} +.tier--pop:hover { + border-color: var(--accent); +} .tier__flag { position: absolute; top: 0; right: 0; font-family: var(--f-mono); font-size: 0.64rem; letter-spacing: 0.16em; text-transform: uppercase; background: var(--accent); color: var(--on-accent); padding: 0.25rem 0.6rem; } @@ -442,9 +505,13 @@ h3 { font-size: 1.5rem; font-weight: 600; } .stepper { display: inline-flex; align-items: stretch; border: 1px solid var(--rule); border-radius: 2px; overflow: hidden; } -.stepper button { width: 44px; min-height: 44px; border: 0; background: var(--surface); - color: var(--ink); font-family: var(--f-mono); font-size: 1.2rem; cursor: pointer; } +.stepper button { + width: 44px; min-height: 44px; border: 0; background: var(--surface); + color: var(--ink); font-family: var(--f-mono); font-size: 1.2rem; cursor: pointer; + transition: background var(--t-med), color var(--t-med), transform var(--t-fast); +} .stepper button:hover { background: var(--accent); color: var(--on-accent); } +.stepper button:active { transform: scale(0.92); } .stepper input { width: 64px; height: 44px; border: 0; text-align: center; background: var(--paper); color: var(--ink); font-family: var(--f-mono); font-size: 1.05rem; font-weight: 600; appearance: textfield; -moz-appearance: textfield; } @@ -470,7 +537,8 @@ select:focus, .stepper input:focus, input:focus { outline: 2px solid var(--accen .switch .track { position: absolute; inset: 0; background: var(--surface-2); border: 1px solid var(--rule); border-radius: 2px; transition: background 0.2s; } .switch .knob { position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; - background: var(--ink-3); border-radius: 1px; transition: transform 0.2s, background 0.2s; } + background: var(--ink-3); border-radius: 1px; + transition: transform var(--t-med) var(--ease-snap), background var(--t-med); } .switch input:checked + .track { background: color-mix(in srgb, var(--accent) 35%, var(--surface)); } .switch input:checked + .track + .knob, .switch input:checked ~ .knob { transform: translateX(20px); background: var(--accent); } @@ -511,10 +579,10 @@ select:focus, .stepper input:focus, input:focus { outline: 2px solid var(--accen gap: 1.5rem; align-items: center; color: var(--ink); font-family: var(--f-display); font-size: 1.25rem; font-weight: 600; } .faq__q .pm { font-family: var(--f-mono); color: var(--accent-ink); font-size: 1.4rem; - flex: none; transition: transform 0.2s; } + flex: none; transition: transform var(--t-slow) var(--ease); } .faq__q[aria-expanded="true"] .pm { transform: rotate(45deg); } .faq__a { overflow: hidden; max-height: 0; visibility: hidden; - transition: max-height 0.3s ease, visibility 0.3s ease; } + transition: max-height var(--t-slow) var(--ease), visibility var(--t-slow); } .faq__q[aria-expanded="true"] + .faq__a { visibility: visible; } .faq__a-inner { padding-bottom: calc(var(--base) * 1.1); color: var(--ink-2); max-width: 70ch; } @@ -535,7 +603,17 @@ select:focus, .stepper input:focus, input:focus { outline: 2px solid var(--accen .form-field input, .form-field textarea { width: 100%; font-family: var(--f-body); font-size: 1rem; color: var(--ink); background: var(--paper); border: 1px solid var(--rule); border-radius: 2px; - padding: 0.65rem 0.8rem; } + padding: 0.65rem 0.8rem; + transition: border-color var(--t-fast), background var(--t-med), outline var(--t-fast); +} +.form-field input:focus, +.form-field textarea:focus, +.form-field select:focus { + border-color: var(--accent); + outline: 1px solid color-mix(in srgb, var(--accent) 25%, transparent); + outline-offset: -1px; + background: var(--paper); +} .form-field textarea { min-height: calc(var(--base) * 4); resize: vertical; } .form-note { font-size: 0.82rem; color: var(--ink-3); margin-top: 0.5rem; } @media (max-width: 820px) { .contact .wrap { grid-template-columns: 1fr; } } @@ -661,24 +739,7 @@ select:focus, .stepper input:focus, input:focus { outline: 2px solid var(--accen /* ---- Custom Cursor - REMOVED (restored to normal system cursor) ------- */ -/* ---- Instant State Changes (No Transitions) ---------------------------- */ -.btn, -a, -.tier, -.service-card, -.svc, -.more-link, -.theme-toggle, -.skin-toggle, -.nav__toggle, -.faq__q, -button, -input, -textarea, -select { - transition: none !important; -} - +/* ---- Instant State Changes (Hover Inversion for Buttons/Tiers) -------- */ .btn:hover, .tier:hover { background: var(--ink); @@ -692,14 +753,16 @@ select { transform: translateX(6px); } -/* ---- Clip-Path Wipe Reveals -------------------------------------------- */ +/* ---- Reveal Animations (Opacity + TranslateY with Stagger) ------------ */ .reveal { - clip-path: inset(0 100% 0 0); - animation: reveal-wipe 0.8s cubic-bezier(0.77, 0, 0.175, 1) forwards; + opacity: 0; + transform: translateY(10px); + transition: opacity var(--t-slow) var(--ease), transform var(--t-slow) var(--ease); } .reveal.in { - clip-path: inset(0 0 0 0); + opacity: 1; + transform: none; } @keyframes reveal-wipe { @@ -722,51 +785,65 @@ select { .dispatch-grid { display: grid; - grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); - gap: calc(var(--base) * 1.5); + grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); + gap: 1px; + background: var(--rule); + border: 1px solid var(--rule); margin-top: var(--base); } .dispatch-card { background: var(--paper); - border: 1px solid var(--rule); - padding: calc(var(--base) * 1.25); + padding: 1rem 1.1rem 1.15rem; + border-left: 1px solid var(--rule); position: relative; + transition: + background-color var(--t-med) ease, + border-color var(--t-fast) ease, + border-left-width var(--t-fast) var(--ease-snap), + transform var(--t-fast) var(--ease-snap); +} +.dispatch-card:hover { + background: var(--surface); + border-left-color: var(--accent); + border-left-width: 3px; + transform: translateY(-1px); } .dispatch-card__label { font-family: var(--f-mono); font-size: 0.7rem; + letter-spacing: 0.5px; + color: var(--ink-3); text-transform: uppercase; - letter-spacing: 0.15em; - color: var(--accent-ink); - margin-bottom: 0.75rem; } .dispatch-card__title { font-family: var(--f-display); - font-size: 1.35rem; + font-size: 1.05rem; font-weight: 600; - line-height: 1.15; - margin-bottom: 0.75rem; + line-height: 1.2; + margin: 0.35rem 0 0.45rem; text-transform: none; + transition: color var(--t-med); +} +.dispatch-card:hover .dispatch-card__title { + color: var(--accent-ink); } .dispatch-card__excerpt { color: var(--ink-2); - font-size: 0.92rem; - line-height: 1.5; - margin-bottom: 1rem; + font-size: 0.9rem; + line-height: 1.35; + margin-bottom: 0.7rem; } .dispatch-card__meta { display: flex; justify-content: space-between; - align-items: center; - gap: 1rem; - padding-top: 1rem; - border-top: 1px solid var(--rule); - font-size: 0.8rem; + font-family: var(--f-mono); + font-size: 0.72rem; + color: var(--ink-3); } .dispatch-card__date { @@ -790,7 +867,32 @@ select { } } -/* ---- Radio Ticker Marquee ---------------------------------------------- */ +/* ---- Radio Promo Bar (Thin Brutal Banner) ------------------------------ */ +.radio-promo { + border-block: 1px solid var(--rule); + background: var(--surface); + font-family: var(--f-mono); + font-size: 0.82rem; + padding: 0.4rem 0; + display: flex; + align-items: center; + gap: 0.75rem; + flex-wrap: wrap; +} +.radio-promo strong { + font-family: var(--f-display); + font-size: 0.9rem; + letter-spacing: 0.5px; + color: var(--accent-ink); +} +.radio-promo .time { + background: var(--accent); + color: var(--on-accent); + padding: 1px 6px; + font-weight: 700; +} + +/* ---- Radio Ticker Marquee (Pauseable on Hover) ------------------------- */ .radio-ticker { position: fixed; bottom: 0; @@ -811,6 +913,10 @@ select { animation: ticker-scroll 30s linear infinite; } +.radio-ticker:hover .radio-ticker__track { + animation-play-state: paused; +} + @keyframes ticker-scroll { 0% { transform: translateX(0); } 100% { transform: translateX(-50%); } diff --git a/projects/acg-website-showcase/multipage/js/app.js b/projects/acg-website-showcase/multipage/js/app.js index 6d61b67..c715b6a 100644 --- a/projects/acg-website-showcase/multipage/js/app.js +++ b/projects/acg-website-showcase/multipage/js/app.js @@ -268,7 +268,7 @@ }); } - /* ---- Reveal on scroll ------------------------------------------------- */ + /* ---- Reveal on scroll (with stagger) ---------------------------------- */ var reveals = $$(".reveal"); if ("IntersectionObserver" in window && reveals.length) { var io = new IntersectionObserver(function (entries) { @@ -276,7 +276,11 @@ if (en.isIntersecting) { en.target.classList.add("in"); io.unobserve(en.target); } }); }, { rootMargin: "0px 0px -8% 0px", threshold: 0.08 }); - reveals.forEach(function (el) { io.observe(el); }); + // Add stagger delays for sequential reveal + reveals.forEach(function (el, i) { + el.style.transitionDelay = Math.min(i * 55, 280) + "ms"; + io.observe(el); + }); } else { reveals.forEach(function (el) { el.classList.add("in"); }); }