diff --git a/css/styles.css b/css/styles.css
new file mode 100644
index 0000000..c54a619
--- /dev/null
+++ b/css/styles.css
@@ -0,0 +1,140 @@
+@charset "UTF-8";
+
+:host {
+ display: block;
+}
+
+html {
+ min-height: 100vh;
+ min-width: 100vw;
+}
+
+body {
+ min-height: 100vh;
+ min-width: 100vw;
+ margin: 0px;
+ scrollbar-width: thin;
+}
+
+.text {
+ color: black;
+}
+
+homework-session {
+ display: block;
+ min-height: 100vh;
+ min-width: 100vw;
+ font-family: Georgia, Times, serif;
+ font-size: 18pt;
+ text-shadow: none;
+ user-select: none;
+ margin: 0px;
+ background-color: white;
+ overflow: hidden;
+ padding: 0 0 0 0;
+}
+
+homework-layout > #headings {
+ padding: .1em .5em 1em .4em;
+ margin: .1em;
+ border-radius: .3em;
+ background-color:white;
+ box-shadow: -4px 2px 5px 2px rgba(0,0,0,0.14), 0 3px 1px -2px rgba(0,0,0,0.12), 0 1px 5px 0 rgba(0,0,0,0.2);
+ z-index: 5000;
+}
+
+homework-layout > #headings > h1 {
+ margin-bottom: .1em;
+}
+
+homework-layout > #headings > h3 {
+ margin-top: .1em;
+ font-size: .8em;
+}
+
+homework-page {
+ margin: 0;
+ padding: 0;
+}
+
+homework-page > #sub-headers {
+ display: flex;
+ flex-flow: row nowrap;
+ justify-content: flex-start;
+ column-gap: .5em;
+ margin-left: .7em;
+}
+
+p.source-language, p.target-language {
+ width: 40%;
+ margin-bottom: 0;
+}
+
+p.target-language {
+ margin-left: .3em;
+}
+
+homework-page > #content {
+ margin-left: .7em;
+}
+
+homework-vocabulary-task {
+ display: flex;
+ flex-flow: row nowrap;
+ column-gap: .5em;
+ margin-top: .4em;
+}
+
+homework-vocabulary-task > input {
+ font-size: .8em;
+ width: 40%;
+}
+
+#page-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-left: .4em;
+}
+
+#page-header > #buttons {
+ display: flex;
+ flex-flow: row nowrap;
+ justify-content: flex-end;
+}
+
+.button {
+ display: flex;
+ flex-flow: column;
+ background: linear-gradient(#F2F2F2, #CFCFCF);
+ height: .7em;
+ min-width: 3em;
+ width: auto;
+ padding: .4em 1em .4em 1em;
+ border-style: solid;
+ border-color: #707070;
+ border-width: .1em;
+ border-radius: .3em;
+ vertical-align: middle;
+ text-align: center;
+ margin-right: .6em;
+ align-items: center;
+ cursor: pointer;
+ user-select: none;
+}
+
+.button-text {
+ font-family: Georgia, Times, serif;
+ font-size: .6em;
+ margin: 0;
+ white-space: nowrap;
+ overflow: hidden;
+}
+
+.button:hover {
+ box-shadow: 0 0 2px 1px #707070;
+}
+
+.button:active {
+ box-shadow: 0 0 3px 2px #707070;
+}
\ No newline at end of file
diff --git a/images/de_DE.svg b/images/de_DE.svg
new file mode 100644
index 0000000..b08334b
--- /dev/null
+++ b/images/de_DE.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/en_GB.svg b/images/en_GB.svg
new file mode 100644
index 0000000..dbac25e
--- /dev/null
+++ b/images/en_GB.svg
@@ -0,0 +1,7 @@
+
diff --git a/images/es_ES.svg b/images/es_ES.svg
new file mode 100644
index 0000000..815e0f8
--- /dev/null
+++ b/images/es_ES.svg
@@ -0,0 +1,544 @@
+
diff --git a/images/favicon.png b/images/favicon.png
new file mode 100644
index 0000000..e3a31db
Binary files /dev/null and b/images/favicon.png differ
diff --git a/images/fr_FR.svg b/images/fr_FR.svg
new file mode 100644
index 0000000..1be6191
--- /dev/null
+++ b/images/fr_FR.svg
@@ -0,0 +1,7 @@
+
diff --git a/images/sv_SE.svg b/images/sv_SE.svg
new file mode 100644
index 0000000..0e41780
--- /dev/null
+++ b/images/sv_SE.svg
@@ -0,0 +1,4 @@
+
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..5bc2d69
--- /dev/null
+++ b/index.html
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+ Homework vocabulary
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/javascript/homeworkElement.js b/javascript/homeworkElement.js
new file mode 100644
index 0000000..148bbc9
--- /dev/null
+++ b/javascript/homeworkElement.js
@@ -0,0 +1,31 @@
+class HomeworkElement extends HTMLElement {
+
+ static updateTexts(container) {
+ let textElements = container.querySelectorAll(".text")
+ console.log(textElements)
+ textElements.forEach((item, index) => {
+ let itemId = item.getAttribute("id")
+ let itemText = HomeworkSession.texts[itemId]
+ HomeworkElement.applyText(itemText, item, null)
+ })
+ }
+
+ static applyText(sourceText, targetElement, fallback = '') {
+ if(sourceText.length > 0) {
+ targetElement.innerHTML = sourceText
+ targetElement.innerHTML = targetElement.textContent.trim()
+ } else if(fallback == '') {
+ console.warn('Missing text in: ', sourceText)
+ } else {
+ targetElement.innerHTML = fallback
+ }
+ }
+}
+
+const HomeworkTypes = Object.freeze({
+ VOCABULARY_ENGLISH: "'English vocabulary'",
+ VOCABULARY_FRENCH: "'French vocabulary'",
+ VOCABULARY_GERMAN: "'German vocabulary'",
+ VOCABULARY_SPANISH: "'Spanish vocabulary'",
+ MATH: "'Math'"
+})
diff --git a/javascript/homeworkLayout.js b/javascript/homeworkLayout.js
new file mode 100644
index 0000000..61700f7
--- /dev/null
+++ b/javascript/homeworkLayout.js
@@ -0,0 +1,22 @@
+class HomeworkLayout extends HomeworkElement {
+ constructor () {
+ super()
+ this.innerHTML =
+ `
+
+
+
+
+
+
+ `
+ this.pages = this.querySelector('#pages')
+ }
+
+ connectedCallback() {
+ console.log("Layout added to session")
+ let page = new HomeworkPage(HomeworkTypes.VOCABULARY_ENGLISH)
+ this.pages.append(page)
+ }
+}
+customElements.define('homework-layout', HomeworkLayout)
\ No newline at end of file
diff --git a/javascript/homeworkPage.js b/javascript/homeworkPage.js
new file mode 100644
index 0000000..ce73523
--- /dev/null
+++ b/javascript/homeworkPage.js
@@ -0,0 +1,96 @@
+class HomeworkPage extends HomeworkElement {
+ constructor (type) {
+ super()
+ this.innerHTML =
+ `
+
+
+
+
+ `
+ let languageTextId = ""
+ let sourceLanguageTextId = "text030"
+ let targetLanguageTextId = ""
+ switch(type) {
+ case HomeworkTypes.VOCABULARY_ENGLISH:
+ console.log("English vocabulary")
+ languageTextId = "text005"
+ targetLanguageTextId = "text031"
+ break
+ case HomeworkTypes.VOCABULARY_FRENCH:
+ console.log("French vocabulary")
+ languageTextId = "text025"
+ targetLanguageTextId = "text032"
+ break
+ case HomeworkTypes.VOCABULARY_GERMAN:
+ console.log("German vocabulary")
+ languageTextId = "text024"
+ targetLanguageTextId = "text034"
+ break
+ case HomeworkTypes.VOCABULARY_SPANISH:
+ console.log("Spanish vocabulary")
+ languageTextId = "text026"
+ targetLanguageTextId = "text033"
+ break
+ default:
+ console.log("Math")
+ languageTextId = "text004"
+ }
+ this.type = type
+ this.headingText = this.querySelector('h2')
+ this.headingText.setAttribute("id", languageTextId)
+ this.languageHeaders = this.querySelectorAll('#sub-headers > p')
+ this.sourceLanguage = this.languageHeaders[0]
+ this.targetLanguage = this.languageHeaders[1]
+ this.sourceLanguage.setAttribute("id", sourceLanguageTextId)
+ this.targetLanguage.setAttribute("id", targetLanguageTextId)
+ this.content = this.querySelector('#content')
+ this.newButton = this.querySelector('#new')
+ this.newButton.addEventListener("click", this.newVocabulary.bind(this))
+ this.saveButton = this.querySelector('#save')
+ this.saveButton.addEventListener("click", this.saveVocabularies.bind(this))
+ this.trainButton = this.querySelector('#train')
+ this.trainButton.addEventListener("click", this.trainVocabulary.bind(this))
+ }
+
+ connectedCallback() {
+ console.log("Page of type " + this.type + " added to session")
+ if(this.type == HomeworkTypes.VOCABULARY_ENGLISH) {
+ const row = new HomeworkVocabularyTask()
+ this.content.append(row)
+ }
+ }
+
+ newVocabulary() {
+ if(this.type == HomeworkTypes.VOCABULARY_ENGLISH) {
+ const row = new HomeworkVocabularyTask()
+ this.content.append(row)
+ console.log("New row in page")
+ }
+ }
+
+ saveVocabularies() {
+ console.log("Saving page content")
+ }
+
+ trainVocabulary() {
+ console.log("Train!!")
+ }
+}
+customElements.define('homework-page', HomeworkPage)
\ No newline at end of file
diff --git a/javascript/homeworkSession.js b/javascript/homeworkSession.js
new file mode 100644
index 0000000..13a9b58
--- /dev/null
+++ b/javascript/homeworkSession.js
@@ -0,0 +1,78 @@
+class HomeworkSession extends HomeworkElement {
+
+ constructor() {
+ super()
+ this.addEventListener('texts-loaded', this.updateTexts.bind(this))
+ }
+
+ connectedCallback() {
+ let top = new HomeworkLayout()
+ this.append(top)
+ console.log("Session added to DOM")
+ }
+
+ static get observedAttributes () {
+ return [ 'language' ]
+ }
+
+ attributeChangedCallback(name, oldValue, newValue) {
+ if(name == 'language') {
+ if(oldValue === null) {
+ console.log("Language initiated to " + newValue)
+ } else {
+ console.log("Language changed to " + newValue + " from " + oldValue)
+ }
+ this.changeLanguage(newValue)
+ } else {
+ console.log("Unknown property", name)
+ }
+ }
+
+ get language() {
+ let languageCode = this.getAttribute("language")
+ return languageCode
+ }
+
+ set language(languageCode) {
+ this.setAttribute("language", languageCode)
+ }
+
+ async changeLanguage(languageCode) {
+ let languageFile = "/resources/" + languageCode + ".json"
+ let response = await fetch(languageFile)
+ HomeworkSession.texts = await response.json()
+ this.dispatchEvent(new CustomEvent('texts-loaded', { bubbles: true }))
+ }
+
+ updateTexts() {
+ HomeworkElement.updateTexts(this)
+ }
+
+/*
+
+ homeworkTypeChanged(event) {
+ let homeworkType = event.target.value
+ console.log("Changed homework type to " + homeworkType )
+ let pages = this.querySelectorAll('.page')
+ pages.forEach((page) => {
+ page.classList.remove('active')
+ })
+ let page = null
+ switch(homeworkType) {
+ case 'math':
+ page = this.querySelector('homework-page-math')
+ page.classList.add('active')
+ break
+ case 'englishVocabulary':
+ page = this.querySelector('homework-page-english-vocabulary')
+ page.classList.add('active')
+ break
+ default:
+ console.warn("Unknown type " + homeworkType)
+ break
+ }
+ }
+ */
+}
+HomeworkSession.texts = { }
+customElements.define('homework-session', HomeworkSession)
diff --git a/javascript/homeworkVocabularyTask.js b/javascript/homeworkVocabularyTask.js
new file mode 100644
index 0000000..d7dd32c
--- /dev/null
+++ b/javascript/homeworkVocabularyTask.js
@@ -0,0 +1,16 @@
+class HomeworkVocabularyTask extends HomeworkElement {
+ constructor () {
+ super()
+ this.innerHTML =
+ `
+
+
+
+ `
+ }
+
+ connectedCallback() {
+ console.log("New task")
+ }
+}
+customElements.define('homework-vocabulary-task', HomeworkVocabularyTask)
\ No newline at end of file
diff --git a/resources/en_GB.json b/resources/en_GB.json
new file mode 100644
index 0000000..b6767fa
--- /dev/null
+++ b/resources/en_GB.json
@@ -0,0 +1,4 @@
+{
+ "heading1": "Homework assistant",
+ "heading2": "Your digital assistant that makes the homework more fun"
+}
\ No newline at end of file
diff --git a/resources/sv_SE.json b/resources/sv_SE.json
new file mode 100644
index 0000000..94ec085
--- /dev/null
+++ b/resources/sv_SE.json
@@ -0,0 +1,39 @@
+{
+ "text001": "Läxassistent",
+ "text002": "Din digitala läxassistent i skoldjungeln",
+ "text003": "Välj typ av läxa",
+ "text004": "Matematik",
+ "text005": "Engelska glosor",
+ "text006": "Välj räknesätt...",
+ "text007": "Addition",
+ "text008": "Subtraktion",
+ "text009": "Multiplikation",
+ "text010": "Division",
+ "text011": "Svårighetsgrad",
+ "text012": "Tiotalsövergång",
+ "text013": "Negativa tal",
+ "text014": "Lätt",
+ "text015": "Medel",
+ "text016": "Medelsvår",
+ "text017": "Svår",
+ "text018": "Omöjlig",
+ "text019": "Användarnamn",
+ "text020": "Lösenord",
+ "text021": "Logga in till läxhjälp",
+ "text022": "Logga in",
+ "text023": "Felaktigt användarnamn eller lösenord",
+ "text024": "Tyska glosor",
+ "text025": "Franska glosor",
+ "text026": "Spanska glosor",
+ "text027": "Användare",
+ "text028": "Språk",
+ "text029": "Välj...",
+ "text030": "Svenska",
+ "text031": "Engelska",
+ "text032": "Franska",
+ "text033": "Spanska",
+ "text034": "Tyska",
+ "text035": "Ny...",
+ "text036": "Träna",
+ "text037": "Spara"
+}
\ No newline at end of file