diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..73e005c2 Binary files /dev/null and b/.DS_Store differ diff --git a/README.md b/README.md index 739cc900..dbca5df0 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,30 @@ -Development of this repository is currently in a halt, due to lack of time. Updates are comming end of June. +# Overlap +- Overlap is a team-first chat assistant that nudges teammates toward each other. +- When someone asks a question, the system checks a shared, opt‑in skills index and, if relevant, suggests which teammate(s) might help — replacing solitary AI answers with socially aware guidance. + +## MVP (minimal viable product) +- Simple web chat UI (single‑page) that sends {user_id, team_id, prompt} to the server. +- Team and user records with a short skills survey (store in SQLite for MVP). +- Backend augmentation: before calling the model, do a fast skill-match (keyword or simple normalization) and inject one short hint into the prompt if a teammate matches. +- Stream model responses back to the client unchanged except for the injected hint. +- Basic seed data, Docker support, and environment variable for the model API key. +- No production auth in MVP (trusted user_id); plan to add auth before public use. + +## User journey (MVP) +1. Join or create a team and complete a quick skills survey. +2. Open chat and ask a question. +3. Server checks team skills and finds possible matches. +4. If a match exists, the reply includes a short suggestion like “Alice knows React — want to connect?” +5. Conversation is logged; skill usage counters may be updated for future recommendations. + +## User personas +#Four User Personnas: + +Sam — Product Manager +Goal: Get a quick, team-aware answer or a referral to the right teammate. +Scenario: Asks “How do we track onboarding metrics?” and is suggested to talk to Maya, who owns analytics. + -working again ; ) -I am very busy at the moment so I would be very thankful for contributions and PR's ## To do - [x] Double confirm when deleting conversation diff --git a/client/css/style.css b/client/css/style.css index a1f69087..f292ddc6 100644 --- a/client/css/style.css +++ b/client/css/style.css @@ -16,800 +16,883 @@ } */ :root { - --colour-1: #000000; - --colour-2: #ccc; - --colour-3: #e4d4ff; - --colour-4: #f0f0f0; - --colour-5: #181818; - --colour-6: #242424; + --colour-1: #000000; + --colour-2: #ccc; + --colour-3: #e4d4ff; + --colour-4: #f0f0f0; + --colour-5: #181818; + --colour-6: #242424; - --accent: #8b3dff; - --blur-bg: #16101b66; - --blur-border: #84719040; - --user-input: #ac87bb; - --conversations: #c7a2ff; + --accent: #8b3dff; + --blur-bg: #16101b66; + --blur-border: #84719040; + --user-input: #ac87bb; + --conversations: #c7a2ff; } :root { - --font-1: "Inter", sans-serif; - --section-gap: 25px; - --border-radius-1: 8px; + --font-1: "Inter", sans-serif; + --section-gap: 25px; + --border-radius-1: 8px; } * { - margin: 0; - padding: 0; - box-sizing: border-box; - position: relative; - font-family: var(--font-1); + margin: 0; + padding: 0; + box-sizing: border-box; + position: relative; + font-family: var(--font-1); +} + +.bottom_buttons button { + display: flex; + align-items: center; + justify-content: center; + text-align: center; + vertical-align: middle; + line-height: normal; } html, body { - scroll-behavior: smooth; - overflow: hidden; + scroll-behavior: smooth; + /* Keep the overall page from scrolling — the app will make the chat + messages area the only scrollable region. This keeps the input and + header always visible. */ + overflow: hidden; + height: 100%; } body { - padding: var(--section-gap); - background: var(--colour-1); - color: var(--colour-3); - min-height: 100vh; + padding: var(--section-gap); + background: var(--colour-1); + color: var(--colour-3); + min-height: 100vh; } .row { - display: flex; - gap: var(--section-gap); - height: 100%; + display: flex; + gap: var(--section-gap); + /* occupy the viewport (accounting for body padding) */ + height: calc(100vh - 2 * var(--section-gap)); } .box { - backdrop-filter: blur(20px); - -webkit-backdrop-filter: blur(20px); - background-color: var(--blur-bg); - height: 100%; - width: 100%; - border-radius: var(--border-radius-1); - border: 1px solid var(--blur-border); + backdrop-filter: blur(20px); + -webkit-backdrop-filter: blur(20px); + background-color: var(--blur-bg); + height: 100%; + width: 100%; + border-radius: var(--border-radius-1); + border: 1px solid var(--blur-border); } .conversations { - max-width: 260px; - padding: var(--section-gap); - overflow: auto; - flex-shrink: 0; - display: flex; - flex-direction: column; - justify-content: space-between; + max-width: 260px; + padding: var(--section-gap); + /* keep the left sidebar static and visible; do not let the page scroll */ + overflow: visible; + /* make the sidebar a fixed column so it doesn't collapse to zero width */ + flex: 0 0 260px; + width: 260px; + display: flex; + flex-direction: column; + justify-content: space-between; } .conversation { - width: 100%; - min-height: 50%; - height: 100vh; - overflow-y: scroll; - overflow-x: hidden; - display: flex; - flex-direction: column; - gap: 15px; + width: 100%; + min-height: 50%; + /* Fill remaining vertical space inside .row. The messages area will + scroll independently; the input stays fixed at the bottom of this box. */ + /* allow the conversation column to grow and take remaining horizontal space */ + flex: 1 1 auto; + height: 100%; + overflow: hidden; + display: flex; + flex-direction: column; + gap: 15px; } .conversation #messages { - width: 100%; - display: flex; - flex-direction: column; - overflow-wrap: break-word; - overflow-y: inherit; - overflow-x: hidden; - padding-bottom: 50px; + width: 100%; + display: flex; + flex-direction: column; + overflow-wrap: break-word; + /* messages area takes remaining space and scrolls */ + flex: 1 1 auto; + overflow-y: auto; + overflow-x: hidden; + padding-bottom: 12px; } .conversation .user-input { - max-height: 10vh; + /* keep input area fixed height so layout is predictable */ + flex: 0 0 auto; } .conversation .user-input input { - font-size: 15px; - width: 100%; - height: 100%; - padding: 12px 15px; - background: none; - border: none; - outline: none; - color: var(--colour-3); + font-size: 15px; + width: 100%; + height: 100%; + padding: 12px 15px; + background: none; + border: none; + outline: none; + color: var(--colour-3); } .conversation .user-input input::placeholder { - color: var(--user-input) + color: var(--user-input); } .gradient:nth-child(1) { - --top: 0; - --right: 0; - --size: 70vw; - --blur: calc(0.5 * var(--size)); - --opacity: 0.3; - animation: zoom_gradient 6s infinite; + --top: 0; + --right: 0; + --size: 70vw; + --blur: calc(0.5 * var(--size)); + --opacity: 0.3; + animation: zoom_gradient 6s infinite; } .gradient { - position: absolute; - z-index: -1; - border-radius: calc(0.5 * var(--size)); - background-color: var(--accent); - background: radial-gradient(circle at center, var(--accent), var(--accent)); - width: 70vw; - height: 70vw; - top: 50%; - right: 0; - transform: translateY(-50%); - filter: blur(calc(0.5 * 70vw)) opacity(var(--opacity)); + position: absolute; + z-index: -1; + border-radius: calc(0.5 * var(--size)); + background-color: var(--accent); + background: radial-gradient(circle at center, var(--accent), var(--accent)); + width: 70vw; + height: 70vw; + top: 50%; + right: 0; + transform: translateY(-50%); + filter: blur(calc(0.5 * 70vw)) opacity(var(--opacity)); } .conversations { - display: flex; - flex-direction: column; - gap: 16px; - flex: auto; - min-width: 0; + display: flex; + flex-direction: column; + gap: 16px; + flex: auto; + min-width: 0; } .conversations .title { - font-size: 14px; - font-weight: 500; + font-size: 14px; + font-weight: 500; } .conversations .convo { - padding: 8px 12px; - display: flex; - gap: 18px; - align-items: center; - user-select: none; - justify-content: space-between; + padding: 8px 12px; + display: flex; + gap: 18px; + align-items: center; + user-select: none; + justify-content: space-between; } .conversations .convo .left { - cursor: pointer; - display: flex; - align-items: center; - gap: 10px; - flex: auto; - min-width: 0; + cursor: pointer; + display: flex; + align-items: center; + gap: 10px; + flex: auto; + min-width: 0; } .conversations i { - color: var(--conversations); - cursor: pointer; + color: var(--conversations); + cursor: pointer; } .convo-title { - color: var(--colour-3); - font-size: 14px; - overflow: hidden; - text-overflow: ellipsis; + color: var(--colour-3); + font-size: 14px; + overflow: hidden; + text-overflow: ellipsis; } .message { - - width: 100%; - overflow-wrap: break-word; - display: flex; - gap: var(--section-gap); - padding: var(--section-gap); - padding-bottom: 0; + width: 100%; + overflow-wrap: break-word; + display: flex; + gap: var(--section-gap); + padding: var(--section-gap); + padding-bottom: 0; } .message:last-child { - animation: 0.6s show_message; + animation: 0.6s show_message; } @keyframes show_message { - from { - transform: translateY(10px); - opacity: 0; - } + from { + transform: translateY(10px); + opacity: 0; + } } .message .user { - max-width: 48px; - max-height: 48px; - flex-shrink: 0; + max-width: 48px; + max-height: 48px; + flex-shrink: 0; } .message .user img { - width: 100%; - height: 100%; - object-fit: cover; - border-radius: 8px; - outline: 1px solid var(--blur-border); + width: 100%; + height: 100%; + object-fit: cover; + border-radius: 8px; + outline: 1px solid var(--blur-border); } .message .user:after { - content: "63"; - position: absolute; - bottom: 0; - right: 0; - height: 60%; - width: 60%; - background: var(--colour-3); - filter: blur(10px) opacity(0.5); - z-index: 10000; + content: "63"; + position: absolute; + bottom: 0; + right: 0; + height: 60%; + width: 60%; + background: var(--colour-3); + filter: blur(10px) opacity(0.5); + z-index: 10000; } .message .content { - display: flex; - flex-direction: column; - gap: 18px; - min-width: 0; + display: flex; + flex-direction: column; + gap: 18px; + min-width: 0; } .message .content p, .message .content li, .message .content code { - font-size: 15px; - line-height: 1.3; + font-size: 15px; + line-height: 1.3; } .message .user i { - position: absolute; - bottom: -6px; - right: -6px; - z-index: 1000; + position: absolute; + bottom: -6px; + right: -6px; + z-index: 1000; } .new_convo { - padding: 8px 12px; - display: flex; - gap: 18px; - align-items: center; - cursor: pointer; - user-select: none; - background: transparent; - border: 1px dashed var(--conversations); - border-radius: var(--border-radius-1); + padding: 8px 12px; + display: flex; + gap: 18px; + align-items: center; + cursor: pointer; + user-select: none; + background: transparent; + border: 1px dashed var(--conversations); + border-radius: var(--border-radius-1); } .new_convo span { - color: var(--colour-3); - font-size: 14px; + color: var(--colour-3); + font-size: 14px; } .new_convo:hover { - border-style: solid; + border-style: solid; } .stop_generating { - position: absolute; - bottom: 118px; - /* left: 10px; + position: absolute; + bottom: 118px; + /* left: 10px; bottom: 125px; right: 8px; */ - left: 50%; - transform: translateX(-50%); - z-index: 1000000; + left: 50%; + transform: translateX(-50%); + z-index: 1000000; } .stop_generating button { - backdrop-filter: blur(20px); - -webkit-backdrop-filter: blur(20px); - background-color: var(--blur-bg); - border-radius: var(--border-radius-1); - border: 1px solid var(--blur-border); - padding: 10px 15px; - color: var(--colour-3); - display: flex; - justify-content: center; - align-items: center; - gap: 12px; - cursor: pointer; - animation: show_popup 0.4s; + backdrop-filter: blur(20px); + -webkit-backdrop-filter: blur(20px); + background-color: var(--blur-bg); + border-radius: var(--border-radius-1); + border: 1px solid var(--blur-border); + padding: 10px 15px; + color: var(--colour-3); + display: flex; + justify-content: center; + align-items: center; + gap: 12px; + cursor: pointer; + animation: show_popup 0.4s; } @keyframes show_popup { - from { - opacity: 0; - transform: translateY(10px); - } + from { + opacity: 0; + transform: translateY(10px); + } } @keyframes hide_popup { - to { - opacity: 0; - transform: translateY(10px); - } + to { + opacity: 0; + transform: translateY(10px); + } } .stop_generating-hiding button { - animation: hide_popup 0.4s; + animation: hide_popup 0.4s; } .stop_generating-hidden button { - display: none; + display: none; } .typing { - position: absolute; - top: -25px; - left: 0; - font-size: 14px; - animation: show_popup 0.4s; + position: absolute; + top: -25px; + left: 0; + font-size: 14px; + animation: show_popup 0.4s; } .typing-hiding { - animation: hide_popup 0.4s; + animation: hide_popup 0.4s; } .typing-hidden { - display: none; + display: none; } input[type="checkbox"] { - height: 0; - width: 0; - display: none; + height: 0; + width: 0; + display: none; } label { - cursor: pointer; - text-indent: -9999px; - width: 50px; - height: 30px; - backdrop-filter: blur(20px); - -webkit-backdrop-filter: blur(20px); - background-color: var(--blur-bg); - border-radius: var(--border-radius-1); - border: 1px solid var(--blur-border); - display: block; - border-radius: 100px; - position: relative; - overflow: hidden; - transition: 0.33s; + cursor: pointer; + text-indent: -9999px; + width: 50px; + height: 30px; + backdrop-filter: blur(20px); + -webkit-backdrop-filter: blur(20px); + background-color: var(--blur-bg); + border-radius: var(--border-radius-1); + border: 1px solid var(--blur-border); + display: block; + border-radius: 100px; + position: relative; + overflow: hidden; + transition: 0.33s; } label:after { - content: ""; - position: absolute; - top: 50%; - transform: translateY(-50%); - left: 5px; - width: 20px; - height: 20px; - background: var(--colour-3); - border-radius: 90px; - transition: 0.33s; + content: ""; + position: absolute; + top: 50%; + transform: translateY(-50%); + left: 5px; + width: 20px; + height: 20px; + background: var(--colour-3); + border-radius: 90px; + transition: 0.33s; } -input:checked+label { - background: var(--blur-border); +input:checked + label { + background: var(--blur-border); } -input:checked+label:after { - left: calc(100% - 5px - 20px); +input:checked + label:after { + left: calc(100% - 5px - 20px); } .buttons { - min-height: 10vh; - display: flex; - align-items: start; - justify-content: left; - width: 100%; + min-height: 10vh; + display: flex; + align-items: start; + justify-content: left; + width: 100%; } .field { - height: fit-content; - display: flex; - align-items: center; - gap: 16px; - padding-right: 15px + height: fit-content; + display: flex; + align-items: center; + gap: 16px; + padding-right: 15px; } .field .about { - font-size: 14px; - color: var(--colour-3); + font-size: 14px; + color: var(--colour-3); } .disable-scrollbars::-webkit-scrollbar { background: transparent; /* Chrome/Safari/Webkit */ width: 0px; } - + .disable-scrollbars { scrollbar-width: none; /* Firefox */ - -ms-overflow-style: none; /* IE 10+ */ + -ms-overflow-style: none; /* IE 10+ */ } select { - -webkit-border-radius: 8px; - -moz-border-radius: 8px; - border-radius: 8px; + -webkit-border-radius: 8px; + -moz-border-radius: 8px; + border-radius: 8px; - -webkit-backdrop-filter: blur(20px); - backdrop-filter: blur(20px); + -webkit-backdrop-filter: blur(20px); + backdrop-filter: blur(20px); - cursor: pointer; - background-color: var(--blur-bg); - border: 1px solid var(--blur-border); - color: var(--colour-3); - display: block; - position: relative; - overflow: hidden; - outline: none; - padding: 8px 16px; + cursor: pointer; + background-color: var(--blur-bg); + border: 1px solid var(--blur-border); + color: var(--colour-3); + display: block; + position: relative; + overflow: hidden; + outline: none; + padding: 8px 16px; - appearance: none; + appearance: none; } .input-box { - display: flex; - align-items: center; - padding-right: 15px; - cursor: pointer; + display: flex; + align-items: center; + padding-right: 15px; + cursor: pointer; } .info { - padding: 8px 12px; - display: flex; - gap: 18px; - align-items: center; - user-select: none; - background: transparent; - border-radius: var(--border-radius-1); - width: 100%; - cursor: default; - border: 1px dashed var(--conversations) + padding: 8px 12px; + display: flex; + gap: 18px; + align-items: center; + user-select: none; + background: transparent; + border-radius: var(--border-radius-1); + width: 100%; + cursor: default; + border: 1px dashed var(--conversations); } .bottom_buttons { - width: 100%; - display: flex; - flex-direction: column; - gap: 10px; + width: 100%; + display: flex; + flex-direction: column; + gap: 10px; } .bottom_buttons button { - padding: 8px 12px; - display: flex; - gap: 18px; - align-items: center; - cursor: pointer; - user-select: none; - background: transparent; - border: 1px solid #c7a2ff; - border-radius: var(--border-radius-1); - width: 100%; + padding: 8px 12px; + display: flex; + gap: 18px; + align-items: center; + cursor: pointer; + user-select: none; + background: transparent; + border: 1px solid #c7a2ff; + border-radius: var(--border-radius-1); + width: 100%; } .bottom_buttons button span { - color: var(--colour-3); - font-size: 14px; + color: var(--colour-3); + font-size: 14px; } .conversations .top { - display: flex; - flex-direction: column; - gap: 16px; - overflow: auto; + display: flex; + flex-direction: column; + gap: 16px; + /* allow the left-top area to scroll vertically if conversation list grows */ + overflow-y: auto; +} + +/* Styles for the conversation list container we render into */ +.conversation-list { + display: flex; + flex-direction: column; + gap: 8px; + max-height: calc(100vh - 260px); + overflow-y: auto; +} + +.conversation-list-items .no-convos { + color: var(--colour-3); + opacity: 0.8; + padding: 8px 12px; + border-radius: 6px; + border: 1px dashed var(--conversations); } #cursor { - line-height: 17px; - margin-left: 3px; - -webkit-animation: blink 0.8s infinite; - animation: blink 0.8s infinite; - width: 7px; - height: 15px; + line-height: 17px; + margin-left: 3px; + -webkit-animation: blink 0.8s infinite; + animation: blink 0.8s infinite; + width: 7px; + height: 15px; } @keyframes blink { - 0% { - background: #ffffff00; - } + 0% { + background: #ffffff00; + } - 50% { - background: white; - } + 50% { + background: white; + } - 100% { - background: #ffffff00; - } + 100% { + background: #ffffff00; + } } @-webkit-keyframes blink { - 0% { - background: #ffffff00; - } + 0% { + background: #ffffff00; + } - 50% { - background: white; - } + 50% { + background: white; + } - 100% { - background: #ffffff00; - } + 100% { + background: #ffffff00; + } } - ol, ul { - padding-left: 20px; + padding-left: 20px; } - @keyframes spinner { - to { - transform: rotate(360deg); - } + to { + transform: rotate(360deg); + } } .spinner:before { - content: ''; - box-sizing: border-box; - position: absolute; - top: 50%; - left: 45%; - width: 20px; - height: 20px; + content: ""; + box-sizing: border-box; + position: absolute; + top: 50%; + left: 45%; + width: 20px; + height: 20px; - border-radius: 50%; - border: 1px solid var(--conversations); - border-top-color: white; - animation: spinner .6s linear infinite; + border-radius: 50%; + border: 1px solid var(--conversations); + border-top-color: white; + animation: spinner 0.6s linear infinite; } .grecaptcha-badge { - visibility: hidden; + visibility: hidden; } .mobile-sidebar { - display: none !important; - position: absolute; - z-index: 100000; - top: 0; - left: 0; - margin: 10px; - font-size: 20px; - cursor: pointer; - backdrop-filter: blur(20px); - -webkit-backdrop-filter: blur(20px); - background-color: var(--blur-bg); - border-radius: 10px; - border: 1px solid var(--blur-border); - width: 40px; - height: 40px; - justify-content: center; - align-items: center; - transition: 0.33s; + display: none !important; + position: absolute; + z-index: 100000; + top: 0; + left: 0; + margin: 10px; + font-size: 20px; + cursor: pointer; + backdrop-filter: blur(20px); + -webkit-backdrop-filter: blur(20px); + background-color: var(--blur-bg); + border-radius: 10px; + border: 1px solid var(--blur-border); + width: 40px; + height: 40px; + justify-content: center; + align-items: center; + transition: 0.33s; } .mobile-sidebar i { - transition: 0.33s; + transition: 0.33s; } .rotated { - transform: rotate(360deg); + transform: rotate(360deg); } @media screen and (max-width: 990px) { - .conversations { - display: none; - width: 100%; - max-width: none; - } + .conversations { + display: none; + width: 100%; + max-width: none; + } - .buttons { + .buttons { flex-wrap: wrap; gap: 5px; padding-bottom: 10vh; margin-bottom: 10vh; -} + } - .field { + .field { min-height: 5%; width: fit-content; -} + } - .mobile-sidebar { - display: flex !important; - } + .mobile-sidebar { + display: flex !important; + } } @media screen and (max-height: 640px) { - body { - height: 87vh - } + body { + height: 87vh; + } } - .shown { - display: flex; + display: flex; } - a:-webkit-any-link { - color: var(--accent); + color: var(--accent); } .conversation .user-input textarea { - font-size: 15px; - width: 100%; - height: 100%; - padding: 12px 15px; - background: none; - border: none; - outline: none; - color: var(--colour-3); + font-size: 15px; + width: 100%; + /* give a static-ish size so layout doesn't jump */ + height: 110px; + padding: 12px 15px; + background: none; + border: none; + outline: none; + color: var(--colour-3); - resize: vertical; - max-height: 150px; - min-height: 80px; + resize: vertical; + max-height: 180px; + min-height: 80px; } /* style for hljs copy */ .hljs-copy-wrapper { - position: relative; - overflow: hidden + position: relative; + overflow: hidden; } .hljs-copy-wrapper:hover .hljs-copy-button, .hljs-copy-button:focus { - transform: translateX(0) + transform: translateX(0); } .hljs-copy-button { - position: absolute; - transform: translateX(calc(100% + 1.125em)); - top: 1em; - right: 1em; - width: 2rem; - height: 2rem; - text-indent: -9999px; - color: #fff; - border-radius: .25rem; - border: 1px solid #ffffff22; - background-color: #2d2b57; - background-image: url('data:image/svg+xml;utf-8,'); - background-repeat: no-repeat; - background-position: center; - transition: background-color 200ms ease, transform 200ms ease-out + position: absolute; + transform: translateX(calc(100% + 1.125em)); + top: 1em; + right: 1em; + width: 2rem; + height: 2rem; + text-indent: -9999px; + color: #fff; + border-radius: 0.25rem; + border: 1px solid #ffffff22; + background-color: #2d2b57; + background-image: url('data:image/svg+xml;utf-8,'); + background-repeat: no-repeat; + background-position: center; + transition: background-color 200ms ease, transform 200ms ease-out; } .hljs-copy-button:hover { - border-color: #ffffff44 + border-color: #ffffff44; } .hljs-copy-button:active { - border-color: #ffffff66 + border-color: #ffffff66; } .hljs-copy-button[data-copied="true"] { - text-indent: 0; - width: auto; - background-image: none + text-indent: 0; + width: auto; + background-image: none; } -@media(prefers-reduced-motion) { - .hljs-copy-button { - transition: none - } +@media (prefers-reduced-motion) { + .hljs-copy-button { + transition: none; + } } .hljs-copy-alert { - clip: rect(0 0 0 0); - clip-path: inset(50%); - height: 1px; - overflow: hidden; - position: absolute; - white-space: nowrap; - width: 1px + clip: rect(0 0 0 0); + clip-path: inset(50%); + height: 1px; + overflow: hidden; + position: absolute; + white-space: nowrap; + width: 1px; } .visually-hidden { - clip: rect(0 0 0 0); - clip-path: inset(50%); - height: 1px; - overflow: hidden; - position: absolute; - white-space: nowrap; - width: 1px; -} - - -.color-picker>fieldset { - border: 0; - display: flex; - width: fit-content; - background: var(--colour-1); - margin-inline: auto; - border-radius: 8px; - -webkit-backdrop-filter: blur(20px); - backdrop-filter: blur(20px); - cursor: pointer; - background-color: var(--blur-bg); - border: 1px solid var(--blur-border); - color: var(--colour-3); - display: block; - position: relative; - overflow: hidden; - outline: none; - padding: 6px 16px; + clip: rect(0 0 0 0); + clip-path: inset(50%); + height: 1px; + overflow: hidden; + position: absolute; + white-space: nowrap; + width: 1px; +} + +.color-picker > fieldset { + border: 0; + display: flex; + width: fit-content; + background: var(--colour-1); + margin-inline: auto; + border-radius: 8px; + -webkit-backdrop-filter: blur(20px); + backdrop-filter: blur(20px); + cursor: pointer; + background-color: var(--blur-bg); + border: 1px solid var(--blur-border); + color: var(--colour-3); + display: block; + position: relative; + overflow: hidden; + outline: none; + padding: 6px 16px; } .color-picker input[type="radio"]:checked { - background-color: var(--radio-color); + background-color: var(--radio-color); } .color-picker input[type="radio"]#light { - --radio-color: gray; + --radio-color: gray; } .color-picker input[type="radio"]#pink { - --radio-color: pink; + --radio-color: pink; } .color-picker input[type="radio"]#blue { - --radio-color: blue; + --radio-color: blue; } .color-picker input[type="radio"]#green { - --radio-color: green; + --radio-color: green; } .color-picker input[type="radio"]#dark { - --radio-color: #232323; + --radio-color: #232323; } .pink { - --colour-1: hsl(310 50% 90%); - --clr-card-bg: hsl(310 50% 100%); - --colour-3: hsl(310 50% 15%); - --conversations: hsl(310 50% 25%); + --colour-1: hsl(310 50% 90%); + --clr-card-bg: hsl(310 50% 100%); + --colour-3: hsl(310 50% 15%); + --conversations: hsl(310 50% 25%); } .blue { - --colour-1: hsl(209 50% 90%); - --clr-card-bg: hsl(209 50% 100%); - --colour-3: hsl(209 50% 15%); - --conversations: hsl(209 50% 25%); + --colour-1: hsl(209 50% 90%); + --clr-card-bg: hsl(209 50% 100%); + --colour-3: hsl(209 50% 15%); + --conversations: hsl(209 50% 25%); } .green { - --colour-1: hsl(109 50% 90%); - --clr-card-bg: hsl(109 50% 100%); - --colour-3: hsl(109 50% 15%); - --conversations: hsl(109 50% 25%); + --colour-1: hsl(109 50% 90%); + --clr-card-bg: hsl(109 50% 100%); + --colour-3: hsl(109 50% 15%); + --conversations: hsl(109 50% 25%); } .dark { - --colour-1: hsl(209 50% 10%); - --clr-card-bg: hsl(209 50% 5%); - --colour-3: hsl(209 50% 90%); - --conversations: hsl(209 50% 80%); + --colour-1: hsl(209 50% 10%); + --clr-card-bg: hsl(209 50% 5%); + --colour-3: hsl(209 50% 90%); + --conversations: hsl(209 50% 80%); } :root:has(#pink:checked) { - --colour-1: hsl(310 50% 90%); - --clr-card-bg: hsl(310 50% 100%); - --colour-3: hsl(310 50% 15%); - --conversations: hsl(310 50% 25%); + --colour-1: hsl(310 50% 90%); + --clr-card-bg: hsl(310 50% 100%); + --colour-3: hsl(310 50% 15%); + --conversations: hsl(310 50% 25%); } :root:has(#blue:checked) { - --colour-1: hsl(209 50% 90%); - --clr-card-bg: hsl(209 50% 100%); - --colour-3: hsl(209 50% 15%); - --conversations: hsl(209 50% 25%); + --colour-1: hsl(209 50% 90%); + --clr-card-bg: hsl(209 50% 100%); + --colour-3: hsl(209 50% 15%); + --conversations: hsl(209 50% 25%); } :root:has(#green:checked) { - --colour-1: hsl(109 50% 90%); - --clr-card-bg: hsl(109 50% 100%); - --colour-3: hsl(109 50% 15%); - --conversations: hsl(109 50% 25%); + --colour-1: hsl(109 50% 90%); + --clr-card-bg: hsl(109 50% 100%); + --colour-3: hsl(109 50% 15%); + --conversations: hsl(109 50% 25%); } :root:has(#dark:checked) { - --colour-1: hsl(209 50% 10%); - --clr-card-bg: hsl(209 50% 5%); - --colour-3: hsl(209 50% 90%); - --conversations: hsl(209 50% 80%); -} \ No newline at end of file + --colour-1: hsl(209 50% 10%); + --clr-card-bg: hsl(209 50% 5%); + --colour-3: hsl(209 50% 90%); + --conversations: hsl(209 50% 80%); +} + +/* Small layout fixes for input and new-convo visibility */ +.conversations .top { + /* ensure the top area can always show the new conversation button */ + min-height: 84px; + padding-bottom: 8px; +} + +.new_convo { + align-items: center; + display: flex; + gap: 8px; +} + +.box.input-box { + display: flex; + align-items: center; + gap: 12px; + padding: 10px; +} + +.input-box textarea#message-input { + width: 100%; + min-height: 80px; + max-height: 180px; + resize: vertical; + padding: 12px; + box-sizing: border-box; + background: none; + border: none; + outline: none; + color: var(--colour-3); +} + +#send-button { + width: 52px; + height: 52px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; +} + +/* ensure the input box stays above decorative gradients */ +.box.input-box { + z-index: 2; +} diff --git a/client/html/index.html b/client/html/index.html index 201ac155..539f56bf 100644 --- a/client/html/index.html +++ b/client/html/index.html @@ -1,160 +1,203 @@ -
- - - - - - - - - - - - - - - - - - - - - - -