Merge branch 'main' of interstellardevelopment.org:YasinOnm08/interstellar_ai
This commit is contained in:
commit
939cdd4497
13 changed files with 984 additions and 206 deletions
|
@ -5,6 +5,8 @@ import InputFrontend from "../components/InputFrontend";
|
|||
import { sendToVoiceRecognition } from "./voice_backend"
|
||||
import axios from "axios";
|
||||
import { useChatHistory } from '../hooks/useChatHistory';
|
||||
import { getWeather } from "./weather";
|
||||
import { changeHistory, getHistory } from "./database";
|
||||
|
||||
const InputOutputBackend: React.FC = () => {
|
||||
// # variables
|
||||
|
@ -24,6 +26,9 @@ const InputOutputBackend: React.FC = () => {
|
|||
const [messages, setMessages] = useState<Message[]>(chatHistory.chats[chatHistory.selectedIndex].messages || []);
|
||||
const [myBoolean, setMyBoolean] = useState<boolean>(false);
|
||||
const [systemMessage, setSystemMessage] = useState<string>("You are a helpful assistant")
|
||||
const [weatherData, setWeatherData] = useState<string>("")
|
||||
const [weatherTriggered, setWeatherTriggered] = useState<boolean>(false)
|
||||
const [chatHistoryTriggered, setChatHistoryTriggered] = useState<boolean>(false)
|
||||
const apiURL = new URL("http://localhost:5000/interstellar_ai/api/ai_create")
|
||||
if (typeof window !== 'undefined') {
|
||||
apiURL.hostname = window.location.hostname;
|
||||
|
@ -34,7 +39,7 @@ const InputOutputBackend: React.FC = () => {
|
|||
console.log(setSelectedIndex)
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
useEffect(() => {
|
||||
console.log("History", chatHistory);
|
||||
console.log("Messages", messages);
|
||||
|
||||
|
@ -43,14 +48,14 @@ useEffect(() => {
|
|||
|
||||
// If the selected chat has messages, set them
|
||||
if (currentMessages.length > 0) {
|
||||
setMessages(currentMessages);
|
||||
setMessages(currentMessages);
|
||||
} else if (currentMessages.length === 0) {
|
||||
// When creating a new chat and no messages exist yet, set default messages
|
||||
addMessage("system", systemMessage)
|
||||
addMessage("assistant", "Hello! How can I help you?")
|
||||
console.log(systemMessage)
|
||||
}
|
||||
}, [chatHistory, chatHistory.selectedIndex, systemMessage]);
|
||||
}, [chatHistory, chatHistory.selectedIndex, systemMessage]);
|
||||
|
||||
// Update messages when any of the settings change
|
||||
useEffect(() => {
|
||||
|
@ -62,10 +67,43 @@ useEffect(() => {
|
|||
setTimeZone(localStorage.getItem("timeZone") || "GMT");
|
||||
setDateFormat(localStorage.getItem("dateFormat") || "DD-MM-YYYY");
|
||||
setMyBoolean(localStorage.getItem('myBoolean') === 'true');
|
||||
getWeatherHere()
|
||||
getChatHistory()
|
||||
}
|
||||
},[])
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
const username = localStorage.getItem("accountName")
|
||||
const password = localStorage.getItem("accountPassword")
|
||||
if (username && password && chatHistoryTriggered) {
|
||||
changeHistory(username, password, chatHistory)
|
||||
console.log("changed history in backend")
|
||||
}
|
||||
}, [chatHistory])
|
||||
|
||||
const getWeatherHere = async () => {
|
||||
setWeatherData(await getWeather({ "unit_type": preferredMeasurement, "city": localStorage.getItem("weatherInfo") || "New York" }))
|
||||
console.log("Got the Data!")
|
||||
setWeatherTriggered(true)
|
||||
}
|
||||
|
||||
const getChatHistory = async () => {
|
||||
const username = localStorage.getItem("accountName")
|
||||
const password = localStorage.getItem("accountPassword")
|
||||
if (username && password) {
|
||||
const tempChatHistory = await getHistory(username, password)
|
||||
if (tempChatHistory && typeof tempChatHistory == "object") {
|
||||
setChatHistory(tempChatHistory)
|
||||
console.log("got history from backend")
|
||||
}
|
||||
}
|
||||
setChatHistoryTriggered(true)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
console.log("creating system prompt")
|
||||
console.log(weatherData)
|
||||
|
||||
const measurementString = (preferredMeasurement == "Metric")
|
||||
? "All measurements follow the metric system. Refuse to use any other measurement system."
|
||||
: "All measurements follow the imperial system. Refuse to use any other measurement system.";
|
||||
|
@ -76,17 +114,18 @@ useEffect(() => {
|
|||
The currency is ${preferredCurrency}.
|
||||
Communicate in the language specified by the user (country code: ${preferredLanguage}), and only in this language.
|
||||
You are only able to change language if the user specifically states you must.
|
||||
Do not answer in multiple languages or multiple measurement systems under any circumstances other than the user requesting it.`
|
||||
: `You are a helpful assistant`;
|
||||
|
||||
Do not answer in multiple languages or multiple measurement systems under any circumstances other than the user requesting it.
|
||||
These are the currently newest Weather infos for the region. In case the user asks about anything weather related, you can use the following data to help the user: ${weatherData}. If there is nothing there say there is no data`
|
||||
: `You are a helpful assistant.`;
|
||||
console.log(newSystemMessage)
|
||||
setSystemMessage(newSystemMessage)
|
||||
}, [preferredCurrency, preferredLanguage, timeFormat, preferredMeasurement, timeZone, dateFormat, myBoolean]);
|
||||
}, [preferredCurrency, preferredLanguage, timeFormat, preferredMeasurement, timeZone, dateFormat, myBoolean, weatherTriggered]);
|
||||
|
||||
useEffect(() => {
|
||||
const messageIndex = 0 // system prompt is the first so index 0
|
||||
updateMessage(messageIndex, systemMessage)
|
||||
console.log(messages)
|
||||
},[systemMessage])
|
||||
}, [systemMessage])
|
||||
|
||||
|
||||
const conversationRef = useRef<HTMLDivElement>(null)
|
||||
|
@ -185,8 +224,8 @@ useEffect(() => {
|
|||
if (newContent == "") {
|
||||
newContent = "Generating answer..."
|
||||
}
|
||||
const messageIndex = chatHistory.chats[chatHistory.selectedIndex].messages.length-1
|
||||
updateMessage(messageIndex,newContent)
|
||||
const messageIndex = chatHistory.chats[chatHistory.selectedIndex].messages.length - 1
|
||||
updateMessage(messageIndex, newContent)
|
||||
};
|
||||
|
||||
const addMessage = (role: string, content: string) => {
|
||||
|
@ -194,7 +233,7 @@ useEffect(() => {
|
|||
setMessages((prevMessages) => [...prevMessages, newMessage])
|
||||
const updatedChats = [...chatHistory.chats]
|
||||
updatedChats[chatHistory.selectedIndex].messages.push(newMessage)
|
||||
setChatHistory({...chatHistory, chats:updatedChats})
|
||||
setChatHistory({ ...chatHistory, chats: updatedChats })
|
||||
}
|
||||
const handleSendClick = (inputValue: string, override: boolean) => {
|
||||
if (inputValue != "") {
|
||||
|
@ -202,7 +241,7 @@ useEffect(() => {
|
|||
setInputDisabled(true)
|
||||
if (postWorkerRef.current) {
|
||||
addMessage("user", inputValue)
|
||||
let type:string = "local"
|
||||
let type: string = "local"
|
||||
let api_key: string = ""
|
||||
if (typeof localStorage !== 'undefined') {
|
||||
type = localStorage.getItem('type') || "local"
|
||||
|
@ -215,7 +254,7 @@ useEffect(() => {
|
|||
}
|
||||
setInputMessage("")
|
||||
const windowname = window.location.hostname
|
||||
postWorkerRef.current.postMessage({ messages: [...messages, { role: "user", content: inputValue }], ai_model: "llama3.2", model_type: type, access_token: accessToken, api_key: api_key, windowname })
|
||||
postWorkerRef.current.postMessage({ messages: [...messages, { role: "user", content: inputValue }], ai_model: localStorage.getItem("model") || "llama3.2", model_type: type, access_token: accessToken, api_key: api_key, windowname })
|
||||
startGetWorker()
|
||||
}
|
||||
}
|
||||
|
|
23
app/backend/weather.ts
Normal file
23
app/backend/weather.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
import axios from "axios";
|
||||
|
||||
const apiURL = new URL("http://localhost:5000/interstellar_ai/api/weather")
|
||||
if (typeof window !== 'undefined') {
|
||||
apiURL.hostname = window.location.hostname;
|
||||
} else {
|
||||
apiURL.hostname = "localhost"
|
||||
}
|
||||
|
||||
export const getWeather = async (data: object): Promise<string> => {
|
||||
try {
|
||||
const response = await axios.post(apiURL.href, data);
|
||||
const status = response.data.status;
|
||||
const success = response.data.response;
|
||||
postMessage({ status, success });
|
||||
console.log(JSON.stringify(success))
|
||||
return JSON.stringify(success);
|
||||
} catch (error) {
|
||||
postMessage({ status: 500, success: false });
|
||||
console.log(error)
|
||||
return "";
|
||||
}
|
||||
};
|
|
@ -2,122 +2,75 @@ import React from 'react';
|
|||
|
||||
const Documentation = () => {
|
||||
return (
|
||||
<div className="documentation-container">
|
||||
<section id="documentation" className="documentation-section">
|
||||
<h1 className="title">AI Virtual Assistant - Internship Students 2024</h1>
|
||||
<h2 className="subtitle">General planning:</h2>
|
||||
<p className="paragraph">
|
||||
We are currently in the process of developing a Python application that leverages HTML and CSS to create an intuitive graphical user interface (GUI). This application will integrate multiple AI models through API calls, enabling users to effortlessly switch between different models tailored for specific tasks, such as coding, mathematics, and language processing. A key feature of our design is that the application will be capable of running locally, ensuring that users can access its functionality without the need for an internet connection.
|
||||
</p>
|
||||
<p className="paragraph">
|
||||
Upon receiving our assignment, we initiated the project by outlining a detailed timeline for each task to ensure a structured approach to development. This timeline serves as a roadmap, helping us allocate resources effectively and track our progress. Following this planning phase, Patrick_Pluto took the lead in creating the repository, establishing a centralized location for our codebase. Meanwhile, Yasin and sageTheDM forked the repository to begin their contributions, allowing them to work on specific features and enhancements independently.
|
||||
</p>
|
||||
<p className="paragraph">
|
||||
As we move forward, our focus will be on refining the user experience, optimizing the integration of AI models, and ensuring that the application is robust and user-friendly. We are excited about the potential of this project and are committed to delivering a high-quality application that meets the needs of our users.
|
||||
</p>
|
||||
<section id="documentation" className="documentation-section">
|
||||
<div className='docDiv'>
|
||||
<h1 className="title">Our Documentation</h1>
|
||||
|
||||
<h2 className="subtitle">Frontend planning:</h2>
|
||||
<p className="paragraph">
|
||||
We are committed to designing a visually appealing graphical user interface (GUI) that significantly enhances user experience and engagement. The GUI will prominently feature a chat function, allowing users to interact seamlessly with the AI Assistant. This conversational interface will facilitate easy communication, making it intuitive for users to ask questions and receive responses.
|
||||
</p>
|
||||
<p className="paragraph">
|
||||
To further improve usability, we will incorporate distinct buttons that enable users to switch effortlessly between online and offline modes. This functionality ensures that users can access the AI's capabilities regardless of their internet connectivity, making the application versatile and accommodating to various user environments.
|
||||
</p>
|
||||
<p className="paragraph">
|
||||
Additionally, the interface will provide options for users to select from a range of AI models, each tailored for specific use cases such as coding assistance, mathematical problem-solving, and language translation. This feature empowers users to choose the most suitable AI for their needs, thereby enhancing the overall effectiveness and relevance of the application.
|
||||
</p>
|
||||
<p className="paragraph">
|
||||
We will also prioritize creating an intuitive layout, ensuring that all elements are easily accessible and visually coherent. By focusing on user experience in our design, we aim to make the application not only functional but also enjoyable to use. Our goal is to create a user-friendly environment that encourages exploration and interaction, ultimately leading to a more satisfying and productive experience for all users.
|
||||
Here you will find our documentation file that was made using Google Docs.
|
||||
</p>
|
||||
<a
|
||||
href="/pdf/documentation.pdf"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="link"
|
||||
aria-label="Open Documentation PDF"
|
||||
>
|
||||
Documentation
|
||||
</a>
|
||||
|
||||
<h2 className="subtitle">Draw.io:</h2>
|
||||
<img src="/img/Live-Message-Idee.jpg" alt='Live Message Skizze' />
|
||||
<h2 className="subtitle">Our Task</h2>
|
||||
<p className="paragraph">
|
||||
If you want to see what our task for that 4-week long project was, click on the link below.
|
||||
</p>
|
||||
<a
|
||||
href="/pdf/AI Virtual Assistant - Internship Students 2024.pdf"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="link"
|
||||
aria-label="View Task Document"
|
||||
>
|
||||
Task
|
||||
</a>
|
||||
|
||||
<h2 className="subtitle">Inspiration:</h2>
|
||||
<p className="paragraph">We got our inspiration from Huggingchat.</p>
|
||||
<h2 className="subtitle">Our Code</h2>
|
||||
<p className="paragraph">
|
||||
If you are interested in our source code, you can click on the links below to either download the source code directly or view it online on our Forgejo.
|
||||
</p>
|
||||
<a
|
||||
href="https://interstellardevelopment.org/code/React-Group/interstellar_ai"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="link"
|
||||
aria-label="View Source Code Repository"
|
||||
>
|
||||
View Repository
|
||||
</a>
|
||||
<a
|
||||
href="https://interstellardevelopment.org/code/React-Group/interstellar_ai/archive/main.tar.gz"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="link"
|
||||
aria-label="Download Source Code"
|
||||
>
|
||||
Download Source Code
|
||||
</a>
|
||||
|
||||
<h2 className="subtitle">First prototype:</h2>
|
||||
<h2 className="subtitle">Our License</h2>
|
||||
<p className="paragraph">
|
||||
After prototyping the Website we started working on optimizing the css and html structure, and combining the front and the backend together with each other using Flask. Since we have never once done that once it was more learning by doing than planning that is why we have not planned this step but documented it.
|
||||
Our project is under the AGPL-3.0 or later. To find the currently used version of the license, click on the link below.
|
||||
</p>
|
||||
|
||||
<h2 className="subtitle">Web APP</h2>
|
||||
<h3 className="subsection-title">QtWebEngine 5</h3>
|
||||
<p className="paragraph">
|
||||
We decided on going with QtWebEngine, because Qt is cross platform, and easy to use. QtWebEngine is basically a slimmed down version of Chromium that runs on the Qt Widget Framework. It looked pretty good, but the browser part is very barebones, so it broke a lot of styling.
|
||||
</p>
|
||||
|
||||
<h3 className="subsection-title">Styling</h3>
|
||||
<p className="paragraph">
|
||||
After conducting thorough testing, we discovered that even after performing a browser reset, the web application exhibited a distinct styling compared to the web version. This inconsistency prompted us to undertake a comprehensive overhaul of the entire CSS framework.
|
||||
</p>
|
||||
<p className="paragraph">
|
||||
In our redesign, we focused on enhancing the user experience by implementing custom scrollbars that align with our overall aesthetic. Additionally, we expanded upon our existing design foundation to ensure a more cohesive and visually appealing interface.
|
||||
</p>
|
||||
<p className="paragraph">
|
||||
Our efforts have resulted in a web application that is not only visually consistent across different platforms but also optimized for performance. The revamped web app is designed to be responsive, making it accessible and functional on a wide range of devices, from desktops to tablets and smartphones. This adaptability ensures that users can enjoy a seamless experience, regardless of the device they choose to use.
|
||||
</p>
|
||||
<p className="paragraph">
|
||||
Overall, these improvements reflect our commitment to delivering a high-quality product that meets the diverse needs of our users while maintaining a polished and professional appearance.
|
||||
</p>
|
||||
|
||||
<h2 className="subtitle">Prototype: 17.09.2024</h2>
|
||||
<p className="paragraph">
|
||||
Our current prototype operates on a straightforward Python backend, which, while functional, relies heavily on our optimism that it will remain stable and not encounter any critical failures or data loss.
|
||||
</p>
|
||||
<p className="paragraph">
|
||||
The existing chat system is equipped with several key features designed to enhance user interaction. Users can easily resend the AI's response, allowing for quick follow-up questions or clarifications. Additionally, the system provides the ability to edit user messages, ensuring that any mistakes can be corrected without starting the conversation anew.
|
||||
</p>
|
||||
<p className="paragraph">
|
||||
Furthermore, users have the option to copy the AI's responses, facilitating easy sharing or saving of information for future reference. These features aim to create a more flexible and user-friendly experience, allowing for seamless communication and interaction with the AI.
|
||||
</p>
|
||||
<p className="paragraph">
|
||||
While the current setup serves as a solid foundation, we recognize the need for further improvements and enhancements to ensure reliability and robustness as we move forward in the development process.
|
||||
</p>
|
||||
<p className="paragraph">
|
||||
Theoretically there is also voice recognition but let us ignore that for now.
|
||||
</p>
|
||||
|
||||
<h2 className="subtitle">17.09.2024</h2>
|
||||
<p className="paragraph">
|
||||
After transitioning to React, we made several significant changes. We renamed our History and Models components to .left-panel, which can now be hidden when not in use. Additionally, with various optimizations through React, we’ve successfully split the CSS and HTML components into more manageable parts.
|
||||
</p>
|
||||
<p className="paragraph">
|
||||
We also made our first strides towards achieving a fully responsive website. With these changes, we are well on our way to completing the responsive design in the near future.
|
||||
</p>
|
||||
|
||||
<h2 className="subtitle">Backend planning:</h2>
|
||||
<h3 className="subsection-title">Task:</h3>
|
||||
<p className="paragraph">
|
||||
We will develop an extensible backend that enables us to easily swap out different AI models, facilitating the creation of a versatile AI Virtual Assistant. This architecture will allow for seamless integration of new AI technologies as they become available, ensuring that our application remains up-to-date and capable of meeting diverse user needs.
|
||||
</p>
|
||||
<p className="paragraph">
|
||||
The backend will also incorporate advanced features such as speech recognition, allowing users to interact with the AI Assistant through voice commands for a more natural and intuitive experience. Additionally, we will implement functionality to save chat histories, enabling users to revisit previous conversations and maintain continuity in their interactions with the AI.
|
||||
</p>
|
||||
<p className="paragraph">
|
||||
For the AI model, we will utilize Microsoft Phi 3.5, which offers robust capabilities for understanding and generating human-like responses. This choice will enhance the overall performance of the Virtual Assistant, making it a valuable tool for users seeking assistance across various tasks and topics. By combining an extensible backend with powerful AI capabilities, we aim to deliver a comprehensive and user-friendly virtual assistant experience.
|
||||
</p>
|
||||
|
||||
<h2 className="subtitle">Design Philosophy:</h2>
|
||||
<p className="paragraph">
|
||||
Our design philosophy is to create one script file per feature. This allows us to possibly reuse certain features in other projects very easily, as we can copy the individual .py files, which all work on their own, except the specific .py file for this project, which is specially tailored towards this AI chatbot.
|
||||
</p>
|
||||
|
||||
<h2 className="subtitle">UML diagrams:</h2>
|
||||
<p className="paragraph">Insert your UML diagrams here, one picture per diagram.</p>
|
||||
|
||||
<h2 className="subtitle">First Prototype:</h2>
|
||||
<p className="paragraph">
|
||||
You are able to simply select an AI Model, then type out what you want to ask. This Prototype is already ready to answer questions and detect what language you write in and give the answer in the corresponding language.
|
||||
</p>
|
||||
|
||||
<h2 className="subtitle">Combining back and frontend</h2>
|
||||
<h3 className="subsection-title">Flask setup</h3>
|
||||
<p className="paragraph">
|
||||
The flask setup was relatively quick. We had to adjust all of the file references, and add /static
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
<a
|
||||
href="/license.html"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="link"
|
||||
aria-label="View License"
|
||||
>
|
||||
License
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -111,6 +111,9 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
|
|||
// Theme selection
|
||||
const [selectedTheme, setSelectedTheme] = useState<string>('');
|
||||
|
||||
// Weather selection
|
||||
const [weatherInfo, setWeatherInfo] = useState(localStorage.getItem('weatherInfo') || "");
|
||||
|
||||
// API Keys
|
||||
|
||||
const [mistral, setMistral] = useState(localStorage.getItem('mistral') || "");
|
||||
|
@ -132,6 +135,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
|
|||
disableChatHistory,
|
||||
disableAIMemory,
|
||||
openSourceMode,
|
||||
weatherInfo,
|
||||
myBoolean
|
||||
},
|
||||
theme: {
|
||||
|
@ -405,7 +409,13 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
|
|||
checked={myBoolean}
|
||||
setChecked={setMyBoolean}
|
||||
/>
|
||||
|
||||
<TextSettings
|
||||
label="Nearest City"
|
||||
value={weatherInfo}
|
||||
type='text'
|
||||
setValue={setWeatherInfo}
|
||||
placeholder={localStorage.getItem("weatherInfo") || "Enter nearest city"} // Show current name or a default
|
||||
/>
|
||||
<DropdownSetting
|
||||
label="Preferred Language"
|
||||
value={preferredLanguage}
|
||||
|
|
|
@ -1,38 +1,73 @@
|
|||
/* styles.css */
|
||||
/* Styling for the documentation container */
|
||||
.documentation-container{
|
||||
padding: 2rem;
|
||||
.documentation-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start; /* Change to flex-start to align content at the top */
|
||||
align-items: center;
|
||||
padding: 2rem; /* Ensure sufficient padding */
|
||||
margin: 2rem;
|
||||
background-color: var(--doc-background-color);
|
||||
}
|
||||
.documentation-section{
|
||||
max-width: 900px;
|
||||
height: 80dvh;
|
||||
margin: auto;
|
||||
background: var(--doc-background-color); /* Use variable for background */
|
||||
padding: 2rem;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 0 20px rgba(0, 0, 0, 0.3);
|
||||
overflow-y: scroll;
|
||||
|
||||
.docDiv {
|
||||
margin: 1em auto;
|
||||
padding: 2em 1.5em; /* Adjusted padding for a modern look */
|
||||
}
|
||||
.title{
|
||||
font-size: calc(var(--font-size)*2);
|
||||
color: var(--doc-title-color); /* Use variable for title color */
|
||||
margin-bottom: 1.5rem;
|
||||
|
||||
#documentation {
|
||||
max-width: 800px;
|
||||
height: 70vh;
|
||||
overflow: auto;
|
||||
width: 90%;
|
||||
background-color: var(--doc-background-color);
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); /* Softer shadow for depth */
|
||||
margin: 4rem auto;
|
||||
border: 1px solid var(--faq-item-border-color);
|
||||
padding: 2rem; /* Added padding to give space around the content */
|
||||
}
|
||||
.subtitle{
|
||||
font-size: calc(var(--font-size)*1.5);
|
||||
color: var(--doc-subtitle-color); /* Use variable for subtitle color */
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 1rem;
|
||||
|
||||
.title,
|
||||
.subtitle,
|
||||
.paragraph,
|
||||
.link {
|
||||
color: var(--text-color);
|
||||
}
|
||||
.subsection-title{
|
||||
font-size: calc(var(--font-size)*1.25);
|
||||
color: var(--doc-subsection-title-color); /* Use variable for subsection title color */
|
||||
margin-top: 1.5rem;
|
||||
margin-bottom: 0.75rem;
|
||||
|
||||
.title {
|
||||
font-size: calc(var(--font-size) * 2);
|
||||
text-align: center;
|
||||
margin-bottom: 1.5rem; /* Space below title */
|
||||
}
|
||||
.paragraph{
|
||||
font-size: calc(var(--font-size));
|
||||
color: var(--doc-paragraph-color); /* Use variable for paragraph color */
|
||||
margin-bottom: 1.5rem;
|
||||
line-height: 1.6;
|
||||
|
||||
.subtitle {
|
||||
font-size: calc(var(--font-size) * 1.5);
|
||||
margin-top: 2rem; /* Increased space for clarity */
|
||||
}
|
||||
|
||||
.paragraph {
|
||||
font-size: 1.1em;
|
||||
line-height: 1.7; /* Increased line height for readability */
|
||||
margin-bottom: 1.5rem; /* Increased space for readability */
|
||||
}
|
||||
|
||||
.link {
|
||||
display: block;
|
||||
padding: 12px 18px; /* Slightly increased padding for buttons */
|
||||
margin-top: 12px; /* Increased space above links */
|
||||
background-color: var(--input-button-color);
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
border-radius: 5px;
|
||||
transition: background-color 0.3s, transform 0.2s;
|
||||
color: #fff; /* Ensure text color is readable */
|
||||
font-weight: bold; /* Make links more prominent */
|
||||
}
|
||||
|
||||
.link:hover {
|
||||
background-color: var(--input-button-hover-color);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.link:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
|
|
@ -129,7 +129,7 @@
|
|||
.header-login-button {
|
||||
right: 5vh; /* Keep login button visible */
|
||||
}
|
||||
.show-hide-btn{
|
||||
.show-hide-btn {
|
||||
width: fit-content;
|
||||
left: 20vw;
|
||||
}
|
||||
|
@ -137,7 +137,7 @@
|
|||
background-image: url(../../public/img/logo-small.png);
|
||||
width: 4em;
|
||||
}
|
||||
.sidebar{
|
||||
.sidebar {
|
||||
width: 0%;
|
||||
display: none;
|
||||
}
|
||||
|
@ -146,14 +146,13 @@
|
|||
margin: auto;
|
||||
padding: auto;
|
||||
}
|
||||
.dropdown{
|
||||
.dropdown {
|
||||
display: flex;
|
||||
position: relative;
|
||||
top: 10px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.slider-option{
|
||||
.slider-option {
|
||||
width: fit-content;
|
||||
margin: 10px 10px 0 0;
|
||||
}
|
||||
|
@ -165,3 +164,22 @@
|
|||
flex-direction: column; /* Stack sidebar and main content on smaller screens */
|
||||
}
|
||||
}
|
||||
|
||||
/* Optional: Add media query for responsive adjustments */
|
||||
@media (max-width: 600px) {
|
||||
.documentation-section {
|
||||
padding: 1.5rem; /* Decrease padding for smaller screens */
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2em; /* Adjust title size */
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 1.5em; /* Adjust subtitle size */
|
||||
}
|
||||
|
||||
.paragraph {
|
||||
font-size: 1em; /* Adjust paragraph size */
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue