diff --git a/Frontend/index.html b/Frontend/index.html
index 0fca6f0..d75c0ac 100644
--- a/Frontend/index.html
+++ b/Frontend/index.html
@@ -4,7 +4,7 @@
-
frontend
+ Discogs
diff --git a/Frontend/src/App.css b/Frontend/src/App.css
index f90339d..e7ed7e5 100644
--- a/Frontend/src/App.css
+++ b/Frontend/src/App.css
@@ -1,184 +1,43 @@
-.counter {
- font-size: 16px;
- padding: 5px 10px;
- border-radius: 5px;
- color: var(--accent);
- background: var(--accent-bg);
- border: 2px solid transparent;
- transition: border-color 0.3s;
- margin-bottom: 24px;
-
- &:hover {
- border-color: var(--accent-border);
- }
- &:focus-visible {
- outline: 2px solid var(--accent);
- outline-offset: 2px;
- }
-}
-
-.hero {
- position: relative;
-
- .base,
- .framework,
- .vite {
- inset-inline: 0;
- margin: 0 auto;
- }
-
- .base {
- width: 170px;
- position: relative;
- z-index: 0;
- }
-
- .framework,
- .vite {
- position: absolute;
- }
-
- .framework {
- z-index: 1;
- top: 34px;
- height: 28px;
- transform: perspective(2000px) rotateZ(300deg) rotateX(44deg) rotateY(39deg)
- scale(1.4);
- }
-
- .vite {
- z-index: 0;
- top: 107px;
- height: 26px;
- width: auto;
- transform: perspective(2000px) rotateZ(300deg) rotateX(40deg) rotateY(39deg)
- scale(0.8);
- }
-}
-
-#center {
+.discogsApp {
+ width: min(740px, 92vw);
+ min-height: 96vh;
+ margin: 2vh auto;
display: flex;
flex-direction: column;
- gap: 25px;
- place-content: center;
- place-items: center;
- flex-grow: 1;
-
- @media (max-width: 1024px) {
- padding: 32px 20px 24px;
- gap: 18px;
- }
}
-#next-steps {
+.mainContainer {
+ background-color: var(--white);
+ flex: 724 1 0;
display: flex;
- border-top: 1px solid var(--border);
- text-align: left;
-
- & > div {
- flex: 1 1 0;
- padding: 32px;
- @media (max-width: 1024px) {
- padding: 24px 20px;
- }
- }
-
- .icon {
- margin-bottom: 16px;
- width: 22px;
- height: 22px;
- }
-
- @media (max-width: 1024px) {
- flex-direction: column;
- text-align: center;
- }
+ flex-direction: row;
}
-#docs {
- border-right: 1px solid var(--border);
-
- @media (max-width: 1024px) {
- border-right: none;
- border-bottom: 1px solid var(--border);
- }
+.contentContainer {
+ flex: 0.675 1 0;
+ display: flex;
+ flex-direction: column;
}
-#next-steps ul {
- list-style: none;
- padding: 0;
+.shelvesContainer {
+ flex: 6 1 0;
display: flex;
- gap: 8px;
- margin: 32px 0 0;
-
- .logo {
- height: 18px;
- }
-
- a {
- color: var(--text-h);
- font-size: 16px;
- border-radius: 6px;
- background: var(--social-bg);
- display: flex;
- padding: 6px 12px;
- align-items: center;
- gap: 8px;
- text-decoration: none;
- transition: box-shadow 0.3s;
-
- &:hover {
- box-shadow: var(--shadow);
- }
- .button-icon {
- height: 18px;
- width: 18px;
- }
- }
-
- @media (max-width: 1024px) {
- margin-top: 20px;
- flex-wrap: wrap;
- justify-content: center;
-
- li {
- flex: 1 1 calc(50% - 8px);
- }
-
- a {
- width: 100%;
- justify-content: center;
- box-sizing: border-box;
- }
- }
+ flex-direction: column;
+ gap: 3rem;
+ padding-top: 1rem;
+ margin-bottom: 4rem;
+ overflow: scroll;
}
-#spacer {
- height: 88px;
- border-top: 1px solid var(--border);
- @media (max-width: 1024px) {
- height: 48px;
- }
+.appFooter {
+ background-color: var(--mayo);
+ flex: 140 1 0;
+ border-radius: 0 0 20px 20px;
+ border-top: 3px solid var(--black);
}
-.ticks {
- position: relative;
- width: 100%;
-
- &::before,
- &::after {
- content: '';
- position: absolute;
- top: -4.5px;
- border: 5px solid transparent;
- }
-
- &::before {
- left: 0;
- border-left-color: var(--border);
- }
- &::after {
- right: 0;
- border-right-color: var(--border);
+@media (max-width: 1000px) {
+ .discogsApp {
+ width: 100vw;
}
}
diff --git a/Frontend/src/App.tsx b/Frontend/src/App.tsx
index 9ca8e8d..1c18228 100644
--- a/Frontend/src/App.tsx
+++ b/Frontend/src/App.tsx
@@ -1,121 +1,39 @@
-import { useState } from 'react'
-import heroImg from './assets/hero.png'
-import reactLogo from './assets/react.svg'
-import viteLogo from './assets/vite.svg'
import './App.css'
+import { DecorativeStripes } from './components/DecorativeStripes'
+import { FilterPanel } from './components/FilterPanel'
+import { Header } from './components/Header'
+import { SearchBar } from './components/SearchBar'
+import { Shelf } from './components/Shelf'
-function App() {
- const [count, setCount] = useState(0)
+const shelves = [
+ { artist: 'Radiohead', albums: ['Reckoner', 'Reckoner', 'Reckoner'] },
+ { artist: 'Radiohead', albums: ['Reckoner', 'Reckoner', 'Reckoner'] },
+ { artist: 'Radiohead', albums: ['Reckoner', 'Reckoner', 'Reckoner'] },
+]
+function App() {
return (
- <>
-
-
-
-
Get started
-
- Edit src/App.tsx and save to test HMR
-
-
-
-
-
-
-
-
-
-
-
Documentation
-
Your questions, answered
-
-
-
-
-
Connect with us
-
Join the Vite community
-
-
-
-
-
-
- >
+
+
+
+
+
+
+
+ {shelves.map((shelf, index) => (
+
+ ))}
+
+
+
+
+
+
+
)
}
diff --git a/Frontend/src/components/DecorativeStripes.css b/Frontend/src/components/DecorativeStripes.css
new file mode 100644
index 0000000..d168b99
--- /dev/null
+++ b/Frontend/src/components/DecorativeStripes.css
@@ -0,0 +1,38 @@
+.stripesCont {
+ display: flex;
+ flex-direction: column;
+ flex: 36 1 0;
+}
+
+.stripesCont.vertical {
+ flex-direction: row;
+ flex: 0.048 1 0;
+}
+
+.stripe {
+ flex: 1 1 0;
+}
+
+.stripesCont .stripe:nth-child(1) {
+ background-color: var(--orange);
+ border-top: 2px solid var(--black);
+}
+
+.stripesCont .stripe:nth-child(2) {
+ background-color: var(--mayo);
+}
+
+.stripesCont .stripe:nth-child(3) {
+ background-color: var(--red);
+ border-bottom: 2px solid var(--black);
+}
+
+.stripesCont.vertical .stripe:nth-child(1) {
+ border-top: none;
+ border-left: 2px solid var(--black);
+}
+
+.stripesCont.vertical .stripe:nth-child(3) {
+ border-bottom: none;
+ border-right: 2px solid var(--black);
+}
diff --git a/Frontend/src/components/DecorativeStripes.tsx b/Frontend/src/components/DecorativeStripes.tsx
new file mode 100644
index 0000000..a280bf0
--- /dev/null
+++ b/Frontend/src/components/DecorativeStripes.tsx
@@ -0,0 +1,15 @@
+import './DecorativeStripes.css'
+
+type DecorativeStripesProps = {
+ orientation?: 'horizontal' | 'vertical'
+}
+
+export function DecorativeStripes({ orientation = 'horizontal' }: DecorativeStripesProps) {
+ return (
+
+ )
+}
diff --git a/Frontend/src/components/FilterPanel.css b/Frontend/src/components/FilterPanel.css
new file mode 100644
index 0000000..0f0424a
--- /dev/null
+++ b/Frontend/src/components/FilterPanel.css
@@ -0,0 +1,134 @@
+.filterPanel {
+ flex: 0.275 1 0;
+ min-width: 0;
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ justify-content: end;
+ align-items: center;
+ background-color: var(--white);
+ color: var(--white);
+}
+
+.filterPanelTitle {
+ height: 22%;
+ margin: 0;
+ display: flex;
+ align-items: center;
+ color: var(--dark);
+ font-size: clamp(1rem, 2vw, 1.4rem);
+ font-weight: 400;
+}
+
+.cabinet {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ flex: 9 1 0;
+ width: 80%;
+ background-color: var(--dark);
+ gap: 1rem;
+ border-radius: 6px;
+ padding: 1rem 0 1rem 0;
+}
+
+.feetContainer {
+ flex: 1 1 0;
+ display: flex;
+ justify-content: space-between;
+ width: 70%;
+ flex-direction: row;
+ gap: 80%;
+}
+
+.cabinetFoot {
+ background-color: var(--black);
+ height: 100%;
+ flex: 1 1 0;
+}
+
+.filterShelf {
+ z-index: 1;
+ flex: 3 1 0;
+ width:90%;
+ padding: 0.8rem 0.55rem;
+ background-color: var(--light-dark);
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ gap: 0.6rem;
+ overflow-y: auto;
+ border: 2px black solid;
+}
+
+.favoriteFilter,
+.filterField {
+ font-size: clamp(0.55rem, 1vw, 0.75rem);
+}
+
+.favoriteFilter {
+ display: flex;
+ align-items: center;
+ gap: 0.35rem;
+}
+
+.favoriteFilter input {
+ width: 0.8rem;
+ height: 0.8rem;
+ margin: 0;
+ accent-color: var(--mayo);
+}
+
+.filterField {
+ display: flex;
+ flex-direction: column;
+ gap: 0.2rem;
+}
+
+.filterField input {
+ min-width: 0;
+ width: 100%;
+ padding: 0.2rem 0.3rem;
+ border: 1px solid var(--dark);
+ border-radius: 2px;
+ background-color: var(--white);
+ color: var(--dark);
+ font-size: inherit;
+}
+
+.filterField input::placeholder {
+ color: var(--dark);
+ opacity: 0.75;
+}
+
+.filterShelfDoor {
+ display: flex;
+ flex-direction: row;
+ flex: 2 1 0;
+ gap: 1rem;
+ width: 90%;
+}
+
+.filterShelfDoor span {
+ position: relative;
+ flex: 1 1 0;
+ border: 2px solid var(--black);
+ background-color: var(--light-dark);
+}
+
+.filterShelfDoor span::after {
+ content: '';
+ position: absolute;
+ top: 50%;
+ left: 70%;
+ width: 0.5rem;
+ height: 0.5rem;
+ border-radius: 50%;
+ background-color: var(--white);
+ transform: translate(-50%, -50%);
+}
+
+.filterShelfDoor span:nth-child(2):after {
+ left: 30%;
+}
diff --git a/Frontend/src/components/FilterPanel.tsx b/Frontend/src/components/FilterPanel.tsx
new file mode 100644
index 0000000..6924bf4
--- /dev/null
+++ b/Frontend/src/components/FilterPanel.tsx
@@ -0,0 +1,36 @@
+import './FilterPanel.css'
+
+export function FilterPanel() {
+ return (
+
+ )
+}
diff --git a/Frontend/src/components/Header.css b/Frontend/src/components/Header.css
new file mode 100644
index 0000000..0d9ce3b
--- /dev/null
+++ b/Frontend/src/components/Header.css
@@ -0,0 +1,15 @@
+.appHeader {
+ background-color: var(--white);
+ border-radius: 20px 20px 0 0;
+ padding: 1.2rem 2rem;
+ min-height: 4rem;
+ display: flex;
+ align-items: center;
+}
+
+.appHeader h1 {
+ margin: 0;
+ color: var(--dark);
+ font-size: clamp(2.2rem, 3vw, 3rem);
+ letter-spacing: 0.08em;
+}
diff --git a/Frontend/src/components/Header.tsx b/Frontend/src/components/Header.tsx
new file mode 100644
index 0000000..bb5db56
--- /dev/null
+++ b/Frontend/src/components/Header.tsx
@@ -0,0 +1,9 @@
+import './Header.css'
+
+export function Header() {
+ return (
+
+ )
+}
diff --git a/Frontend/src/components/SearchBar.css b/Frontend/src/components/SearchBar.css
new file mode 100644
index 0000000..7e2a168
--- /dev/null
+++ b/Frontend/src/components/SearchBar.css
@@ -0,0 +1,22 @@
+.searchContainer {
+ flex: 1 1 0;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ padding: 1rem 0 0.5rem;
+}
+
+.searchBar {
+ width: min(80%, 28.5rem);
+ border: none;
+ border-radius: 20px;
+ padding: 0.8rem 1rem;
+ background-color: var(--dark);
+ color: var(--white);
+ font-size: 1rem;
+ box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.15);
+}
+
+.searchBar::placeholder {
+ color: rgba(253, 220, 169, 0.8);
+}
diff --git a/Frontend/src/components/SearchBar.tsx b/Frontend/src/components/SearchBar.tsx
new file mode 100644
index 0000000..472732e
--- /dev/null
+++ b/Frontend/src/components/SearchBar.tsx
@@ -0,0 +1,9 @@
+import './SearchBar.css'
+
+export function SearchBar() {
+ return (
+
+ )
+}
diff --git a/Frontend/src/components/Shelf.css b/Frontend/src/components/Shelf.css
new file mode 100644
index 0000000..4d88e9a
--- /dev/null
+++ b/Frontend/src/components/Shelf.css
@@ -0,0 +1,73 @@
+.shelfCont {
+ flex: 0.333;
+ display: flex;
+ flex-direction: column;
+ position: relative;
+ min-height: 100px;
+}
+
+.leftBrace {
+ background-color: var(--dark);
+ border-right: 2px solid var(--black);
+ position: absolute;
+ width: 4.4%;
+ height: 82%;
+}
+
+.leftSpike {
+ position: absolute;
+ background-color: var(--dark);
+ width: 4.4%;
+ height: 12%;
+ clip-path: polygon(0 0, 100% 100%, 0 100%);
+ top: -11%;
+}
+
+.rightBrace {
+ background-color: var(--dark);
+ border-left: 2px solid var(--black);
+ right: 0;
+ position: absolute;
+ width: 4.4%;
+ height: 82%;
+}
+
+.rightSpike {
+ position: absolute;
+ background-color: var(--dark);
+ width: 4.4%;
+ height: 12%;
+ clip-path: polygon(100% 0, 100% 100%, 0 100%);
+ top: -11%;
+ right: 0;
+}
+
+.midBrace {
+ background-color: var(--light-dark);
+ flex: 0.785 1 0;
+ border-top: 2px solid var(--black);
+ border-bottom: 2px solid var(--black);
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+ align-items: flex-end;
+ gap: 10%;
+ padding: 0 1rem;
+}
+
+.shelfLabel {
+ background-color: var(--dark);
+ flex: 0.225 1 0;
+ border-top: 2px solid var(--black);
+ border-bottom: 2px solid var(--black);
+ color: var(--white);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.shelfLabel p {
+ margin: 0;
+ font-weight: 600;
+ letter-spacing: 0.03em;
+}
diff --git a/Frontend/src/components/Shelf.tsx b/Frontend/src/components/Shelf.tsx
new file mode 100644
index 0000000..f5f4b81
--- /dev/null
+++ b/Frontend/src/components/Shelf.tsx
@@ -0,0 +1,26 @@
+import './Shelf.css'
+import { VinylCard } from './VinylCard'
+
+type ShelfProps = {
+ artist: string
+ albums: string[]
+}
+
+export function Shelf({ artist, albums }: ShelfProps) {
+ return (
+
+
+ {albums.map((album, index) => (
+
+ ))}
+
+
+
+
+
+
+
+ )
+}
diff --git a/Frontend/src/components/VinylCard.css b/Frontend/src/components/VinylCard.css
new file mode 100644
index 0000000..80fa615
--- /dev/null
+++ b/Frontend/src/components/VinylCard.css
@@ -0,0 +1,71 @@
+.vinylBox {
+ height: 90%;
+ aspect-ratio: 1 / 1;
+ background-color: var(--vinyl-olive);
+ position: relative;
+ bottom: -1px;
+ border-radius: 0.2rem;
+}
+
+.vinylBoxCover {
+ background-color: var(--vinyl-olive);
+ width: 100%;
+ height: 50%;
+ position: absolute;
+ bottom: 0;
+ display: flex;
+ border-radius: 0.2rem;
+ align-items: flex-end;
+ justify-content: center;
+ padding-bottom: 0.3rem;
+ box-sizing: border-box;
+}
+
+.vinylBoxCover .vinylTitle {
+ margin: 0;
+ color: #f9f3e9;
+ font-size: 0.7rem;
+ letter-spacing: 0.04em;
+ text-align: center;
+}
+
+.vinyl {
+ background-color: var(--black);
+ height: 90%;
+ aspect-ratio: 1 / 1;
+ border-radius: 50%;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ transition: transform 0.3s ease;
+}
+
+.vinyl:hover {
+ transform: translate(-50%, calc(-50% - 30px));
+}
+
+.vinyl::after {
+ content: '';
+ position: absolute;
+ width: 33%;
+ height: 33%;
+ background-color: var(--vinyl-teal);
+ border-radius: 50%;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+}
+
+.vinyl::before {
+ content: '';
+ position: absolute;
+ width: 4px;
+ height: 4px;
+ background-color: var(--vinyl-olive);
+ border-radius: 50%;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ z-index: 2;
+}
diff --git a/Frontend/src/components/VinylCard.tsx b/Frontend/src/components/VinylCard.tsx
new file mode 100644
index 0000000..d844275
--- /dev/null
+++ b/Frontend/src/components/VinylCard.tsx
@@ -0,0 +1,16 @@
+import './VinylCard.css'
+
+type VinylCardProps = {
+ title: string
+}
+
+export function VinylCard({ title }: VinylCardProps) {
+ return (
+
+ )
+}
diff --git a/Frontend/src/index.css b/Frontend/src/index.css
index 5fb3313..bfc610d 100644
--- a/Frontend/src/index.css
+++ b/Frontend/src/index.css
@@ -1,111 +1,56 @@
:root {
- --text: #6b6375;
- --text-h: #08060d;
- --bg: #fff;
- --border: #e5e4e7;
- --code-bg: #f4f3ec;
- --accent: #aa3bff;
- --accent-bg: rgba(170, 59, 255, 0.1);
- --accent-border: rgba(170, 59, 255, 0.5);
- --social-bg: rgba(244, 243, 236, 0.5);
- --shadow:
- rgba(0, 0, 0, 0.1) 0 10px 15px -3px, rgba(0, 0, 0, 0.05) 0 4px 6px -2px;
-
- --sans: system-ui, 'Segoe UI', Roboto, sans-serif;
- --heading: system-ui, 'Segoe UI', Roboto, sans-serif;
- --mono: ui-monospace, Consolas, monospace;
-
- font: 18px/145% var(--sans);
- letter-spacing: 0.18px;
- color-scheme: light dark;
- color: var(--text);
- background: var(--bg);
+ --white: #fddca9;
+ --red: #c21717;
+ --orange: #fea712;
+ --dark: #562717;
+ --light-dark: #603425;
+ --mayo: #e76219;
+ --black: #000000;
+ --vinyl-black: #171414;
+ --vinyl-dark-red: #5c1f24;
+ --vinyl-red: #8f2929;
+ --vinyl-burgundy: #642b35;
+ --vinyl-brown: #4a3028;
+ --vinyl-orange: #c45a25;
+ --vinyl-mustard: #c08a2e;
+ --vinyl-cream: #e6cfa8;
+ --vinyl-olive: #667044;
+ --vinyl-teal: #356b68;
+ --vinyl-blue: #3d536b;
+ --vinyl-purple: #5a405f;
+
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+ line-height: 1.5;
+ font-weight: 400;
+ color: var(--black);
+ background: rgb(37, 36, 36);
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-
- @media (max-width: 1024px) {
- font-size: 16px;
- }
-}
-
-@media (prefers-color-scheme: dark) {
- :root {
- --text: #9ca3af;
- --text-h: #f3f4f6;
- --bg: #16171d;
- --border: #2e303a;
- --code-bg: #1f2028;
- --accent: #c084fc;
- --accent-bg: rgba(192, 132, 252, 0.15);
- --accent-border: rgba(192, 132, 252, 0.5);
- --social-bg: rgba(47, 48, 58, 0.5);
- --shadow:
- rgba(0, 0, 0, 0.4) 0 10px 15px -3px, rgba(0, 0, 0, 0.25) 0 4px 6px -2px;
- }
-
- #social .button-icon {
- filter: invert(1) brightness(2);
- }
}
-#root {
- width: 1126px;
- max-width: 100%;
- margin: 0 auto;
- text-align: center;
- border-inline: 1px solid var(--border);
- min-height: 100svh;
- display: flex;
- flex-direction: column;
+* {
box-sizing: border-box;
}
-body {
- margin: 0;
-}
-
-h1,
-h2 {
- font-family: var(--heading);
- font-weight: 500;
- color: var(--text-h);
+html {
+ background-color: rgb(37, 36, 36);
}
-h1 {
- font-size: 56px;
- letter-spacing: -1.68px;
- margin: 32px 0;
- @media (max-width: 1024px) {
- font-size: 36px;
- margin: 20px 0;
- }
-}
-h2 {
- font-size: 24px;
- line-height: 118%;
- letter-spacing: -0.24px;
- margin: 0 0 8px;
- @media (max-width: 1024px) {
- font-size: 20px;
- }
-}
-p {
+body {
margin: 0;
+ min-height: 100vh;
+ background: rgb(37, 36, 36);
}
-code,
-.counter {
- font-family: var(--mono);
- display: inline-flex;
- border-radius: 4px;
- color: var(--text-h);
+#root {
+ min-height: 100vh;
}
-code {
- font-size: 15px;
- line-height: 135%;
- padding: 4px 8px;
- background: var(--code-bg);
+input,
+button,
+textarea,
+select {
+ font: inherit;
}
diff --git a/docs/AI-Usage.md b/docs/AI-Usage.md
index 07b5e02..ffb730c 100644
--- a/docs/AI-Usage.md
+++ b/docs/AI-Usage.md
@@ -22,3 +22,5 @@ Different group members use different harnesses and models, according to persona
| 29.09.2026 | Daniel | Mistral Vibe Work | Find fitting labels for issues and PRs for the project |
| 9.10.2026 | Daniel | Mistral Vibe Work | Help with freeing disk space on VM and make a list over usefull postgreSQL command |
| 2026-10-09 | Henrik | Mistral Vibe Code | Generation of helper script for parsing the dataset to appropriate insert commands for the database. |
+| 14.10.2026 | Anton | Microsoft Copilot | Used to help "convert" a html/css design i made based on figma sketch to react/typescript components. |
+| 15.10.2026 | Anton | Microsoft Copilot | Used to make the foundation for filterPanel component based on picture from Figma, but it was very bad so most was changed. |
Connect with us
-Join the Vite community
---
-
-
- GitHub
-
-
- -
-
-
- Discord
-
-
- -
-
-
- X.com
-
-
- -
-
-
- Bluesky
-
-
-
-