From 5fe6ac671660e0e005e054fc54e53faf33a0fc5d Mon Sep 17 00:00:00 2001 From: Sara Date: Sun, 19 Oct 2025 22:41:54 +0200 Subject: [PATCH] feat: Add profile card for codeUser073 --- .DS_Store | Bin 0 -> 6148 bytes .idea/.gitignore | 8 + .idea/Introduction.iml | 12 + .idea/copilot.data.migration.agent.xml | 6 + .idea/copilot.data.migration.ask.xml | 6 + .idea/copilot.data.migration.ask2agent.xml | 6 + .idea/copilot.data.migration.edit.xml | 6 + .idea/modules.xml | 8 + .idea/vcs.xml | 6 + contributors.json | 9 + profiles/.DS_Store | Bin 0 -> 6148 bytes profiles/codeUser073/.DS_Store | Bin 0 -> 6148 bytes profiles/codeUser073/assets/.DS_Store | Bin 0 -> 6148 bytes .../codeUser073/assets/images/profile.png | Bin 0 -> 1589 bytes profiles/codeUser073/css/style.css | 253 ++++++++++++++++++ profiles/codeUser073/index.html | 64 +++++ profiles/codeUser073/js/main.js | 115 ++++++++ 17 files changed, 499 insertions(+) create mode 100644 .DS_Store create mode 100644 .idea/.gitignore create mode 100644 .idea/Introduction.iml create mode 100644 .idea/copilot.data.migration.agent.xml create mode 100644 .idea/copilot.data.migration.ask.xml create mode 100644 .idea/copilot.data.migration.ask2agent.xml create mode 100644 .idea/copilot.data.migration.edit.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 profiles/.DS_Store create mode 100644 profiles/codeUser073/.DS_Store create mode 100644 profiles/codeUser073/assets/.DS_Store create mode 100644 profiles/codeUser073/assets/images/profile.png create mode 100644 profiles/codeUser073/css/style.css create mode 100644 profiles/codeUser073/index.html create mode 100644 profiles/codeUser073/js/main.js diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..ea99c758ccb1f8a1dcdb31f71f7d7f674b9dda1f GIT binary patch literal 6148 zcmeHKyG{c!5S)b+C()#&^e^xSRusN~A3!7^A)R!Hi2f?RE1$;fqeyhng(jMn)?=@C zY9C%tQ3^Khr(uNO$8rC>)|36Qdk+;pO-~ ck}|LPocq0SP7FHZK_}{Gz;%&Hf&W(E2XOfnpa1{> literal 0 HcmV?d00001 diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/Introduction.iml b/.idea/Introduction.iml new file mode 100644 index 0000000..24643cc --- /dev/null +++ b/.idea/Introduction.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/copilot.data.migration.agent.xml b/.idea/copilot.data.migration.agent.xml new file mode 100644 index 0000000..4ea72a9 --- /dev/null +++ b/.idea/copilot.data.migration.agent.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/copilot.data.migration.ask.xml b/.idea/copilot.data.migration.ask.xml new file mode 100644 index 0000000..7ef04e2 --- /dev/null +++ b/.idea/copilot.data.migration.ask.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/copilot.data.migration.ask2agent.xml b/.idea/copilot.data.migration.ask2agent.xml new file mode 100644 index 0000000..1f2ea11 --- /dev/null +++ b/.idea/copilot.data.migration.ask2agent.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/copilot.data.migration.edit.xml b/.idea/copilot.data.migration.edit.xml new file mode 100644 index 0000000..8648f94 --- /dev/null +++ b/.idea/copilot.data.migration.edit.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..2107307 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/contributors.json b/contributors.json index 6335866..b39b304 100644 --- a/contributors.json +++ b/contributors.json @@ -61,5 +61,14 @@ "github_profile_url": "https://github.com/seobysoumik", "project_netlify_link": "https://soumik-profile-card.netlify.app/", "tags": ["animated", "light-theme"] + }, + { + "name": "Sara", + "occupation": "Student", + "place": "Europe", + "bio": "Pationate about learning new things and exploring the world of computer science.", + "github_profile_url": "https://github.com/codeUser073", + "project_netlify_link": "https://profile-card-073.netlify.app/", + "tags": ["minimalist", "animation", "dark-theme", "light-theme","pixel"] } ] \ No newline at end of file diff --git a/profiles/.DS_Store b/profiles/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..879e5e8b0e575cfb5a869c74b8c1da2113247209 GIT binary patch literal 6148 zcmeHKyG{c!5S)b+k#^56 zwmik{Edbko4EMkqz>@BWPao#y`|dNlsfZEjJmVQByx|>pc${Vb9&qjo2aFiV{K`I37JkCIzH`6p#W^Knh$)fhw%a)rHQ}F;YMZT#o|&eQ0#YUN|Mjr-MVZ0K^5u zVVp-VL2Mo%_QENV5t=2Hm{hA4!;;Q;tGr$~B_+jd+KDr4j6YR8!#I=Jn~OR+oDkc zDnJFO02QDDA66g>>}dSqb9o#UpaQ?IfPEhd+^{CLf&S^h;4J`ffUq0p-b(U%pabM+2j!Q2{DI1*iZOpaKt9AWLlX_VAN=AQhkj&#r)d9}3*CCXRvr>A>JE0C0}58|L0i z0E-2HHE|3?1g1d+2351g(4Zq;GOs3%fk79|=0o#l%??HVcAQ^4U9<*rqykjnUV)cb zwpRaF@L&4>dlFYvfC~I81$5rO_Z^;;wRQ41tF;BbhFi`RZicy2FnBozdO60z%JIUJ bBCpsS`!#V4bUNZr2l8jYbfHm!zgFM|YL^v< literal 0 HcmV?d00001 diff --git a/profiles/codeUser073/assets/images/profile.png b/profiles/codeUser073/assets/images/profile.png new file mode 100644 index 0000000000000000000000000000000000000000..ccf5424d3eb107676f053d98c994ca660354a579 GIT binary patch literal 1589 zcmeAS@N?(olHy`uVBq!ia0y~yU|a&i985rwk9x<(tB?jST-^X9pUp3uvTy!o}6`;ncuxN zKK7FH&#BLPFKnN`9vB*H{K7;fl3e zzs>nFulT&g>=PnEX z;4MEg{d&~vFKxT4o~(ZXO8EDIzMnj-qaIj#J=}WDYA@r1`JdD1SE&BsU|{(F|B9Xo UfBzZ*P<6oI>FVdQ&MBb@05!QAvj6}9 literal 0 HcmV?d00001 diff --git a/profiles/codeUser073/css/style.css b/profiles/codeUser073/css/style.css new file mode 100644 index 0000000..73f41bc --- /dev/null +++ b/profiles/codeUser073/css/style.css @@ -0,0 +1,253 @@ +/* ===== design tokens ===== */ +:root{ + --paper:#f7f7f7; + --ink:#111; + --muted:#666; + --card:#fff; + --accent:#ff6b00; + --accent-2:#0ad35e; + --border:#111; + --shadow:#111; + --elev-shadow: rgba(0,0,0,0.95); /* shadow used for elevated elements (buttons/cards) */ + --elev-shadow-strong: rgba(0,0,0,0.95); /* stronger variant (fallback for light mode) */ + --radius:10px; /* small, pixel-ish */ + --mx:10px; + --my:10px; + /* background/grid / noise / ripple tokens */ + --bg-base: #caa5e8; /* main background base color */ + --bg-grid-color: rgba(239,246,239,0.7); /* grid lines used in .bg */ + --noise-opacity: .04; /* opacity of the noise overlay */ + --ripple-color: rgba(255,255,255,0.47); /* button ripple color */ + color-scheme: light; +} +@media (prefers-color-scheme: dark){ + :root{ + --paper:#0f1115; + --ink:#e9eef6; + --muted:#9aa4b2; + --card:#12151c; + --accent:#ff8f3a; + --accent-2:#25e073; + --border:#e9eef6; + --shadow:#000; + --elev-shadow: rgba(255,255,255,0.08); /* light/white-ish shadow in dark mode */ + --elev-shadow-strong: rgba(255,255,255,0.14); /* stronger white for important controls */ + color-scheme: dark; + } +} + +/* bitmap-style font for headings */ +@font-face{ + font-family:"Pixel"; + src: local("Press Start 2P"), + url("https://fonts.gstatic.com/s/pressstart2p/v15/e3t4euO8T-267oIAQAu6jDQyK3nVivY.woff2") format("woff2"); + font-display: swap; +} + +/* ===== page ===== */ +*{box-sizing:border-box} +html,body{height:100%} +body{ + margin:0; + font-family: Inter, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, "Apple Color Emoji","Segoe UI Emoji"; + color:var(--ink); + background:var(--paper); +} + +/* graph-paper background + faint vignette */ +.site{ + position:relative; + min-height:100%; + display:grid; + place-items:center; + padding:40px 18px; +} +.bg{ + position:fixed; inset:0; z-index:-2; + background: var(--bg-base); + background-image: linear-gradient(var(--bg-grid-color) .1em, transparent .1em), linear-gradient(90deg, var(--bg-grid-color) .1em, transparent .1em); + background-size: 3em 3em; + transform: translate3d(var(--mx, 0px), var(--my, 0px), 0); + transition: transform .06s linear; +} +.noise{ + position:fixed; inset:0; z-index:-1; pointer-events:none; + background-image:url("data:image/svg+xml;utf8,"); + background-size:110px 110px; + opacity: var(--noise-opacity); +} + +/* ===== card ===== */ +.card{ + position:relative; + width:min(720px, 92vw); + padding:24px clamp(18px, 4vw, 28px); + background:var(--card); + border:2px solid var(--border); + border-radius:var(--radius); + /* chunky pixel shadow */ + box-shadow: + 0 0 0 2px var(--border) inset, + 0 0 0 0 var(--elev-shadow), + 6px 6px 0 0 var(--elev-shadow); +} + +/* pixel corner “brackets” */ +.ring{ + pointer-events:none; +} +.card::before, +.card::after{ + content:""; + position:absolute; + width:16px; height:16px; border:2px solid var(--accent); +} +.card::before{ left:10px; top:10px; border-right:none; border-bottom:none; } +.card::after{ right:10px; bottom:10px; border-left:none; border-top:none; } + +/* header */ +.id{ + display:grid; grid-template-columns:auto 1fr; gap:14px 16px; align-items:center; +} +.avatar-wrap{ width:84px; height:84px; position:relative } +.avatar{ + width:84px; height:84px; border-radius:6px; image-rendering:pixelated; + object-fit:cover; border:2px solid var(--border); + box-shadow:4px 4px 0 0 var(--elev-shadow); +} + +/* tiny “online” LED */ + + + +.name{ + margin:0; font-family:"Pixel", monospace; + font-size: clamp(18px, 3.8vw, 24px); + letter-spacing:.04em; +} +.title{ margin:4px 0 0; color:var(--muted); font-weight:700; text-transform:uppercase; font-size:12px } +.meta{ margin:6px 0 0; color:var(--muted); display:flex; gap:8px; align-items:center } + +/* actions */ +.actions{ display:flex; gap:10px; flex-wrap:wrap; margin:18px 0 8px } +.btn{ + --rx:50%; --ry:50%; + position:relative; display:inline-flex; align-items:center; gap:10px; + padding:10px 14px; font-weight:800; text-transform:uppercase; letter-spacing:.06em; + border:2px solid var(--border); background:var(--card); color:var(--ink); + border-radius:8px; text-decoration:none; cursor:pointer; + box-shadow:4px 4px 0 0 var(--elev-shadow); + transition: transform .06s ease; +} +.btn:active{ transform: translate(2px,2px); box-shadow:2px 2px 0 0 var(--elev-shadow) } +.btn.primary{ background:var(--accent); color:#fff; border-color:var(--border) } +.btn.icon{ width:42px; height:42px; justify-content:center; padding:0 } + +/* pixel ripple using radial gradient positioned by --rx/--ry */ +.btn::after{ + content:""; position:absolute; inset:0; pointer-events:none; + background: radial-gradient(circle at var(--rx, 50%) var(--ry, 50%), var(--ripple-color) 0, transparent 48%); + opacity:0; transform:scale(.9); + transition: opacity .18s ease, transform .18s ease; +} +.btn.is-rippling::after{ opacity:1; transform:scale(1) } + +/* socials */ +.socials{ list-style:none; padding:0; margin:8px 0 0; display:flex; gap:10px } +.socials a{ + width:42px; height:42px; display:grid; place-items:center; + border:2px solid var(--border); background:var(--card); color:var(--ink); + border-radius:8px; text-decoration:none; + box-shadow:4px 4px 0 0 var(--elev-shadow); + transition: transform .06s ease; +} +.socials a:active{ transform: translate(2px,2px); box-shadow:2px 2px 0 0 var(--elev-shadow) } + +/* CRT scanlines overlay for nerd points */ +.card > .scanlines{ display:none } /* reserved */ +.card::marker{ content:"" } + +/* focus */ +.btn:focus-visible, .socials a:focus-visible{ + outline:3px dashed var(--accent); + outline-offset:2px; +} + +/* smooth theme transitions for key UI elements */ +body, .bg, .card, .btn, .btn.primary, .socials a { + transition: background-color .22s ease, color .22s ease, border-color .22s ease, box-shadow .22s ease; +} + +/* responsive */ +@media (max-width:520px){ + .id{ grid-template-columns:1fr; text-align:center } + .avatar-wrap{ margin-inline:auto } +} + +/* --- Explicit theme overrides (put at END of file) --- */ +html[data-theme="light"]{ + color-scheme: light; + --paper:#f7f7f7; + --ink:#111; + --muted:#666; + --card:#fff; + --accent:#ff6b00; + --accent-2:#0ad35e; + --border:#111; + --shadow:#111; + + --bg-base: #caa5e8; + --bg-grid-color: rgba(239,246,239,0.7); + --noise-opacity: .04; + --ripple-color: rgba(255,255,255,0.47); +} + +html[data-theme="dark"]{ + color-scheme: dark; + --paper: rgba(15, 17, 21, 0.46); + --ink:#e9eef6; + --muted:#9aa4b2; + --card:#12151c; + --accent: #6a0bdd; + --accent-2:#25e073; + --border:#e9eef6; + --shadow:#000; + /* background tokens for dark theme */ + --bg-base: #0c1523; /* slightly darker base for the gradient */ + --bg-grid-color: #0b2edd; /* very subtle grid lines in dark */ + --noise-opacity: .06; /* a touch stronger noise in dark */ + --ripple-color: rgba(0,0,0,0.35); /* dark ripple to contrast bright buttons */ + --elev-shadow-strong: rgba(255, 255, 255, 0.94); +} + +/* specific stronger highlight for theme-toggle in dark mode */ +html[data-theme="dark"] #theme-toggle{ + + position: absolute; + right: 18px; + top: 18px; + z-index: 9999; /* sit above background elements so shadow is visible */ + + /* pixel offset shadow plus a soft white glow for visibility */ + box-shadow: + 6px 6px 0 0 var(--elev-shadow-strong), + 0 10px 24px rgba(255,255,255,0.10); + + transition: box-shadow .22s ease, transform .12s ease; +} + +html[data-theme="light"] #theme-toggle{ + + position: absolute; + right: 18px; + top: 18px; + z-index: 9999; /* sit above background elements so shadow is visible */ + + /* pixel offset shadow plus a soft white glow for visibility */ + box-shadow: + 6px 6px 0 0 var(--elev-shadow-strong), + 0 10px 24px rgba(255,255,255,0.10); + + transition: box-shadow .22s ease, transform .12s ease; +} + diff --git a/profiles/codeUser073/index.html b/profiles/codeUser073/index.html new file mode 100644 index 0000000..f40296b --- /dev/null +++ b/profiles/codeUser073/index.html @@ -0,0 +1,64 @@ + + + + + + Intro Card – Your Name + + + + + + + + + +
+ + + + + + +
+ + + + diff --git a/profiles/codeUser073/js/main.js b/profiles/codeUser073/js/main.js new file mode 100644 index 0000000..fc204e6 --- /dev/null +++ b/profiles/codeUser073/js/main.js @@ -0,0 +1,115 @@ +const qs = (s, el=document)=>el.querySelector(s); +const qsa = (s, el=document)=>[...el.querySelectorAll(s)]; +const reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches; + + +//====================================== Interactions ================================================================== +/* parallax graph paper — uses unit fallbacks (0px) to satisfy strict linters */ +const bg = qs(".bg"); +document.addEventListener("pointermove",(e)=>{ + if (reduce) return; + const {innerWidth:w, innerHeight:h} = window; + const ox = (e.clientX / w - .5) * 16; + const oy = (e.clientY / h - .5) * 16; + bg.style.setProperty("--mx", `${-ox}px`); + bg.style.setProperty("--my", `${-oy}px`); +}); + +/* tiny tilt — feels 8-bit when subtle */ +const card = qs(".card"); +let raf=0; +function onMove(e){ + if (reduce) return; + const r = card.getBoundingClientRect(); + const x = (e.clientX - r.left)/r.width - .5; + const y = (e.clientY - r.top)/r.height - .5; + const rx = (y*3).toFixed(2), ry = (-x*3).toFixed(2); + cancelAnimationFrame(raf); + raf = requestAnimationFrame(()=> card.style.transform = `rotateX(${rx}deg) rotateY(${ry}deg)`); +} +function reset(){ card.style.transform = "rotateX(0deg) rotateY(0deg)"; } +card.addEventListener("mousemove", onMove); +card.addEventListener("mouseleave", reset); + +/* pixel ripple — sets --rx/--ry with fallbacks */ +qsa(".btn").forEach(btn=>{ + btn.addEventListener("click",(e)=>{ + const rect = btn.getBoundingClientRect(); + const rx = ((e.clientX - rect.left)/rect.width)*100; + const ry = ((e.clientY - rect.top)/rect.height)*100; + btn.style.setProperty("--rx", `${rx}%`); + btn.style.setProperty("--ry", `${ry}%`); + btn.classList.add("is-rippling"); + setTimeout(()=>btn.classList.remove("is-rippling"), 160); + }); +}); + +/* ensure alt if missing */ +const img = qs(".avatar"); +if (img && !img.getAttribute("alt")) img.setAttribute("alt", "Profile picture"); + +// ====================================== Dark-mode switch with persistence ============================================ +const THEME_KEY = "intro-theme"; // localStorage key +const mq = window.matchMedia("(prefers-color-scheme: dark)"); + +// Safe localStorage helpers (private; gracefully degrade if blocked) +function _safeGetItem(key) { + try { + return localStorage.getItem(key); + } catch (err) { + // localStorage may be disabled (privacy mode) — fall back to null + return null; + } +} +function _safeSetItem(key, value) { + try { + localStorage.setItem(key, value); + } catch (err) { + // ignore write failures + } +} + +function setTheme(theme, {remember=true} = {}) { + document.documentElement.setAttribute("data-theme", theme); + // get the current toggle button at the time of update (may be null if not in DOM yet) + const btn = document.getElementById("theme-toggle"); + if (btn) { + btn.innerHTML = theme === "dark" + ? '' + : ''; + btn.setAttribute('aria-pressed', theme === 'dark' ? 'true' : 'false'); + btn.setAttribute('aria-label', theme === 'dark' ? 'Switch to light theme' : 'Switch to dark theme'); + } + if (remember) _safeSetItem(THEME_KEY, theme); +} + +function getInitialTheme() { + const saved = _safeGetItem(THEME_KEY); + if (saved === "light" || saved === "dark") return saved; + return mq.matches ? "dark" : "light"; +} + +// initialize +setTheme(getInitialTheme(), {remember:false}); + +// Ensure the toggle button is wired even if the script ran before the DOM element existed +document.addEventListener('DOMContentLoaded', () => { + const btn = document.getElementById('theme-toggle'); + if (btn) { + btn.addEventListener('click', () => { + const current = document.documentElement.getAttribute('data-theme'); + setTheme(current === 'dark' ? 'light' : 'dark'); + }); + // update the button visuals to match the already-initialized theme + setTheme(document.documentElement.getAttribute('data-theme'), {remember:false}); + } +}); + +// OPTIONAL: follow system if user never chose manually +// (i.e., no saved key yet). If you want to *always* follow system +// after manual picks, remove the if-condition. +mq.addEventListener?.("change", e => { + if (!_safeGetItem(THEME_KEY)) { + setTheme(e.matches ? "dark" : "light", {remember:false}); + } +});