Initial commit: SMF2290 studie-app for eksamen vår 2026

Komplett pensumstudie-app med:
- 120 flashcards, 49 quiz-spørsmål, 16 eksamenstrener-oppgaver
- Sammendrag av alle 12 forelesninger
- tl;dr-side for siste-minutts pugging
- Søk gjennom hele pensumet
- Dark/light mode, mobile-vennlig

Cross-platform launchere (Start.sh + Start.bat) med auto-detect
og auto-install av HTTP-server. PowerShell-fallback for Windows.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-29 18:44:00 +02:00
commit 8933e9501d
52 changed files with 8796 additions and 0 deletions

1830
app/css/style.css Normal file

File diff suppressed because it is too large Load Diff

262
app/data/exam.json Normal file

File diff suppressed because one or more lines are too long

962
app/data/flashcards.json Normal file
View File

@@ -0,0 +1,962 @@
[
{
"id": "fc-001",
"category": "etikk",
"subcategory": "Grunnbegreper",
"week": 2,
"front": "Hva er forskjellen mellom etikk og moral?",
"back": "Moral = personlige/felles oppfatninger av rett og galt, læres i praksis. Etikk = systematisk fagdisiplin/refleksjon over rett og galt, læres gjennom studier. Etikk er teori; moral er normer."
},
{
"id": "fc-002",
"category": "etikk",
"subcategory": "Grunnbegreper",
"week": 3,
"front": "Definer jus og forklar forskjellen fra etikk og moral.",
"back": "Jus = det formelle systemet av regler og forskrifter som styrer samfunnets atferd, håndhevet av myndighetene. Etikk er filosofisk fagdisiplin, moral er praktiserte normer, mens jus er kodifisert og håndhevet gjennom rettssystemet."
},
{
"id": "fc-003",
"category": "etikk",
"subcategory": "Grunnbegreper",
"week": 3,
"front": "Hva er forskjellen mellom normativ og deskriptiv etikk?",
"back": "Normativ etikk gir veiledning om hva man bør gjøre. Deskriptiv etikk beskriver hva folk faktisk tror om moral og hvordan de handler, uten å bedømme eller anbefale."
},
{
"id": "fc-004",
"category": "etikk",
"subcategory": "Grunnbegreper",
"week": 3,
"front": "Hva er moralrelativisme?",
"back": "Synet på at det ikke finnes absolutte, uforanderlige moralske verdier; verdiene er relative og varierer med omstendighetene og kulturen. «Mennesket er alle tings mål» alt er subjektivt."
},
{
"id": "fc-005",
"category": "etikk",
"subcategory": "Prinsipper",
"week": 3,
"front": "Nevn de seks etiske prinsippene.",
"back": "1) Likhetsprinsippet, 2) Autonomiprinsippet, 3) Velgjørenhetsprinsippet (beneficence), 4) Ikke-skade-prinsippet (non-maleficence), 5) Rettferdighetsprinsippet (justice), 6) Føre-var-prinsippet (precautionary principle)."
},
{
"id": "fc-006",
"category": "etikk",
"subcategory": "Prinsipper",
"week": 3,
"front": "Forklar likhetsprinsippet.",
"back": "Like tilfeller skal behandles likt. Alle skal ha samme regler og muligheter. Eksempel: likelønn for likt arbeid, lik tilgang til helsetjenester."
},
{
"id": "fc-007",
"category": "etikk",
"subcategory": "Prinsipper",
"week": 3,
"front": "Forklar autonomiprinsippet.",
"back": "Retten til å bestemme over seg selv. Mennesket eier seg selv, sin kropp og sitt liv, og har personlig handlefrihet. Knyttet til FN: «Alle mennesker er født frie og med samme menneskeverd og menneskerettigheter»."
},
{
"id": "fc-008",
"category": "etikk",
"subcategory": "Prinsipper",
"week": 3,
"front": "Forklar velgjørenhetsprinsippet (beneficence).",
"back": "Plikten til å gjøre godt mot andre, bidra til andres velvære og forhindre eller fjerne skade. Eksempel: filantropi (Bill & Melinda Gates Foundation), frivillig hjelp til eldre."
},
{
"id": "fc-009",
"category": "etikk",
"subcategory": "Prinsipper",
"week": 3,
"front": "Forklar ikke-skade-prinsippet.",
"back": "Forpliktelse til å sikre at vi ikke skader andre gjennom våre handlinger eller unnlatelser. Gjelder ved kjent risiko. Eksempel: sikkerhetsprotokoller på arbeidsplassen, unngå utslipp av skadelige kjemikalier."
},
{
"id": "fc-010",
"category": "etikk",
"subcategory": "Prinsipper",
"week": 3,
"front": "Forklar rettferdighetsprinsippet.",
"back": "Rettferdig behandling tilpasset individuelle behov og situasjoner. Ulik behandling kan være nødvendig for å sikre at alle får det de trenger for å ha like muligheter. Ikke nødvendigvis lik behandling."
},
{
"id": "fc-011",
"category": "etikk",
"subcategory": "Prinsipper",
"week": 3,
"front": "Forklar føre-var-prinsippet.",
"back": "«Bedre føre var enn etter snar.» Anvendes ved stor vitenskapelig usikkerhet når mulige skadevirkninger kan være alvorlige eller uopprettelige. Manglende kunnskap er ikke grunn til å gjøre ingenting. Eksempel: strenge kjemikaliereguleringer, COVID-lockdown."
},
{
"id": "fc-012",
"category": "etikk",
"subcategory": "Prinsipper",
"week": 3,
"front": "Hva er forskjellen mellom likhetsprinsippet og rettferdighetsprinsippet?",
"back": "Likhet = lik behandling for like tilfeller (samme regler for alle). Rettferdighet = rimelig behandling basert på individuelle behov (kan kreve ulik behandling). Eksempel: utvidet eksamenstid for studenter med dysleksi er rettferdig men ikke likt."
},
{
"id": "fc-013",
"category": "etikk",
"subcategory": "Prinsipper",
"week": 5,
"front": "Hva er forskjellen mellom ikke-skade-prinsippet og føre-var-prinsippet?",
"back": "Ikke-skade gjelder ved kjent risiko ikke gjør det vi vet skader. Føre-var gjelder ved usikker, men potensielt alvorlig risiko vær forsiktig selv uten full kunnskap. Eksempel KI: bevist diskriminerende system (ikke-skade) vs. nytt system med ukjente effekter (føre-var)."
},
{
"id": "fc-014",
"category": "etikk",
"subcategory": "Dilemma",
"week": 3,
"front": "Hva er et etisk dilemma?",
"back": "En situasjon der to eller flere etiske prinsipper (eller teorier) står mot hverandre. Krever vurdering av argumenter for begge sider og begrunnelse for valget."
},
{
"id": "fc-015",
"category": "etikk",
"subcategory": "Dilemma",
"week": 3,
"front": "Hva er forskjellen mellom ekte og falskt etisk dilemma?",
"back": "Ekte dilemma: begge handlingsalternativene er like gode eller dårlige (eks. varsling vs. taushet). Falskt dilemma: det er klart hva som er riktig, men fristende å velge noe annet (eks. å jukse på eksamen)."
},
{
"id": "fc-016",
"category": "etikk",
"subcategory": "Hovedteorier",
"week": 4,
"front": "Hva er konsekvensetikk?",
"back": "Etisk retning som vurderer om en handling er riktig eller gal ut fra konsekvensene den får. Den mest kjente formen er utilitarisme. Tilhørende teorier: utilitarisme, egoisme, hedonisme."
},
{
"id": "fc-017",
"category": "etikk",
"subcategory": "Hovedteorier",
"week": 4,
"front": "Hva er ikke-konsekvensetikk?",
"back": "Vurderer handlinger ut fra andre kriterier enn konsekvenser plikter, regler, verdier, karakter og intensjoner. Sentrale teorier: pliktetikk (Kant) og dydsetikk (Aristoteles)."
},
{
"id": "fc-018",
"category": "etikk",
"subcategory": "Hovedteorier",
"week": 4,
"front": "Forklar utilitarismen og hvem som er hovedrepresentanten.",
"back": "Konsekvensetisk teori: en handling er moralsk riktig hvis den maksimerer nytte «mest mulig lykke til flest mulig». Hovedrepresentant: John Stuart Mill (18061873). Bygger på Bentham."
},
{
"id": "fc-019",
"category": "etikk",
"subcategory": "Hovedteorier",
"week": 4,
"front": "Forklar pliktetikken (deontologi).",
"back": "Etisk teori som fokuserer på handlingens iboende riktighet uavhengig av konsekvenser. Følg regler og plikter. Hovedrepresentant: Immanuel Kant. «Riktige handlinger følger regler og plikter»."
},
{
"id": "fc-020",
"category": "etikk",
"subcategory": "Hovedteorier",
"week": 4,
"front": "Hva er det kategoriske imperativ?",
"back": "Kants pliktetiske prinsipp. Første formulering: «Handle etter den maksimen gjennom hvilken du samtidig kan ville at den skal bli en allmenn lov.» Andre formulering: behandle alltid mennesker som mål i seg selv, aldri bare som middel."
},
{
"id": "fc-021",
"category": "etikk",
"subcategory": "Hovedteorier",
"week": 4,
"front": "Hva betyr Kants humanitetsformulering?",
"back": "«Handle slik at du alltid bruker menneskeheten både i din egen person og i enhver annens person samtidig som et formål og aldri bare som et middel.» Hvert menneske har egen verdighet og egne mål kan ikke bare brukes som verktøy."
},
{
"id": "fc-022",
"category": "etikk",
"subcategory": "Hovedteorier",
"week": 4,
"front": "Forklar dydsetikken og hvem som er hovedrepresentanten.",
"back": "Aristotelisk teori som fokuserer på personens karakter og dyder (ærlighet, mot, visdom). Spør: «Hva ville et godt menneske gjort?» Moralen ligger i hvem du er. Mål: eudaimonia (det gode liv). Krever praktisk klokskap (phronesis)."
},
{
"id": "fc-023",
"category": "etikk",
"subcategory": "Hovedteorier",
"week": 4,
"front": "Gi tre eksempler på aristoteliske dyder.",
"back": "Mot (brannmann som risikerer eget liv), ærlighet (student som innrømmer feil), rettferdighet (upartisk dommer), medfølelse (frivillig hjelper), visdom (langsiktig leder)."
},
{
"id": "fc-024",
"category": "etikk",
"subcategory": "Hovedteorier",
"week": 4,
"front": "Hva er egoisme som etisk teori?",
"back": "Teorien sier at det riktige er det som er best for en selv. Fokus: egeninteresse. Egoister mener det er naturlig og riktig å maksimere egen fordel. Ikke i pensum, men brukes for forståelse."
},
{
"id": "fc-025",
"category": "etikk",
"subcategory": "Hovedteorier",
"week": 4,
"front": "Hva er hedonisme?",
"back": "Etisk teori som sier at det gode er nytelse og det onde er smerte. Mennesket bør maksimere nytelse og minimere smerte. Handler om HVA som er godt, ikke hvem som får godene. Kan være egoistisk eller altruistisk."
},
{
"id": "fc-026",
"category": "etikk",
"subcategory": "Hovedteorier",
"week": 4,
"front": "Hva er forskjellen på hedonisme og egoisme?",
"back": "Hedonisme handler om HVA som er godt (nytelse). Egoisme handler om HVEM som skal få godene (meg selv). En egoist trenger ikke være hedonist (kan ønske penger, makt), og en hedonist trenger ikke være egoistisk."
},
{
"id": "fc-027",
"category": "etikk",
"subcategory": "Hovedteorier",
"week": 4,
"front": "Hva er diskursetikk og hvilke 4 kjennetegn har en praktisk diskurs?",
"back": "Habermas-inspirert tilnærming der svaret på rett handling ligger i mellommenneskelig kommunikasjon. 4 kjennetegn: 1) full offentlighet, 2) lik rett til å delta, 3) frivillig og uten tvang, 4) det beste argumentet vinner."
},
{
"id": "fc-028",
"category": "etikk",
"subcategory": "Beslutningsmodeller",
"week": 5,
"front": "Hva er Kvalnes' Navigasjonshjul, og hvilke seks sektorer har det?",
"back": "Etisk beslutningsmodell med spørsmålet «Hva gjør du?» i sentrum. Seks sektorer: Juss (lovlig?), Identitet (samsvar med verdier?), Moral (riktig?), Omdømme (beholder troverdighet?), Økonomi (lønnsomt?), Etikk (lar det seg begrunne?)."
},
{
"id": "fc-029",
"category": "etikk",
"subcategory": "Beslutningsmodeller",
"week": 5,
"front": "Beskriv Crane og Mattens 5-fasemodell for etiske beslutninger.",
"back": "1) Identifikasjon av problem/mulighet, 2) Innsamling av informasjon og vurdering, 3) Valg mellom alternativer, 4) Gjennomføring av beslutning, 5) Resultat/læring. Sirkulær modell som sløyfer tilbake til fase 1."
},
{
"id": "fc-030",
"category": "etikk",
"subcategory": "Forretningsetikk",
"week": 2,
"front": "Hva er forretningsetikk (business ethics)?",
"back": "Å anvende etiske prinsipper i en forretningskontekst ta moralsk forsvarlige og ansvarlige beslutninger utover bare å følge loven. Omfatter ærlighet, rettferdig behandling, åpenhet og unngåelse av korrupsjon."
},
{
"id": "fc-031",
"category": "etikk",
"subcategory": "Beslutningsmodeller",
"week": 5,
"front": "Når kan man vike fra likhetsprinsippet?",
"back": "Når ulikheter er relevante, og når lik behandling fører til urettferdige konsekvenser. Eksempel: tilrettelegging for studenter med dysleksi eller ansatte med kronisk sykdom."
},
{
"id": "fc-032",
"category": "etikk",
"subcategory": "Hovedteorier",
"week": 4,
"front": "Sammenlign de tre hovedteoriene i én setning hver (Kant, Mill, Aristoteles).",
"back": "Kant (pliktetikk): følg regler, uansett konsekvenser. Mill (utilitarisme): velg det som gir mest lykke for flest. Aristoteles (dydsetikk): vær et godt menneske la handlinger følge karakter."
},
{
"id": "fc-033",
"category": "baerekraft",
"subcategory": "Definisjoner",
"week": 2,
"front": "Hva er Brundtland-definisjonen av bærekraftig utvikling?",
"back": "«En utvikling som imøtekommer dagens behov uten å ødelegge mulighetene for at kommende generasjoner skal få dekket sine behov.» (Verdenskommisjonen for miljø og utvikling, 1987, ledet av Gro Harlem Brundtland)."
},
{
"id": "fc-034",
"category": "baerekraft",
"subcategory": "Definisjoner",
"week": 2,
"front": "Hva er Triple Bottom Line (TBL)?",
"back": "Modell av John Elkington (1997) som sier at virksomheter må måles på tre dimensjoner: People (sosial), Planet (miljø), Profit (økonomi). De tre pilarene av bærekraft."
},
{
"id": "fc-035",
"category": "baerekraft",
"subcategory": "Definisjoner",
"week": 2,
"front": "Hvor mange bærekraftsmål har FN og hva er hovedformålet?",
"back": "17 mål og 169 delmål. Formål: utrydde fattigdom, bekjempe ulikhet og stoppe klimaendringene innen 2030. «Verdens felles arbeidsplan.» Alle skal oppnås ingen prioritering."
},
{
"id": "fc-036",
"category": "baerekraft",
"subcategory": "SDG",
"week": 7,
"front": "Forklar SDG-kaken (Stockholm Resilience Centre).",
"back": "3-lags struktur: Biosphere (Planet, SDG 6/13/14/15) er grunnlaget. Society (People, SDG 1-5, 7, 11, 16) hviler på biosfæren. Economy (SDG 8, 9, 10, 12) hviler på samfunn. SDG 17 (partnerskap) binder alt sammen. Økonomien er en del av samfunnet som er en del av biosfæren."
},
{
"id": "fc-037",
"category": "baerekraft",
"subcategory": "FN",
"week": 7,
"front": "Når og hvorfor ble FN etablert?",
"back": "Etablert 24. oktober 1945 etter andre verdenskrig for å forhindre nye kriger. Hovedområder: 1) fred og sikkerhet, 2) bærekraftig utvikling, 3) menneskerettigheter."
},
{
"id": "fc-038",
"category": "baerekraft",
"subcategory": "FN",
"week": 7,
"front": "Hvilke tre roller har FN?",
"back": "1) Møteplass for medlemslandene (Generalforsamling, Sikkerhetsråd, Menneskerettighetsråd). 2) Organisasjon med egne ansatte (Generalsekretæren). 3) Skaper av internasjonale lover og regler (folkeretten) «moralsk dommer»."
},
{
"id": "fc-039",
"category": "baerekraft",
"subcategory": "Planet",
"week": 11,
"front": "Hva er planetens tålegrenser?",
"back": "Forskningsbasert rammeverk (Rockström/Stockholm Resilience Centre, fra 2009) som angir hvor mye intakt natur menneskeheten trenger for å leve trygt. 9 grenser definerer «safe operating space»."
},
{
"id": "fc-040",
"category": "baerekraft",
"subcategory": "Planet",
"week": 11,
"front": "Nevn de ni planetære tålegrensene.",
"back": "1) Klimaendringer, 2) Tap av biologisk mangfold, 3) Nitrogen-/fosforsyklus, 4) Havforsuring, 5) Endringer i arealbruk, 6) Ferskvannsforbruk, 7) Atmosfærisk aerosolkonsentrasjon, 8) Ozonlagsnedbrytning, 9) Nye kjemiske stoffer (plast m.fl.)."
},
{
"id": "fc-041",
"category": "baerekraft",
"subcategory": "Planet",
"week": 11,
"front": "Hvor mange av de planetære tålegrensene er overskredet per 2025?",
"back": "7 av 9 tålegrenser er overskredet (status fra Stockholm Resilience Centre 2025). Status har eskalert: 2009 (3 av 7), 2015 (4 av 7), 2023 (6 av 9), 2025 (7 av 9)."
},
{
"id": "fc-042",
"category": "baerekraft",
"subcategory": "Modeller",
"week": 11,
"front": "Forklar Smultringmodellen til Kate Raworth.",
"back": "Modell fra 2017. Indre sirkel = sosialt fundament (mat, vann, helse, utdanning, likestilling, bolig osv.) under = underforbruk. Ytre sirkel = økologisk tak (planetens tålegrenser) over = overforbruk. Mellom: «et trygt og rettferdig rom for menneskeheten»."
},
{
"id": "fc-043",
"category": "baerekraft",
"subcategory": "Sirkulær økonomi",
"week": 11,
"front": "Definer sirkulær økonomi.",
"back": "Et økonomisk system der produktets reise fører tilbake til der det begynte søker å minimere skade på miljøet ved å resirkulere, gjenbruke eller regenerere materialer. Reduserer avfall, råmaterialer og utslipp (Oxford Dictionary 2022)."
},
{
"id": "fc-044",
"category": "baerekraft",
"subcategory": "Sirkulær økonomi",
"week": 11,
"front": "Hvilke faser har sirkulærmodellen?",
"back": "Råmaterialer → Bærekraftig design → Produksjon → Distribusjon → Forbruk/Gjenbruk/Reparasjon → Innsamling → Resirkulering → tilbake til råmaterialer. Restavfall som «tap»."
},
{
"id": "fc-045",
"category": "baerekraft",
"subcategory": "Sirkulær økonomi",
"week": 11,
"front": "Sammenlign lineær, resirkulerings- og sirkulær økonomi.",
"back": "Lineær: Take-Make-Use-Waste (mye avfall). Resirkulering: Take-Make-Use-Recycle (mindre avfall). Sirkulær: Take-Make-Use + Reuse/Repair/Recycle/Return (ingen avfall som mål)."
},
{
"id": "fc-046",
"category": "baerekraft",
"subcategory": "Sirkulær økonomi",
"week": 11,
"front": "Hva er Norges sirkularitet, og hva er global sirkularitet?",
"back": "Norge: bare 2,4 % sirkulært. Verden globalt: 8,6 % sirkulært 91,4 % av materialer kastes eller forsvinner. (Circularity Gap Report 2021)."
},
{
"id": "fc-047",
"category": "baerekraft",
"subcategory": "Sirkulær økonomi",
"week": 11,
"front": "Hva er 10R-rammeverket (Kirchher)?",
"back": "Hierarki av sirkulære strategier fra mest til minst sirkulær: R0 Refuse, R1 Rethink, R2 Reduce (smartere bruk), R3 Reuse, R4 Repair, R5 Refurbish, R6 Remanufacture, R7 Repurpose (forlenge levetid), R8 Recycle, R9 Recover (materialebruk)."
},
{
"id": "fc-048",
"category": "baerekraft",
"subcategory": "Vekst",
"week": 16,
"front": "Hva er motvekst (degrowth)?",
"back": "Økonomisk, sosial og filosofisk bevegelse som utfordrer ideen om uendelig økonomisk vekst. Mener vekst fører til miljøskader, ulikhet og overforbruk og bør begrenses for bærekraft og livskvalitet."
},
{
"id": "fc-049",
"category": "baerekraft",
"subcategory": "Vekst",
"week": 16,
"front": "Hvilke fire kjernepilarer har motvekstbevegelsen?",
"back": "1) Ressursbevissthet (redusere overforbruk, sirkulær økonomi), 2) Rettferdighet (sosial likhet), 3) Lokalisering (lokale samfunn fremfor globalisering), 4) Livskvalitet (immaterielle verdier som helse, fellesskap, natur)."
},
{
"id": "fc-050",
"category": "baerekraft",
"subcategory": "Vekst",
"week": 16,
"front": "Hva er forskjellen mellom absolutt og relativ frikobling (decoupling)?",
"back": "Absolutt frikobling: utslipp går NED mens BNP fortsetter å vokse. Relativ frikobling: utslipp øker mindre enn BNP, men øker fortsatt. Jason Hickels poeng: vi ser bare relativ frikobling, ikke absolutt derfor er grønn vekst urealistisk."
},
{
"id": "fc-051",
"category": "baerekraft",
"subcategory": "Vekst",
"week": 16,
"front": "Hva er forskjellen på grønn vekst og motvekst?",
"back": "Grønn vekst: fortsette vekst, men på en miljøvennlig måte (sirkulær økonomi, fornybar energi). Motvekst: redusere vekst for å oppnå bærekraft. Hickel kritiserer grønn vekst fordi vi kun oppnår relativ frikobling."
},
{
"id": "fc-052",
"category": "baerekraft",
"subcategory": "Klima",
"week": 11,
"front": "Hvilken temperaturøkning forventes i Norge mot 2100?",
"back": "Ca. 4,5 grader i høyutslippsscenario, ca. 2,7 grader i middels scenario. Mer nedbør, regnflommer, skred. Havnivåstigning mindre enn globalt pga. landheving. Varmere og surere havområder."
},
{
"id": "fc-053",
"category": "baerekraft",
"subcategory": "Historikk",
"week": 7,
"front": "Hva var Brundtland-rapporten?",
"back": "Rapporten *Our Common Future* (1987) fra FN-kommisjonen for miljø og utvikling, ledet av Gro Harlem Brundtland. Etablerte definisjonen av bærekraftig utvikling og knyttet sammen økonomi, miljø og sosiale forhold."
},
{
"id": "fc-054",
"category": "baerekraft",
"subcategory": "Historikk",
"week": 7,
"front": "Hva er Limits to Growth (1972)?",
"back": "Rapport fra Club of Rome som viste at ubegrenset vekst kunne føre til alvorlige miljø- og ressurskriser. Klassisk grunnlag for motvekstbevegelsen og bærekraftstenkning."
},
{
"id": "fc-055",
"category": "baerekraft",
"subcategory": "Pilarer",
"week": 2,
"front": "Hva inngår i den sosiale pilaren av bærekraft?",
"back": "Filantropi, ansattgoder, likestilling, menneskerettigheter, ingen barnearbeid. «People» i Triple Bottom Line."
},
{
"id": "fc-056",
"category": "baerekraft",
"subcategory": "Pilarer",
"week": 2,
"front": "Hva inngår i miljøpilaren av bærekraft?",
"back": "Økologi, økologisk produksjon og produkter, spare energi, CO2-reduksjon. «Planet» i Triple Bottom Line."
},
{
"id": "fc-057",
"category": "baerekraft",
"subcategory": "Pilarer",
"week": 2,
"front": "Hva inngår i den økonomiske pilaren av bærekraft?",
"back": "Bedriftsstyring, etikkodeks, beskyttelse av immaterielle rettigheter, forhold til investorer/leverandører/kunder, sikkerhet i drift og kvalitet på produkter. «Profit» i Triple Bottom Line."
},
{
"id": "fc-058",
"category": "baerekraft",
"subcategory": "Implementering",
"week": 16,
"front": "Hva er forskjellen på «strategi for bærekraft» og «bærekraft i strategien»?",
"back": "«Strategi for bærekraft» = egen sidestrategi for bærekraftsarbeid. «Bærekraft i strategien» = integrert i hele forretningsstrategien (mer modent). Tilsvarer proaktiv tilnærming og Porters CSV."
},
{
"id": "fc-059",
"category": "baerekraft",
"subcategory": "Implementering",
"week": 16,
"front": "Hva er sustainopreneurship?",
"back": "Miksen mellom entreprenørskap og bærekraft å løse sosiale og miljømessige problemer gjennom forretningsmodeller. Globale problemer blir forretningsmuligheter via bærekraftsinnovasjon."
},
{
"id": "fc-060",
"category": "baerekraft",
"subcategory": "Implementering",
"week": 16,
"front": "Beskriv de fem implementeringsstegene for bærekraft i en bedrift.",
"back": "1) Planlegging (strategi), 2) Interessentdialog (kartlegging, Kap. 7), 3) Rapportering (GRI, CSRD), 4) Verifikasjon (ISO 14001, tredjepart), 5) Oppfølging (kontinuerlig forbedring)."
},
{
"id": "fc-061",
"category": "samfunn",
"subcategory": "CSR",
"week": 2,
"front": "Definer CSR (Corporate Social Responsibility).",
"back": "Det ansvaret selskaper påtar seg for miljø, samfunn og mennesker som påvirkes av virksomheten, utover det som er lovpålagt. Frivillig ansvar utover lovkrav."
},
{
"id": "fc-062",
"category": "samfunn",
"subcategory": "CSR",
"week": 6,
"front": "Hva er Buchholtz og Carrolls definisjon av samfunnsansvar?",
"back": "«Bedriftens samfunnsansvar er det sosiale ansvaret bedriften har til samfunnets økonomiske, juridiske, etiske og filantropiske forventninger til organisasjoner på et gitt tidspunkt.» (Buchholtz & Carroll, 2009:40)."
},
{
"id": "fc-063",
"category": "samfunn",
"subcategory": "CSR",
"week": 8,
"front": "Beskriv Carrolls CSR-pyramide (1991) fra bunn til topp.",
"back": "1) Økonomisk ansvar vær lønnsom (grunnlaget), 2) Juridisk ansvar adlyd loven, 3) Etisk ansvar vær etisk (gjør det rette), 4) Filantropisk/frivillig ansvar vær en god bedriftsborger (gi tilbake)."
},
{
"id": "fc-064",
"category": "samfunn",
"subcategory": "CSR",
"week": 8,
"front": "Hvorfor er økonomisk ansvar grunnlaget i Carrolls pyramide?",
"back": "Fordi en bedrift som ikke er lønnsom ikke kan eksistere og dermed ikke kan oppfylle de andre ansvarsformene. «Grunnlaget som alt annet hviler på.»"
},
{
"id": "fc-065",
"category": "samfunn",
"subcategory": "CSR",
"week": 7,
"front": "Hvem regnes som «CSR-feltets far», og hvorfor?",
"back": "Howard R. Bowen, gjennom boken *Social Responsibilities of the Businessman* (1953). Introduserte CSR som et normativt begrep: «Hva bør en bedrift gjøre?» Bedrifter har moralsk ansvar utover profitt."
},
{
"id": "fc-066",
"category": "samfunn",
"subcategory": "Shareholder",
"week": 8,
"front": "Hva er Milton Friedmans aksjonærmodell?",
"back": "Friedman (1970): Bedrifters eneste samfunnsansvar er å maksimere profitt for aksjonærene innenfor lovens rammer. «The business of business is business.» Markedet, ikke bedriftene, skal løse samfunnsproblemer."
},
{
"id": "fc-067",
"category": "samfunn",
"subcategory": "Stakeholder",
"week": 6,
"front": "Hvem skrev Stakeholder-teorien, og når?",
"back": "R. Edward Freeman (f. 1951), amerikansk professor i forretningsetikk ved University of Virginia. Boken *Strategic Management: A Stakeholder Approach* (1984). «Faren» til stakeholderteorien."
},
{
"id": "fc-068",
"category": "samfunn",
"subcategory": "Stakeholder",
"week": 7,
"front": "Hva er forskjellen mellom primære og sekundære interessenter?",
"back": "Primære: direkte/transaksjonsbasert relasjon ansatte, kunder, eiere, investorer, leverandører, lokalsamfunn. Sekundære: indirekte frivillige organisasjoner, aktivister, myndigheter, medier."
},
{
"id": "fc-069",
"category": "samfunn",
"subcategory": "Stakeholder",
"week": 6,
"front": "Hva er forskjellen på shareholder og stakeholder?",
"back": "Shareholder = andelseier (aksjonær). Stakeholder = interessent enhver som påvirker eller blir påvirket av virksomheten. Friedmans smale syn (kun shareholders) vs. Freemans brede syn (alle stakeholders)."
},
{
"id": "fc-070",
"category": "samfunn",
"subcategory": "Stakeholder",
"week": 6,
"front": "Beskriv Mitchells modell for stakeholder-salience (1997).",
"back": "Mitchell, Agle & Wood (1997) klassifiserer interessenter etter tre dimensjoner: Makt (evne til å tvinge gjennom vilje), Legitimitet (sosialt akseptert krav), Hastverk/Urgency (tvingende nødvendig). Gir 7 kombinasjoner."
},
{
"id": "fc-071",
"category": "samfunn",
"subcategory": "Stakeholder",
"week": 6,
"front": "Hvilke syv interessent-kategorier gir Mitchells modell?",
"back": "1 kraft: Sovende (makt), Frivillig (legitimitet), Krevende (hastverk). 2 krefter: Dominerende (makt+legitimitet), Avhengig (legitimitet+hastverk), Farlig (makt+hastverk). 3 krefter: Avgjørende (alle tre) må prioriteres høyest."
},
{
"id": "fc-072",
"category": "samfunn",
"subcategory": "Stakeholder",
"week": 6,
"front": "Hva er 4-nivå kartleggingen av interessenter?",
"back": "Nivå 1: Ansatte (HMS, lønn via LO). Nivå 2: Direkte berørte (kunder, leverandører). Nivå 3: Indirekte berørte (myndigheter, media, NGO-er). Nivå 4: Globalt ansvar politisk samfunnsansvar, FNs bærekraftsmål."
},
{
"id": "fc-073",
"category": "samfunn",
"subcategory": "Institusjonell teori",
"week": 6,
"front": "Hva er forskjellen mellom institusjon og virksomhet?",
"back": "Institusjon = de usynlige reglene/normer/forventninger (formelle: lover; uformelle: tradisjoner). Virksomhet = konkret aktør (bedrift, skole, sykehus). Institusjonen er «hvordan ting bør være»; virksomheten må tilpasse seg for å få legitimitet."
},
{
"id": "fc-074",
"category": "samfunn",
"subcategory": "Institusjonell teori",
"week": 6,
"front": "Hva er Scotts tre søyler i institusjonell teori?",
"back": "1) Regulativ søyle (lover, regler «hva er lovlig?»). 2) Normativ søyle (verdier/normer «hva er rett?»). 3) Kulturell-kognitiv søyle (tatt-for-gitt antakelser «hva er fornuftig?»)."
},
{
"id": "fc-075",
"category": "samfunn",
"subcategory": "Institusjonell teori",
"week": 6,
"front": "Definer isomorfisme.",
"back": "Prosessen der organisasjoner blir mer like hverandre over tid som et resultat av press fra institusjonene. Press til konformitet fører til likhet i form/struktur."
},
{
"id": "fc-076",
"category": "samfunn",
"subcategory": "Institusjonell teori",
"week": 6,
"front": "Hva er legitimitet ifølge Suchman (1995)?",
"back": "«En generalisert oppfatning eller antagelse om at organisasjonens aktiviteter er ønskelige, velegnede eller passende innenfor et sosialt konstruert system av normer, antagelser og definisjoner.» Tre typer: juridisk, sosial, politisk."
},
{
"id": "fc-077",
"category": "samfunn",
"subcategory": "Institusjonell teori",
"week": 6,
"front": "Hvilke fire typer ansvar finnes en virksomhet (Kap. 5)?",
"back": "1) Moralsk ansvar (etikk), 2) Juridisk ansvar (loven), 3) Kausalt ansvar (årsakssammenheng), 4) Formelt ansvar (offisielle roller og plikter)."
},
{
"id": "fc-078",
"category": "samfunn",
"subcategory": "Institusjonell teori",
"week": 6,
"front": "Kan en virksomhet være moralsk ansvarlig?",
"back": "Pågående debatt: Peter French (JA virksomheter er moralske aktører). Thurlow & Poyner (NEI bare individer kan ha moralsk ansvar). Konklusjon: ja, men ikke på samme måte som enkeltmennesker."
},
{
"id": "fc-079",
"category": "samfunn",
"subcategory": "CSV",
"week": 8,
"front": "Hva er Creating Shared Value (CSV)?",
"back": "Forretningsstrategi av Porter & Kramer (2006) der bedrifter skaper økonomisk verdi samtidig som de løser samfunnsmessige utfordringer. Samfunnsproblemer integreres i kjernevirksomheten, ikke som filantropi."
},
{
"id": "fc-080",
"category": "samfunn",
"subcategory": "CSV",
"week": 8,
"front": "Hva er forskjellen mellom CSR og CSV?",
"back": "CSR: drevet av eksternt press, gir tilbake VED SIDEN AV kjernevirksomheten, fokus på filantropi. CSV: integrert i bedriftens strategi, kobler samfunnsforbedring DIREKTE til økonomisk verdiskaping, søker felles verdi."
},
{
"id": "fc-081",
"category": "samfunn",
"subcategory": "CSV",
"week": 8,
"front": "Hva er Porter & Kramers tre prinsipper for CSV i praksis?",
"back": "1) Rekonfigurere produkter og markeder (utvikle produkter som adresserer sosiale behov). 2) Redefinere produktivitetskjedene (ressurseffektivitet, arbeidstakerforhold). 3) Støtte lokal klyngeutvikling (utdanning, infrastruktur)."
},
{
"id": "fc-082",
"category": "samfunn",
"subcategory": "Eksternaliteter",
"week": 8,
"front": "Definer eksternalitet.",
"back": "Økonomiske kostnader eller fordeler som påvirker tredjeparter som ikke er direkte involvert i en økonomisk aktivitet, og som ikke reflekteres i markedsprisen. Markedssvikt."
},
{
"id": "fc-083",
"category": "samfunn",
"subcategory": "Eksternaliteter",
"week": 8,
"front": "Hva er forskjellen på negative og positive eksternaliteter? Gi eksempler.",
"back": "Negative: kostnader påført tredjepart utenfor markedspris (forurensning, støy, røyking). Positive: fordeler skapt for tredjepart (utdanning, vaksinasjon, FoU)."
},
{
"id": "fc-084",
"category": "samfunn",
"subcategory": "Eksternaliteter",
"week": 8,
"front": "Hvilke tre verktøy kan myndighetene bruke for å håndtere eksternaliteter?",
"back": "1) Reguleringer og lover (utslippsgrenser). 2) Skatter og avgifter (karbonavgift). 3) Subsidier og insentiver (utdanningstilskudd, forskningsstipender for positive eksternaliteter)."
},
{
"id": "fc-085",
"category": "samfunn",
"subcategory": "Eksternaliteter",
"week": 8,
"front": "Hva er samfunnsansvarlig forretningsdrift ifølge læreboka (s. 200)?",
"back": "«Å ta ansvar for de negative eksternalitetene som virksomheter skaper med andre ord å sørge for at virksomheten har en positiv nettoeffekt på samfunnet.»"
},
{
"id": "fc-086",
"category": "samfunn",
"subcategory": "Kritikk",
"week": 8,
"front": "Hva mener Joel Bakan med «den psykopatiske bedriften»?",
"back": "Bakan (2004, *The Corporation*): bedrifter fungerer som institusjonalisert psykopati pga. juridisk struktur og mål om profittmaksimering undergraver samfunnet. Ikke naturlov, men resultat av lovverket. Løsning: demokratisk styring og tilsyn."
},
{
"id": "fc-087",
"category": "samfunn",
"subcategory": "Sosial pilar",
"week": 10,
"front": "Hva er forskjellen på intern og ekstern sosial søyle?",
"back": "Intern: rettet mot ansatte obligatorisk (lovpålagt), avtalt (tariff/fagforening) og frivillig (CSR). Ekstern: rettet mot lokalsamfunn filantropi, sponsing, Cause Related Marketing."
},
{
"id": "fc-088",
"category": "samfunn",
"subcategory": "Sosial pilar",
"week": 10,
"front": "Hva er de tre nivåene i intern sosialpolitikk?",
"back": "1) Obligatorisk sosialpolitikk (lovpålagt Arbeidsmiljøloven m.fl.). 2) Avtalt sosialpolitikk (kollektive avtaler, fagforeninger). 3) Frivillig sosialpolitikk (CSR-tiltak utover lov/avtale). Bare frivillig er strengt sett CSR."
},
{
"id": "fc-089",
"category": "samfunn",
"subcategory": "Sosial pilar",
"week": 10,
"front": "Hva er Cause-Related Marketing (CRM)?",
"back": "Markedsføringsstrategi der bedriften donerer del av inntekter til veldedig sak hver gang kunden kjøper. Klassisk eksempel: American Express donerte 1 cent per kortbruk til restaureringen av Frihetsgudinnen i 1983 (1,7 mill. dollar)."
},
{
"id": "fc-090",
"category": "samfunn",
"subcategory": "Sosial pilar",
"week": 10,
"front": "Definer filantropi.",
"back": "Praksisen med å fremme andres velferd gjennom generøse donasjoner av penger, ressurser eller tid til veldedige formål. Tidlig form for CSR (Carnegie, Rockefeller). Eksempler: donasjoner, stipendier, bygging av skoler/sykehus, frivillig arbeid."
},
{
"id": "fc-091",
"category": "samfunn",
"subcategory": "Sosial pilar",
"week": 10,
"front": "Hva er et cafeteria system for ansattfordeler?",
"back": "Fleksibel fordelsplan der ansatte velger fordeler som passer egne behov. Tre varianter: 1) alt for alle, 2) buffetsystem (velg innen ramme), 3) alternativ meny. Øker motivasjon og medvirkning."
},
{
"id": "fc-092",
"category": "samfunn",
"subcategory": "Investeringer",
"week": 11,
"front": "Hva er samfunnsansvarlige investeringer (SRI)?",
"back": "Investeringsstrategi som integrerer etiske, miljømessige og sosiale betraktninger. Mål: finansiell lønnsomhet + ikke-finansielle kriterier. Vanlig: avkastning × risiko × tid. SRI legger til samfunnsansvar som 4. faktor."
},
{
"id": "fc-093",
"category": "samfunn",
"subcategory": "Investeringer",
"week": 11,
"front": "Hva står ESG for, og når ble det introdusert?",
"back": "Environmental, Social, Governance (norsk: Miljø-, Sosiale- og Forretningsetiske forhold). Introdusert av FN i 2006 (UN PRI Prinsipper for ansvarlige investeringer). EU tok det i bruk i 2020."
},
{
"id": "fc-094",
"category": "samfunn",
"subcategory": "Investeringer",
"week": 11,
"front": "Hva er de tre hovedvariantene av samfunnsansvarlige investeringer?",
"back": "1) Filtrering (positiv: velger beste; negativ: utelukker f.eks. våpen/tobakk/kull). 2) Aksjonærengasjement (aktiv påvirkning på generalforsamlinger). 3) Samfunnsinvesteringer (rettet mot trengende prosjekter)."
},
{
"id": "fc-095",
"category": "samfunn",
"subcategory": "Investeringer",
"week": 11,
"front": "Hva er mikrofinansiering, og hvem regnes som grunnleggeren?",
"back": "Finansiell strategi som gir små lån, spareordninger og finansielle tjenester til mennesker uten tilgang til tradisjonelle banker særlig i lavinntektsområder. Mohammad Yunus (Grameen Bank, Bangladesh, 1976) fikk Nobels fredspris."
},
{
"id": "verktoy-001",
"category": "verktoy",
"subcategory": "Standarder",
"week": 12,
"front": "Hva er forskjellen på obligatoriske og frivillige verktøy innen bærekraft?",
"back": "Obligatoriske: lover, forskrifter, reguleringer, rapporteringskrav (eks: CSRD, Åpenhetsloven, Grunnloven §112). Frivillige: ISO-standarder, GRI-rammeverk, miljømerker, Code of Conduct."
},
{
"id": "verktoy-002",
"category": "verktoy",
"subcategory": "Standarder",
"week": 12,
"front": "Beskriv ISO-trekanten med tre standarder.",
"back": "ISO 26000 = People/samfunnsansvar (IKKE sertifiserbar kun veiledende). ISO 14001 = Planet/miljø (sertifiserbar). ISO 9001 = Profit/kvalitetsledelse (sertifiserbar). Tilsvarer Triple Bottom Line."
},
{
"id": "verktoy-003",
"category": "verktoy",
"subcategory": "Rapportering",
"week": 12,
"front": "Hva er GRI (Global Reporting Initiative)?",
"back": "Mest brukte globale standard for bærekraftsrapportering. Frivillig, brukt av >10 000 virksomheter. Hjelper virksomheter rapportere påvirkninger på økonomi, miljø og mennesker på transparent og sammenlignbar måte. Internasjonalt «felles språk»."
},
{
"id": "verktoy-004",
"category": "verktoy",
"subcategory": "EU",
"week": 12,
"front": "Hva er CSRD og hvem gjelder direktivet for?",
"back": "Corporate Sustainability Reporting Directive EU-direktiv som erstatter NFRD. Krever ESG-rapportering med dobbel materialitet og lovpålagt attestasjon. Fra 2024 store foretak av allmenn interesse, 2025 store foretak, 2026 børsnoterte SMB."
},
{
"id": "verktoy-005",
"category": "verktoy",
"subcategory": "EU",
"week": 12,
"front": "Hva er dobbel vesentlighetsanalyse (dobbel materialitet)?",
"back": "Sentralt prinsipp i CSRD. Vurderer både 1) hvordan virksomheten påvirker miljø/samfunn (impact materiality) og 2) hvordan eksterne bærekraftsforhold påvirker virksomhetens økonomi (financial materiality). Gir helhetlig bilde av risiko og muligheter."
},
{
"id": "verktoy-006",
"category": "verktoy",
"subcategory": "EU",
"week": 12,
"front": "Hva er EUs Green Deal og hvilke tre hovedmål har den?",
"back": "EUs brede strategi for å gjøre Europa klimanøytralt innen 2050. Tre hovedmål: 1) ingen netto utslipp av klimagasser innen 2050, 2) økonomisk vekst løsrevet fra ressursbruk, 3) ingen person eller sted utelatt."
},
{
"id": "verktoy-007",
"category": "verktoy",
"subcategory": "EU",
"week": 12,
"front": "Hva er EU-taksonomien?",
"back": "Klassifiseringssystem som definerer hvilke økonomiske aktiviteter som kan regnes som bærekraftige. Del av EUs grønne giv. Hjelper investorer, selskaper og myndigheter med å identifisere og støtte bærekraftige prosjekter."
},
{
"id": "verktoy-008",
"category": "verktoy",
"subcategory": "Lover",
"week": 12,
"front": "Hva er Åpenhetsloven?",
"back": "«Lov om virksomheters åpenhet og arbeid med grunnleggende menneskerettigheter og anstendige arbeidsforhold.» Gjelder fra 1. juli 2022. Krever redegjørelse av aktsomhetsvurderinger for ansvarlige arbeidsforhold internt og i leverandørkjeden."
},
{
"id": "verktoy-009",
"category": "verktoy",
"subcategory": "Lover",
"week": 12,
"front": "Hva sier Grunnloven §112?",
"back": "«Enhver har rett til et miljø som sikrer helsen, og til en natur der produksjonsevne og mangfold bevares. Naturens ressurser skal disponeres ut fra en langsiktig og allsidig betraktning som ivaretar denne rett også for etterslekten.»"
},
{
"id": "verktoy-010",
"category": "verktoy",
"subcategory": "Implementering",
"week": 12,
"front": "Hva er Code of Conduct og hva er formålet?",
"back": "En bedrifts formelle erklæring om grunnleggende verdier og forretningsprinsipper. Formål: hjelpe ansatte med etisk navigasjon, gi føringer for beslutninger, læring, engasjement, styrke omdømme og tillit. Bør involvere ansatte i utforming."
},
{
"id": "verktoy-011",
"category": "verktoy",
"subcategory": "Implementering",
"week": 12,
"front": "Hva er forskjellen mellom reaktiv og proaktiv tilnærming til bærekraft?",
"back": "Reaktiv: defensiv, risikominimering, beskyttelse av omdømme, etterkommer kun lovkrav. Proaktiv: integrert i kjernevirksomhet, kultur og «DNA», bærekraft som strategisk mulighet og konkurransefortrinn."
},
{
"id": "verktoy-012",
"category": "verktoy",
"subcategory": "Standarder",
"week": 12,
"front": "Hva er tredjepartsverifikasjon, og hvilke former finnes?",
"back": "Uavhengig kontroll. Tre former: 1) Revisjon (gjennomgang av etisk regnskap), 2) Sertifisering iht. standard (eks: ISO 14001), 3) Miljømerker (Svanemerket, Debio, Fairtrade) autorisering av produkter."
},
{
"id": "verktoy-013",
"category": "verktoy",
"subcategory": "Standarder",
"week": 12,
"front": "Nevn norske miljømerker.",
"back": "Svanemerket, Debio (økologisk), Nøkkelhullet, Nyt Norge, Fairtrade, Dyrevernalliansen, Miljøfyrtårn. Alle er former for uavhengig tredjepartsverifisering på produktnivå."
},
{
"id": "verktoy-014",
"category": "verktoy",
"subcategory": "Rapportering",
"week": 12,
"front": "Hvilke CSRD-rapporteringstemaer finnes innen miljø (E1E5)?",
"back": "E1: Klimaendringer (tilpasning, reduksjon, energi). E2: Forurensning (luft/vann/jord, mikroplast). E3: Vann og marine ressurser. E4: Biomangfold og økosystemer. E5: Ressursbruk og sirkularitet."
},
{
"id": "verktoy-015",
"category": "verktoy",
"subcategory": "Rapportering",
"week": 12,
"front": "Hvilke CSRD-rapporteringstemaer finnes innen sosiale forhold (S1S4) og styring (G1)?",
"back": "S1: Egen arbeidskraft. S2: Arbeidere i verdikjeden. S3: Berørte lokalsamfunn. S4: Forbrukere og sluttbrukere. G1: Forretningsetikk (kultur, varslere, korrupsjon, dyrevelferd, lobbying, leverandørrelasjoner)."
},
{
"id": "verktoy-016",
"category": "verktoy",
"subcategory": "EU",
"week": 12,
"front": "Hva er CSDDD?",
"back": "Corporate Sustainability Due Diligence Directive EU-direktiv om aktsomhetsvurderinger. Del av Green Deal-virkemidlene sammen med EU-taksonomien (klassifisering) og CSRD (rapportering)."
},
{
"id": "verktoy-017",
"category": "verktoy",
"subcategory": "Standarder",
"week": 12,
"front": "Hva er SA8000?",
"back": "Internasjonal standard for arbeidstakerrettigheter, basert på ILO-konvensjoner. Sertifiseringsstandard for sosial ansvarlighet i arbeidsforhold."
},
{
"id": "case-001",
"category": "case",
"subcategory": "Verktøykasse",
"week": 4,
"front": "Hvilke verktøy bør du bruke i en case-drøfting på eksamen (oppgave 4)?",
"back": "1) Identifisere interessenter, 2) Identifisere prinsipper som står i konflikt, 3) Anvende de tre etiske teoriene (utilitarisme, pliktetikk, dydsetikk), 4) Skille ekte og falskt dilemma, 5) Konkludere med begrunnelse, 6) Tenk på TBL hvis bærekraft er relevant. Bruk gjerne Navigasjonshjulet."
},
{
"id": "case-002",
"category": "case",
"subcategory": "Friedman-Freeman",
"week": 8,
"front": "Beskriv tre posisjoner i CSR-debatten (Friedman, Bakan, Porter/Kramer).",
"back": "Friedman: profitt løser alt (markedstillit shareholder value). Bakan: profittjakt blir psykopatisk uten regulering (markedssvikt). Porter/Kramer: profitt og samfunnsverdi kan forenes (CSV)."
},
{
"id": "case-003",
"category": "case",
"subcategory": "Norske eksempler",
"week": 8,
"front": "Gi tre norske eksempler på CSV-praksis.",
"back": "1) Hoff (sunnere produkter folkehelse + nye markeder). 2) Yara (presisjonsgjødsel mindre utslipp + mer salg). 3) Den Lille Nøttefabrikken/Brynild (Mosambik-program bedre priser, treplanting, barnehager)."
},
{
"id": "case-004",
"category": "case",
"subcategory": "Skandinavia",
"week": 16,
"front": "Hvorfor regnes Skandinavia som leder innen samfunnsansvar og bærekraft? Hva er kritikken?",
"back": "Lederskap: sterke institusjoner, høy SDG-rangering, avansert lovverk (Åpenhetsloven, Grunnloven §112), trepartssamarbeid. Kritikk: høyt fotavtrykk per innbygger, eksport av forurensning, fortsatt olje-/gassproduksjon, «moralsk imperialisme»."
},
{
"id": "case-005",
"category": "case",
"subcategory": "Historikk",
"week": 7,
"front": "Sett opp den historiske utviklingen av CSR fra 1700 til i dag.",
"back": "17001800: individuell etikk (Kant, Smith). 18001900: sosialt ansvar, filantropi (Owen, Carnegie). 1953: CSR (Bowen). 1970: miljø/systemkritikk. 1987: Brundtland. 1997: TBL (Elkington). 2010: ESG. 2015: SDG/Paris."
},
{
"id": "case-006",
"category": "case",
"subcategory": "Politisk samfunnsansvar",
"week": 6,
"front": "Hva er politisk samfunnsansvar?",
"back": "«En utvidet styringsmodell der private bedrifter bidrar til global regulering og tilby offentlige goder» (s. 159). Begrunnes med at nasjonalstaten ikke alene kan håndtere globale utfordringer. Knyttes til FNs bærekraftsmål."
},
{
"id": "case-007",
"category": "case",
"subcategory": "Klassiske eksempler",
"week": 10,
"front": "Beskriv Bata-modellen som klassisk eksempel på sosial pilar.",
"back": "Tomáš Baťa (Tsjekkia, ca 19001932) skapte paternalistisk velferdsbedrift: 40-timers uke (mot 48), bygde hus for ansatte, sykehus, kantine for 33 000, kulturhus med kino. Filosofi: «co-workers, not employees every co-worker is an entrepreneur.»"
},
{
"id": "case-008",
"category": "case",
"subcategory": "Koblinger",
"week": 8,
"front": "Hvordan kobles eksternaliteter til Brundtlands bærekraftdefinisjon?",
"back": "Negative eksternaliteter (klimagassutslipp, forurensning) er det operative bærekraftproblemet. Brundtlands definisjon krever at vi internaliserer disse ellers ødelegger vi for fremtidige generasjoner. CSR = ta ansvar for negative eksternaliteter."
}
]

688
app/data/quiz.json Normal file
View File

@@ -0,0 +1,688 @@
[
{
"id": "q-001",
"category": "etikk",
"week": 2,
"question": "Hva er forskjellen mellom etikk og moral ifølge pensum?",
"options": [
"Etikk er praktiske normer, moral er teoretisk refleksjon",
"Etikk er et fag og systematisk refleksjon, moral er personlige/felles oppfatninger lært gjennom omgang med andre",
"Etikk er lovregulert, moral er frivillig",
"Det er ingen reell forskjell mellom dem"
],
"correct": 1,
"explanation": "Etikk er et fag og systematisk refleksjon over hva som er rett og galt, læres gjennom studier. Moral er de personlige og felles oppfatningene om rett og galt, læres gjennom omgang med andre mennesker."
},
{
"id": "q-002",
"category": "etikk",
"week": 3,
"question": "Hvilket av de seks etiske prinsippene handler om at like tilfeller skal behandles likt?",
"options": [
"Rettferdighetsprinsippet",
"Autonomiprinsippet",
"Likhetsprinsippet",
"Velgjørenhetsprinsippet"
],
"correct": 2,
"explanation": "Likhetsprinsippet (Principle of equality) sier at like tilfeller skal behandles likt, og at alle skal få de samme mulighetene. Rettferdighetsprinsippet handler derimot om rimelig behandling tilpasset individuelle behov."
},
{
"id": "q-003",
"category": "etikk",
"week": 3,
"question": "Hva er hovedforskjellen mellom ikke-skade-prinsippet og føre-var-prinsippet?",
"options": [
"Ikke-skade gjelder bedrifter, føre-var gjelder myndigheter",
"Ikke-skade gjelder kjent risiko, føre-var gjelder usikker, potensielt alvorlig risiko",
"Ikke-skade er lovpålagt, føre-var er frivillig",
"Det er ingen forskjell de er synonymer"
],
"correct": 1,
"explanation": "Ikke-skade-prinsippet (non-maleficence) anvendes når risikoen er kjent. Føre-var-prinsippet anvendes ved vitenskapelig usikkerhet der mulige skader kan være alvorlige eller uopprettelige manglende kunnskap er ikke grunn til å gjøre ingenting."
},
{
"id": "q-004",
"category": "etikk",
"week": 4,
"question": "Hvem regnes som grunnleggeren av pliktetikken og det kategoriske imperativ?",
"options": [
"John Stuart Mill",
"Immanuel Kant",
"Aristoteles",
"Jürgen Habermas"
],
"correct": 1,
"explanation": "Immanuel Kant (1724-1804) er pliktetikkens grunnlegger. Hans kategoriske imperativ sier at man skal handle etter regler som kunne vært universelle, og behandle mennesker som mål aldri kun som middel."
},
{
"id": "q-005",
"category": "etikk",
"week": 4,
"question": "Hvilken etisk teori sier at en handling er moralsk riktig hvis den gir størst mulig lykke til flest mulig?",
"options": [
"Pliktetikk",
"Dydsetikk",
"Utilitarisme",
"Diskursetikk"
],
"correct": 2,
"explanation": "Utilitarismen, hovedsakelig knyttet til John Stuart Mill, sier at en handling er moralsk riktig hvis den maksimerer nytte det vil si størst mulig lykke eller velvære for flest mulig mennesker. Det er en form for konsekvensetikk."
},
{
"id": "q-006",
"category": "etikk",
"week": 4,
"question": "Hvilken etiker stilte spørsmålet 'Hva ville et godt menneske gjort?' og fokuserte på karakter og dyder?",
"options": [
"Immanuel Kant",
"Jeremy Bentham",
"Aristoteles",
"Adam Smith"
],
"correct": 2,
"explanation": "Aristoteles er grunnleggeren av dydsetikken (virtue ethics). Den fokuserer på menneskets karakter og dyder (mot, ærlighet, visdom). Praktisk klokskap (phronesis) og eudaimonia (det gode liv) er sentrale begreper."
},
{
"id": "q-007",
"category": "etikk",
"week": 4,
"question": "Hvilken formulering er Kants 'humanitetsformulering' av det kategoriske imperativ?",
"options": [
"Handle etter den maksimen du kan ville skal bli allmenn lov",
"Handle slik at du alltid bruker menneskeheten som et mål, aldri bare som et middel",
"Den største lykke for det største antall",
"Vær et godt menneske med praktisk klokskap"
],
"correct": 1,
"explanation": "Kants humanitetsformulering sier: 'Handle slik at du alltid bruker menneskeheten både i din egen person og i enhver annens person samtidig som et formål og aldri bare som et middel.' I næringsliv betyr dette at ansatte ikke kun skal ses som produksjonsfaktorer."
},
{
"id": "q-008",
"category": "etikk",
"week": 5,
"question": "Hvilket prinsipp i Kvalnes' navigasjonshjul stiller spørsmålet 'Er det lovlig?'",
"options": [
"Etikk",
"Moral",
"Juss",
"Omdømme"
],
"correct": 2,
"explanation": "Juss-sektoren i Kvalnes' navigasjonshjul stiller spørsmålet 'Er det lovlig?'. De seks sektorene er: Juss (lovlig?), Identitet/verdi (samsvar med verdier?), Moral (riktig?), Omdømme (troverdighet?), Økonomi (lønner det seg?), Etikk (lar det seg begrunne?)."
},
{
"id": "q-009",
"category": "etikk",
"week": 5,
"question": "Hvor mange sektorer/perspektiver har Kvalnes' navigasjonshjul?",
"options": [
"Fire",
"Fem",
"Seks",
"Syv"
],
"correct": 2,
"explanation": "Navigasjonshjulet har seks sektorer med 'Hva gjør du?' i sentrum: Juss, Identitet/verdi, Moral, Omdømme, Økonomi og Etikk. Modellen brukes for å analysere etiske dilemmaer fra flere perspektiver."
},
{
"id": "q-010",
"category": "etikk",
"week": 5,
"question": "Hva er det første steget i Crane og Mattens 5-fasemodell for etiske beslutninger?",
"options": [
"Innsamling av informasjon og vurdering",
"Identifikasjon av et problem eller mulighet",
"Valg mellom alternativer",
"Gjennomføring av beslutning"
],
"correct": 1,
"explanation": "Fase 1 i Crane og Mattens modell er Identifikasjon av et problem eller mulighet. Deretter følger: 2) Innsamling/vurdering, 3) Valg mellom alternativer, 4) Gjennomføring, 5) Resultat/læring (sirkulær sløyfer tilbake til fase 1)."
},
{
"id": "q-011",
"category": "etikk",
"week": 4,
"question": "Hva er hovedforskjellen mellom konsekvensetikk og ikke-konsekvensetikk?",
"options": [
"Konsekvensetikk vurderer handlinger ut fra utfall, ikke-konsekvensetikk ut fra plikter, regler, karakter eller intensjon",
"Konsekvensetikk er moderne, ikke-konsekvensetikk er klassisk",
"Konsekvensetikk gjelder bedrifter, ikke-konsekvensetikk gjelder individer",
"Konsekvensetikk er deontologisk, ikke-konsekvensetikk er teleologisk"
],
"correct": 0,
"explanation": "Konsekvensetikk (teleologi) vurderer riktigheten av en handling ut fra dens konsekvenser (eks. utilitarisme). Ikke-konsekvensetikk vurderer handlinger ut fra plikter (Kant), karakter (Aristoteles) eller intensjoner ikke utfall."
},
{
"id": "q-012",
"category": "etikk",
"week": 3,
"question": "Hva kjennetegner et 'ekte' etisk dilemma ifølge pensum?",
"options": [
"Det er klart hva som er riktig, men fristende å velge noe annet",
"Begge handlingsalternativene er like gode eller i det minste ikke dårligere valg",
"Det er en konflikt mellom personlig moral og lovverket",
"Det handler alltid om bestikkelse i internasjonale forhandlinger"
],
"correct": 1,
"explanation": "Et ekte dilemma oppstår når begge handlingsalternativene er like gode eller i det minste ikke dårligere valg. Et falskt dilemma er når det er klart hva som er riktig, men fristende å velge noe annet (eks. å jukse)."
},
{
"id": "q-013",
"category": "etikk",
"week": 3,
"question": "Hva er forskjellen mellom normativ og deskriptiv etikk?",
"options": [
"Normativ etikk beskriver hva folk faktisk gjør, deskriptiv etikk anbefaler hva man bør gjøre",
"Normativ etikk gir veiledning om hva man bør gjøre, deskriptiv etikk beskriver hva folk faktisk tror og gjør uten å bedømme",
"Normativ etikk er religiøs, deskriptiv etikk er sekulær",
"Normativ etikk gjelder individer, deskriptiv etikk gjelder organisasjoner"
],
"correct": 1,
"explanation": "Normativ etikk forsøker å fastsette hva som er moralsk riktig og galt, og gir veiledning om hvordan vi bør handle. Deskriptiv etikk beskriver og analyserer hva mennesker faktisk tror om moral og hvordan de handler, uten å bedømme."
},
{
"id": "q-014",
"category": "etikk",
"week": 5,
"question": "Hvilket dyrebart begrep i dydsetikken refererer til 'det gode, blomstrende liv' som normativt mål?",
"options": [
"Phronesis",
"Eudaimonia",
"Telos",
"Ataraxia"
],
"correct": 1,
"explanation": "Eudaimonia er det gode, blomstrende liv i aristotelisk dydsetikk det normative målet. Phronesis er den praktiske klokskapen som kreves for å oppnå det. Begge er sentrale begreper i Aristoteles' etikk."
},
{
"id": "q-015",
"category": "baerekraft",
"week": 2,
"question": "Hvem ledet kommisjonen som i 1987 ga den klassiske definisjonen av bærekraftig utvikling?",
"options": [
"Kofi Annan",
"Gro Harlem Brundtland",
"Kate Raworth",
"John Elkington"
],
"correct": 1,
"explanation": "Gro Harlem Brundtland ledet Verdenskommisjonen for miljø og utvikling som i 1987 publiserte rapporten 'Our Common Future'. Definisjonen: 'En utvikling som imøtekommer dagens behov uten å ødelegge mulighetene for at kommende generasjoner skal få dekket sine behov.'"
},
{
"id": "q-016",
"category": "baerekraft",
"week": 2,
"question": "Hva står de tre P-ene i Triple Bottom Line (TBL) for?",
"options": [
"People, Profit, Process",
"People, Planet, Profit",
"Planet, Politics, Profit",
"People, Performance, Planet"
],
"correct": 1,
"explanation": "Triple Bottom Line (Elkington 1997) består av de tre P-ene: People (sosiale forhold), Planet (miljø/økologi) og Profit (økonomi). Disse kalles også de 'tre pilarene' av bærekraft."
},
{
"id": "q-017",
"category": "baerekraft",
"week": 2,
"question": "Hvor mange bærekraftsmål (SDGs) og delmål har FN vedtatt for 2030?",
"options": [
"15 mål og 150 delmål",
"17 mål og 169 delmål",
"20 mål og 200 delmål",
"12 mål og 100 delmål"
],
"correct": 1,
"explanation": "FNs bærekraftsmål (SDG) består av 17 mål og 169 delmål, vedtatt i 2015 med frist i 2030. Alle målene skal oppnås det er ingen prioritering eller rangering."
},
{
"id": "q-018",
"category": "baerekraft",
"week": 11,
"question": "Hvem utviklet smultringmodellen (Doughnut Economics)?",
"options": [
"John Elkington",
"Kate Raworth",
"Michael Porter",
"Johan Rockström"
],
"correct": 1,
"explanation": "Smultringmodellen ble utviklet av økonomen Kate Raworth (2017). Den indre sirkelen er det sosiale fundamentet (grunnleggende behov), den ytre sirkelen er det økologiske taket (planetens tålegrenser). Mellom dem ligger 'et trygt og rettferdig rom for menneskeheten'."
},
{
"id": "q-019",
"category": "baerekraft",
"week": 11,
"question": "Hvor mange planetariske tålegrenser (planetary boundaries) er det i rammeverket fra Stockholm Resilience Centre?",
"options": [
"Syv",
"Åtte",
"Ni",
"Ti"
],
"correct": 2,
"explanation": "Rammeverket har ni tålegrenser: klimaendringer, tap av biologisk mangfold, nitrogen-/fosforsyklus, havforsuring, endringer i arealbruk, ferskvannsforbruk, atmosfærisk aerosolkonsentrasjon, ozonlagsnedbrytning og nye kjemiske stoffer."
},
{
"id": "q-020",
"category": "baerekraft",
"week": 11,
"question": "Hva utgjør den indre sirkelen i smultringmodellen?",
"options": [
"Økologisk tak / planetens tålegrenser",
"Sosialt fundament med grunnleggende behov",
"Profittmargin",
"Bedriftens kjernevirksomhet"
],
"correct": 1,
"explanation": "Den indre sirkelen i smultringmodellen er det sosiale fundamentet grunnleggende behov som mat, vann, helse, utdanning, likestilling, bolig, energi, fred, inntekt og arbeid. Å falle innenfor betyr underforbruk."
},
{
"id": "q-021",
"category": "baerekraft",
"week": 11,
"question": "Hva er hovedforskjellen på sirkulær og lineær økonomi?",
"options": [
"Sirkulær økonomi er digital, lineær er fysisk",
"Lineær følger Take-Make-Use-Waste, sirkulær fokuserer på gjenbruk, reparasjon og resirkulering for å minimere avfall",
"Sirkulær økonomi gjelder kun små bedrifter, lineær gjelder store",
"Sirkulær økonomi er kun et teoretisk konsept uten praktisk anvendelse"
],
"correct": 1,
"explanation": "Lineær økonomi følger Take-Make-Use-Waste og gir mye avfall. Sirkulær økonomi søker å minimere skade ved å resirkulere, gjenbruke, reparere og regenerere produkter/materialer for å redusere avfall og ressursbruk."
},
{
"id": "q-022",
"category": "baerekraft",
"week": 11,
"question": "Hvem regnes som 'faren' til mikrofinansiering og grunnla Grameen Bank?",
"options": [
"Milton Friedman",
"Adam Smith",
"Mohammad Yunus",
"Howard Bowen"
],
"correct": 2,
"explanation": "Mohammad Yunus grunnla Grameen Bank i Bangladesh i 1976 og fikk Nobels fredspris. Mikrofinansiering gir små lån, spareordninger og finansielle tjenester til mennesker (særlig kvinner) som ikke har tilgang til tradisjonelle banker."
},
{
"id": "q-023",
"category": "baerekraft",
"week": 16,
"question": "Hva kjennetegner 'motvekst' (degrowth) som bevegelse?",
"options": [
"Den krever at all økonomisk aktivitet stanses",
"Den utfordrer ideen om uendelig økonomisk vekst og prioriterer bærekraft og livskvalitet over BNP-vekst",
"Den ønsker å øke BNP-veksten til 5 % per år",
"Den fokuserer kun på lokal handel uten internasjonalt perspektiv"
],
"correct": 1,
"explanation": "Motvekst (degrowth) utfordrer ideen om uendelig vekst og argumenterer for at vekst kan styres mot bærekraft og livskvalitet. Fire pilarer: ressursbevissthet, rettferdighet, lokalisering og livskvalitet. Limits to Growth (1972) var en sentral inspirasjon."
},
{
"id": "q-024",
"category": "baerekraft",
"week": 16,
"question": "Hvem argumenterer for at 'grønn vekst' ikke er mulig fordi vi bare ser relativ ikke absolutt frikobling?",
"options": [
"Milton Friedman",
"Jason Hickel",
"Michael Porter",
"Joel Bakan"
],
"correct": 1,
"explanation": "Jason Hickel, kjent fra boken 'Less is More: How Degrowth Will Save the World', kritiserer grønn vekst. Han mener at absolutt frikobling (utslipp ned mens BNP vokser) ikke er realistisk kun relativ frikobling (utslipp øker mindre enn BNP) observeres."
},
{
"id": "q-025",
"category": "baerekraft",
"week": 7,
"question": "Hvilken modell viser at økonomien er innebygget i samfunnet, som igjen er innebygget i biosfæren?",
"options": [
"Carrolls pyramide",
"Triple Bottom Line",
"SDG-bryllupskaken (Stockholm Resilience Centre)",
"Mitchells modell"
],
"correct": 2,
"explanation": "SDG-bryllupskaken (Stockholm Resilience Centre) viser SDGene i tre lag: Biosphere (SDG 6, 13, 14, 15) som grunnlag, Society over (SDG 1-5, 7, 11, 16) og Economy øverst (SDG 8, 9, 10, 12). SDG 17 binder alt sammen. Økonomien er innebygget i samfunnet og biosfæren."
},
{
"id": "q-026",
"category": "samfunn",
"week": 8,
"question": "Hvilket nivå utgjør grunnlaget i Carrolls CSR-pyramide (1991)?",
"options": [
"Juridisk ansvar",
"Etisk ansvar",
"Økonomisk ansvar",
"Filantropisk ansvar"
],
"correct": 2,
"explanation": "I Carrolls CSR-pyramide (1991) er økonomisk ansvar grunnlaget 'Vær lønnsom'. Pyramiden bygges nedenfra: Økonomisk → Juridisk → Etisk → Filantropisk. Bedriften må være lønnsom for å eksistere og kunne oppfylle de andre ansvarsformene."
},
{
"id": "q-027",
"category": "samfunn",
"week": 8,
"question": "Hvilket av disse er det øverste nivået i Carrolls pyramide?",
"options": [
"Økonomisk ansvar (vær lønnsom)",
"Filantropisk/frivillig ansvar (vær en god bedriftsborger)",
"Etisk ansvar (vær etisk)",
"Juridisk ansvar (adlyd loven)"
],
"correct": 1,
"explanation": "Filantropisk/frivillig ansvar er øverst i Carrolls pyramide 'Vær en god bedriftsborger'. Det handler om å yte ressurser til samfunnet og forbedre livskvalitet (gaver, støtte til lokalmiljø). Den er frivillig, ikke obligatorisk."
},
{
"id": "q-028",
"category": "samfunn",
"week": 6,
"question": "Hvilken teoretiker står bak utsagnet 'The business of business is business'?",
"options": [
"R. Edward Freeman",
"Milton Friedman",
"Howard Bowen",
"Adam Smith"
],
"correct": 1,
"explanation": "Milton Friedman (1912-2006), Nobelprisvinner og sentral i Chicago-skolen, formulerte i 1970 at bedriftens eneste samfunnsansvar er å maksimere profitt for aksjonærene innenfor lovens rammer. Han står for shareholder-modellen."
},
{
"id": "q-029",
"category": "samfunn",
"week": 6,
"question": "Hvem regnes som 'faren' til stakeholder-teorien?",
"options": [
"Milton Friedman",
"Howard Bowen",
"R. Edward Freeman",
"Archie Carroll"
],
"correct": 2,
"explanation": "R. Edward Freeman (f. 1951), amerikansk professor i forretningsetikk, regnes som faren til stakeholder-teorien. Hans bok 'Strategic Management: A Stakeholder Approach' (1984) argumenterte for at bedrifter har ansvar overfor alle interessenter, ikke bare aksjonærene."
},
{
"id": "q-030",
"category": "samfunn",
"week": 6,
"question": "Hvor mange dimensjoner har Mitchells modell for interessentkartlegging?",
"options": [
"To",
"Tre",
"Fire",
"Fem"
],
"correct": 1,
"explanation": "Mitchells modell (Mitchell, Agle & Wood 1997) bruker tre dimensjoner: Makt (power), Legitimitet (legitimacy) og Hastverk (urgency). Kombinasjonene gir 7 kategorier av interessenter."
},
{
"id": "q-031",
"category": "samfunn",
"week": 6,
"question": "Hva kalles en interessent som har alle tre dimensjoner (makt, legitimitet og hastverk) i Mitchells modell?",
"options": [
"Dominerende",
"Farlig",
"Avgjørende (definitive)",
"Sovende"
],
"correct": 2,
"explanation": "Avgjørende (definitive) interessenter har alle tre dimensjoner makt, legitimitet og hastverk og må prioriteres høyest. Andre kombinasjoner: dominerende (makt+legitimitet), avhengig (legitimitet+hastverk), farlig (makt+hastverk)."
},
{
"id": "q-032",
"category": "samfunn",
"week": 6,
"question": "Hvilke tre søyler beskriver Richard W. Scotts institusjonelle teori?",
"options": [
"Økonomisk, sosial, miljømessig",
"Regulativ, normativ, kulturell-kognitiv",
"Strukturell, politisk, kulturell",
"Juridisk, etisk, økonomisk"
],
"correct": 1,
"explanation": "Richard W. Scotts tre søyler er: Regulativ (lover/regler 'hva er lovlig?'), Normativ (normer/verdier 'hva er rett og rettferdig?'), og Kulturell-kognitiv (delte forståelser 'hva er fornuftig?' / 'slik gjør vi det her')."
},
{
"id": "q-033",
"category": "samfunn",
"week": 6,
"question": "Hva betyr 'isomorfisme' i institusjonell teori?",
"options": [
"At organisasjoner blir mer ulike hverandre over tid",
"Prosessen der organisasjoner blir mer like hverandre over tid som resultat av press fra institusjonene",
"At organisasjoner blir mer transparente",
"At organisasjoner skifter sektor"
],
"correct": 1,
"explanation": "Isomorfisme er prosessen der organisasjoner blir mer like hverandre over tid som et resultat av press fra institusjonene. Organisasjoner søker legitimitet, og dette presset mot konformitet gjør dem like i form/struktur."
},
{
"id": "q-034",
"category": "samfunn",
"week": 8,
"question": "Hva er en negativ eksternalitet?",
"options": [
"Et internt etisk dilemma i en bedrift",
"Kostnader som påvirker tredjeparter uten å reflekteres i markedsprisen",
"Et tap som rammer aksjonærene",
"En frivillig CSR-handling utenfor kjernevirksomheten"
],
"correct": 1,
"explanation": "En negativ eksternalitet oppstår når en økonomisk aktivitet påfører kostnader på andre uten at disse reflekteres i markedsprisen. Klassisk eksempel: en fabrikk forurenser en elv fiskerne lider, men kostnaden fanges ikke opp i produsentens pris."
},
{
"id": "q-035",
"category": "samfunn",
"week": 8,
"question": "Hvem introduserte begrepet 'Creating Shared Value' (CSV) i 2006/2011?",
"options": [
"Friedman & Bowen",
"Mitchell & Wood",
"Porter & Kramer",
"Carroll & Buchholtz"
],
"correct": 2,
"explanation": "Michael Porter og Mark Kramer introduserte 'Creating Shared Value' (CSV) i 2006/2011. CSV er en forretningsstrategi der bedrifter skaper økonomisk verdi samtidig som de løser samfunnsmessige utfordringer integrert i kjernevirksomheten."
},
{
"id": "q-036",
"category": "samfunn",
"week": 8,
"question": "Hva er hovedforskjellen mellom CSR og CSV?",
"options": [
"CSR er global, CSV er lokal",
"CSR gir tilbake ved siden av kjernevirksomheten, CSV integrerer samfunnsforbedring direkte i forretningsstrategien",
"CSR er ulovlig, CSV er lovlig",
"CSR gjelder ansatte, CSV gjelder kunder"
],
"correct": 1,
"explanation": "CSR er ofte drevet av eksternt press og handler om å gi tilbake til samfunnet ved siden av kjernevirksomheten. CSV (Porter & Kramer) er en integrert del av bedriftens strategi som kobler samfunnsforbedring direkte til økonomisk verdiskaping."
},
{
"id": "q-037",
"category": "samfunn",
"week": 8,
"question": "Hvem regnes som 'CSR-feltets far' med boken Social Responsibilities of the Businessman (1953)?",
"options": [
"Milton Friedman",
"Howard R. Bowen",
"Joel Bakan",
"John Elkington"
],
"correct": 1,
"explanation": "Howard R. Bowen er kjent som 'CSR-feltets far' for boken 'Social Responsibilities of the Businessman' (1953). Han introduserte CSR som et normativt begrep: bedrifter har moralsk ansvar utover profitt."
},
{
"id": "q-038",
"category": "samfunn",
"week": 8,
"question": "Hvem skrev boken 'The Corporation' (2004) og argumenterer for at bedrifter er 'institusjonalisert psykopati'?",
"options": [
"Naomi Klein",
"Joel Bakan",
"Milton Friedman",
"Adam Smith"
],
"correct": 1,
"explanation": "Joel Bakan argumenterer i 'The Corporation' (2004) at bedrifter fungerer som institusjonalisert psykopati pga. juridisk struktur og målet om profittmaksimering. Løsningen er demokratisk styring og myndigheters tilsyn."
},
{
"id": "q-040",
"category": "samfunn",
"week": 10,
"question": "Hva er 'Cause-Related Marketing' (CRM)?",
"options": [
"Et lovkrav om å donere 10 % av overskudd til samfunnet",
"En markedsføringsstrategi der bedriften donerer en del av inntektene eller produktene til et godt formål per kjøp",
"En investeringsstrategi der man unngår uetiske selskaper",
"Et obligatorisk rapporteringsrammeverk"
],
"correct": 1,
"explanation": "Cause-Related Marketing er en markedsføringsstrategi der bedriften samarbeider med veldedig organisasjon og donerer del av inntekter/produkter per kjøp. Klassisk eksempel: American Express donerte 1 cent per kortbruk til Frihetsgudinnen-restaureringen (1983)."
},
{
"id": "q-041",
"category": "samfunn",
"week": 10,
"question": "Den interne sosiale søyle inneholder tre nivåer. Hvilke?",
"options": [
"Strategisk, taktisk, operativ",
"Obligatorisk (lovpålagt), avtalt (kollektivt/tariff), frivillig (CSR)",
"Filantropisk, sponsing, CRM",
"Mikro, meso, makro"
],
"correct": 1,
"explanation": "Den interne sosiale søylen deles i tre nivåer: 1) Obligatorisk sosialpolitikk (lovpålagt arbeidsmiljøloven m.m.), 2) Avtalt sosialpolitikk (kollektive avtaler/fagforeninger), 3) Frivillig sosialpolitikk (CSR-tiltak). Kun det frivillige nivået er strengt sett CSR."
},
{
"id": "q-042",
"category": "verktoy",
"week": 12,
"question": "Hva står CSRD for?",
"options": [
"Corporate Social Responsibility Directive",
"Corporate Sustainability Reporting Directive",
"Corporate Standardized Reporting Document",
"Climate Sustainability Reporting Directive"
],
"correct": 1,
"explanation": "CSRD står for Corporate Sustainability Reporting Directive et EU-direktiv som erstatter NFRD og krever omfattende ESG-rapportering med dobbel materialitet og lovpålagt attestasjon."
},
{
"id": "q-043",
"category": "verktoy",
"week": 12,
"question": "Hva betyr 'dobbel vesentlighet' (dobbel materialitet) i CSRD?",
"options": [
"At rapporteringen skal gjøres på to språk",
"Å vurdere både hvordan virksomheten påvirker omgivelsene (impact materiality) OG hvordan eksterne bærekraftsforhold påvirker virksomhetens økonomi (financial materiality)",
"At alle data må rapporteres to ganger for kvalitetssikring",
"At rapporten må gjelde både morselskap og datterselskaper"
],
"correct": 1,
"explanation": "Dobbel vesentlighet i CSRD krever vurdering av: 1) Påvirkningsvesentlighet hvordan virksomheten påvirker miljø/samfunn, og 2) Finansiell vesentlighet hvordan bærekraftsforhold påvirker virksomhetens økonomi. Begge perspektiver må analyseres."
},
{
"id": "q-044",
"category": "verktoy",
"week": 12,
"question": "Hva står GRI for?",
"options": [
"Global Risk Indicator",
"Green Reporting Index",
"Global Reporting Initiative",
"Governance Regulation Institute"
],
"correct": 2,
"explanation": "GRI står for Global Reporting Initiative den mest brukte globale standarden for bærekraftsrapportering, brukt av over 10 000 virksomheter globalt. Anses som det internasjonale 'felles språket' for bærekraftsrapportering."
},
{
"id": "q-045",
"category": "verktoy",
"week": 12,
"question": "Hvilken ISO-standard er knyttet til samfunnsansvar (people-pilaren) og er KUN veiledende (ikke sertifiserbar)?",
"options": [
"ISO 9001",
"ISO 14001",
"ISO 26000",
"ISO 45001"
],
"correct": 2,
"explanation": "ISO 26000 er standarden for samfunnsansvar (people-pilaren) og er kun veiledende ikke sertifiserbar. ISO 14001 (miljø/planet) og ISO 9001 (kvalitet/profit) er derimot sertifiserbare."
},
{
"id": "q-046",
"category": "verktoy",
"week": 12,
"question": "Når trådte den norske Åpenhetsloven i kraft?",
"options": [
"1. januar 2020",
"1. juli 2022",
"1. januar 2023",
"1. juli 2024"
],
"correct": 1,
"explanation": "Åpenhetsloven 'Lov om virksomheters åpenhet og arbeid med grunnleggende menneskerettigheter og anstendige arbeidsforhold' trådte i kraft 1. juli 2022. Den krever aktsomhetsvurderinger for ansvarlige arbeidsforhold internt og i leverandørkjeden."
},
{
"id": "q-047",
"category": "verktoy",
"week": 12,
"question": "Hva er hovedforskjellen mellom en reaktiv og en proaktiv tilnærming til bærekraft?",
"options": [
"Reaktiv er offentlig, proaktiv er privat",
"Reaktiv er defensiv (risikominimering, omdømmebeskyttelse), proaktiv integrerer bærekraft i kjernevirksomheten og strategien",
"Reaktiv er billigere, proaktiv er dyrere",
"Reaktiv er kortsiktig, proaktiv handler om filantropi"
],
"correct": 1,
"explanation": "Reaktiv tilnærming er defensiv fokus på risikominimering og omdømmebeskyttelse, etterkommer kun lovkrav. Proaktiv tilnærming integrerer bærekraft i bedriftens kultur og 'DNA' som strategisk mulighet, gir konkurransefortrinn og innovasjon."
},
{
"id": "q-048",
"category": "verktoy",
"week": 12,
"question": "Hva er hovedformålet med EUs Green Deal?",
"options": [
"Å innføre ny grønn merverdiavgift i EU",
"Å gjøre Europa klimanøytralt innen 2050 med vekst løsrevet fra ressursbruk og ingen utelatt",
"Å erstatte FN sine bærekraftsmål med europeiske mål",
"Å forby fossile energikilder umiddelbart"
],
"correct": 1,
"explanation": "EUs Green Deal har tre hovedmål: 1) Ingen netto utslipp av klimagasser innen 2050, 2) Økonomisk vekst løsrevet fra ressursbruk, 3) Ingen person eller sted utelatt. Virkemidler: EU-taksonomi, CSDDD, CSRD og SFDR."
},
{
"id": "q-049",
"category": "verktoy",
"week": 16,
"question": "Hva er det andre steget i de fem implementeringsstegene for bærekraft (Kap. 11)?",
"options": [
"Verifikasjon",
"Interessentdialog",
"Rapportering",
"Oppfølging"
],
"correct": 1,
"explanation": "De fem implementeringsstegene er: 1) Planlegging, 2) Interessentdialog (Kap. 7 kartlegge interessenter og deres verdier), 3) Rapportering (Kap. 10 GRI/CSRD), 4) Verifikasjon (ISO 14001 m.m.), 5) Oppfølging (kontinuerlig forbedring)."
},
{
"id": "q-050",
"category": "verktoy",
"week": 12,
"question": "Hvilken norsk lovparagraf gir alle rett til 'et miljø som sikrer helsen, og til en natur der produksjonsevne og mangfold bevares'?",
"options": [
"Grunnloven § 112",
"Forurensningsloven § 1",
"Plan- og bygningsloven § 1.1",
"Naturmangfoldloven § 1"
],
"correct": 0,
"explanation": "Grunnloven § 112 gir enhver rett til et miljø som sikrer helsen, og til en natur der produksjonsevne og mangfold bevares. Naturens ressurser skal disponeres ut fra en langsiktig og allsidig betraktning som ivaretar denne rett også for etterslekten."
}
]

371
app/index.html Normal file
View File

@@ -0,0 +1,371 @@
<!DOCTYPE html>
<html lang="nb" data-theme="dark">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<meta name="description" content="Studie-app for SMF2290 — Etikk, bærekraft og samfunnsansvar">
<title>SMF2290 · Pensum</title>
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' rx='4' fill='%23E07B5F'/%3E%3Ctext x='16' y='22' text-anchor='middle' fill='%230F1218' font-family='serif' font-style='italic' font-size='18' font-weight='400'%3ES%3C/text%3E%3C/svg%3E">
<link rel="stylesheet" href="css/style.css">
<script src="vendor/marked.min.js"></script>
</head>
<body>
<!-- Mobile menu toggle -->
<button class="sidebar-toggle" id="sidebarToggle" aria-label="Vis meny">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></svg>
</button>
<div class="sidebar-scrim" id="sidebarScrim"></div>
<div class="app" id="app">
<!-- Sidebar -->
<aside class="sidebar" id="sidebar">
<a href="#" class="sidebar__brand" data-route="home">
<span class="sidebar__brand-code">SMF · 2290</span>
<span class="sidebar__brand-name">Pensum</span>
</a>
<div class="sidebar__section">
<div class="sidebar__label">Studie</div>
<nav class="sidebar__nav">
<a href="#" data-route="home" class="sidebar__link">
<span class="sidebar__link-num">00</span>
<span>Oversikt</span>
</a>
<a href="#/tldr" data-route="tldr" class="sidebar__link sidebar__link--tldr">
<span class="sidebar__link-num">!</span>
<span>tl;dr — i farta</span>
</a>
<a href="#/flashcards" data-route="flashcards" class="sidebar__link">
<span class="sidebar__link-num">FC</span>
<span>Flashcards</span>
</a>
<a href="#/quiz" data-route="quiz" class="sidebar__link">
<span class="sidebar__link-num">QZ</span>
<span>Selvtest</span>
</a>
<a href="#/eksamen" data-route="eksamen" class="sidebar__link">
<span class="sidebar__link-num">EX</span>
<span>Eksamenstrener</span>
</a>
</nav>
</div>
<div class="sidebar__section">
<div class="sidebar__label">Uker</div>
<nav class="sidebar__nav" id="weekNav">
<!-- populated by JS -->
</nav>
</div>
<div class="sidebar__exam">
<div class="sidebar__exam-label">Eksamen om</div>
<div class="sidebar__exam-countdown" id="examCountdown"></div>
<div class="sidebar__exam-detail">01.06.2026 · 09:00 · 4t · Inspera</div>
</div>
</aside>
<!-- Main canvas -->
<main class="canvas">
<!-- Top bar -->
<div class="topbar">
<div class="topbar__crumbs" id="crumbs">
<strong>SMF2290</strong>
<span>/</span>
<span id="crumbCurrent">Oversikt</span>
</div>
<div class="search">
<svg class="search__icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
<input type="text" class="search__input" id="searchInput" placeholder="Søk i pensum — begreper, teorier …" autocomplete="off">
<kbd class="search__kbd">/</kbd>
<div class="search-results" id="searchResults"></div>
</div>
<div class="topbar__actions">
<button class="icon-btn" id="themeBtn" aria-label="Bytt tema" title="Bytt tema">
<svg id="themeIcon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
</svg>
</button>
</div>
</div>
<!-- View container -->
<div id="view" class="view"></div>
</main>
</div>
<!-- Templates -->
<template id="t-home">
<div class="page">
<section class="hero reveal">
<div>
<div class="hero__meta">
<span><strong>SMF2290</strong> · Vår 2026</span>
<span>NTNU</span>
<span>Martina Ortová</span>
</div>
<h1 class="hero__title">Etikk, bærekraft<br>& <em>samfunnsansvar</em></h1>
<div class="hero__quote">Det viktigste er ikke å kunne alle teorier og prinsipper, men å utvikle etisk bevissthet og evne til refleksjon.</div>
<div class="hero__attribution">— Martina Ortová, Uke 17</div>
</div>
</section>
<div class="exam-strip reveal">
<div class="exam-cell">
<span class="exam-cell__label">Dato</span>
<span class="exam-cell__value">Mandag 01.06.26</span>
</div>
<div class="exam-cell">
<span class="exam-cell__label">Tid</span>
<span class="exam-cell__value">09:00 · 4 timer</span>
</div>
<div class="exam-cell">
<span class="exam-cell__label">System</span>
<span class="exam-cell__value">Inspera</span>
</div>
<div class="exam-cell">
<span class="exam-cell__label">Sted</span>
<span class="exam-cell__value">Campus Gjøvik</span>
</div>
<div class="exam-cell">
<span class="exam-cell__label">Hjelpemiddel</span>
<span class="exam-cell__value">Kode E</span>
</div>
<div class="exam-cell">
<span class="exam-cell__label">Vekting</span>
<span class="exam-cell__value">100/100</span>
</div>
</div>
<section class="themes">
<div class="themes__head reveal">
<h2 class="themes__title">Fire domener · <em class="serif">eksamen i fire deler</em></h2>
<span class="themes__count">25 % hver</span>
</div>
<div class="themes__grid">
<a href="#/tema/etikk" class="theme-card theme-card--etikk reveal" data-route="tema-etikk">
<span class="theme-card__num">01</span>
<div class="theme-card__eyebrow">Oppgave I</div>
<h3 class="theme-card__title"><em>Etikk</em></h3>
<p class="theme-card__summary">Pliktetikk, konsekvensetikk og dydsetikk. De seks etiske prinsippene, Kvalnes-hjulet, og bedrifters etiske dilemmaer.</p>
<div class="theme-card__list">
<span class="theme-card__chip">Kant</span>
<span class="theme-card__chip">Mill</span>
<span class="theme-card__chip">Aristoteles</span>
<span class="theme-card__chip">Kvalnes</span>
<span class="theme-card__chip">6 prinsipper</span>
</div>
<div class="theme-card__foot">
<span>Uke 3 · 4 · 5 · 17</span>
<span class="theme-card__arrow">Les →</span>
</div>
</a>
<a href="#/tema/baerekraft" class="theme-card theme-card--baerekraft reveal" data-route="tema-baerekraft">
<span class="theme-card__num">02</span>
<div class="theme-card__eyebrow">Oppgave II</div>
<h3 class="theme-card__title"><em>Bærekraft</em></h3>
<p class="theme-card__summary">Triple Bottom Line, sirkulær økonomi, planetens tålegrenser og motvekst. Brundtland-arven og SDG.</p>
<div class="theme-card__list">
<span class="theme-card__chip">TBL</span>
<span class="theme-card__chip">Sirkulær</span>
<span class="theme-card__chip">SDG</span>
<span class="theme-card__chip">Smultringen</span>
<span class="theme-card__chip">Degrowth</span>
</div>
<div class="theme-card__foot">
<span>Uke 2 · 11 · 16</span>
<span class="theme-card__arrow">Les →</span>
</div>
</a>
<a href="#/tema/samfunn" class="theme-card theme-card--samfunn reveal" data-route="tema-samfunn">
<span class="theme-card__num">03</span>
<div class="theme-card__eyebrow">Oppgave III</div>
<h3 class="theme-card__title">Samfunns<em>ansvar</em></h3>
<p class="theme-card__summary">CSR vs CSV, Carrolls pyramide, stakeholder-teori og institusjonell teori. Eksternaliteter og sosial pilar.</p>
<div class="theme-card__list">
<span class="theme-card__chip">CSR</span>
<span class="theme-card__chip">CSV</span>
<span class="theme-card__chip">Carroll</span>
<span class="theme-card__chip">Mitchell</span>
<span class="theme-card__chip">Friedman</span>
</div>
<div class="theme-card__foot">
<span>Uke 6 · 7 · 8 · 10</span>
<span class="theme-card__arrow">Les →</span>
</div>
</a>
<a href="#/tema/verktoy" class="theme-card theme-card--verktoy reveal" data-route="tema-verktoy">
<span class="theme-card__num">04</span>
<div class="theme-card__eyebrow">Oppgave IV · Case</div>
<h3 class="theme-card__title"><em>Verktøy</em> & implementering</h3>
<p class="theme-card__summary">Etiske kodekser, CSRD, GRI, ISO, Green Deal. Implementeringssteg og verktøykasse for case-drøftingen.</p>
<div class="theme-card__list">
<span class="theme-card__chip">CSRD</span>
<span class="theme-card__chip">GRI</span>
<span class="theme-card__chip">ISO 26000</span>
<span class="theme-card__chip">Green Deal</span>
<span class="theme-card__chip">5 steg</span>
</div>
<div class="theme-card__foot">
<span>Uke 12 · 16</span>
<span class="theme-card__arrow">Les →</span>
</div>
</a>
</div>
</section>
<section class="tldr-promo reveal">
<a href="#/tldr" class="tldr-promo__card" data-route="tldr">
<div class="tldr-promo__icon">!</div>
<div class="tldr-promo__body">
<div class="tldr-promo__label">tl;dr — i farta</div>
<div class="tldr-promo__title">Eksamen <em>i morgen?</em> Dette må du kunne.</div>
<div class="tldr-promo__desc">Det aller viktigste destillert til én side. Definisjoner, navn, formler. Bruk på bussen, i køen, eller når det panikker.</div>
</div>
<div class="tldr-promo__arrow"></div>
</a>
</section>
<section class="modes">
<div class="themes__head reveal" style="margin-bottom: var(--sp-7)">
<h2 class="themes__title">Studiemodus · <em class="serif">tren før eksamen</em></h2>
</div>
<div class="modes__grid">
<a href="#/flashcards" class="mode-card reveal" data-route="flashcards">
<span class="mode-card__label">Flashcards</span>
<span class="mode-card__title">Pugg <em>begreper</em></span>
<span class="mode-card__desc">Spaced-repetition over alle definisjoner, modeller og navn fra pensum. Klikk for å snu kortet.</span>
<span class="mode-card__cta">Start</span>
</a>
<a href="#/quiz" class="mode-card reveal" data-route="quiz">
<span class="mode-card__label">Selvtest</span>
<span class="mode-card__title"><em>Sjekk</em> kunnskapen</span>
<span class="mode-card__desc">Flervalg, kort fasitsvar, og forklaringer. Test deg innenfor hvert tema eller hele pensum.</span>
<span class="mode-card__cta">Start</span>
</a>
<a href="#/eksamen" class="mode-card reveal" data-route="eksamen">
<span class="mode-card__label">Eksamenstrener</span>
<span class="mode-card__title">Skriv <em>som på</em> Inspera</span>
<span class="mode-card__desc">Tidligere eksempelspørsmål med veiledede svar og sjekkliste for hva som forventes.</span>
<span class="mode-card__cta">Start</span>
</a>
</div>
</section>
</div>
</template>
<template id="t-lesson">
<div class="page">
<header class="lesson-header reveal">
<div class="lesson-header__num" id="lessonNum">Uke 00</div>
<h1 class="lesson-header__title" id="lessonTitle"></h1>
<div class="lesson-header__meta" id="lessonMeta"></div>
</header>
<article class="lesson" id="lessonBody">
<div class="is-loading" style="height: 400px;"></div>
</article>
<nav class="lesson-pager" id="lessonPager"></nav>
</div>
</template>
<template id="t-flashcards">
<div class="page">
<header class="lesson-header reveal" style="text-align:center; border:none; padding-bottom:var(--sp-5)">
<div class="lesson-header__num">Studiemodus</div>
<h1 class="lesson-header__title"><em>Flashcards</em></h1>
<div class="lesson-header__meta" style="justify-content:center"><span>Klikk på kortet for å snu · piltaster for navigering</span></div>
</header>
<div class="fc-filters reveal" id="fcFilters"></div>
<div class="fc-stage">
<div class="fc-meta reveal">
<span><strong id="fcCurrent">1</strong> / <span id="fcTotal">0</span></span>
<span class="fc-meta__sep">·</span>
<span id="fcCategory"></span>
<span class="fc-meta__sep">·</span>
<span><strong id="fcKnown">0</strong> mestret</span>
</div>
<div class="fc-card reveal" id="fcCard">
<div class="fc-face fc-face--front">
<span class="fc-face__type" id="fcFrontType">SPØRSMÅL</span>
<div class="fc-face__front-text" id="fcFront">Trykk for å starte</div>
<div class="fc-face__hint"><span>klikk for å snu</span><span>SPACE</span></div>
</div>
<div class="fc-face fc-face--back">
<span class="fc-face__type" id="fcBackType">SVAR</span>
<div class="fc-face__back-text" id="fcBack"></div>
<div class="fc-face__hint"><span>vurder hvor godt du husker</span></div>
</div>
</div>
<div class="fc-controls reveal">
<button class="fc-btn" id="fcPrev">← Forrige</button>
<button class="fc-btn fc-btn--hard" id="fcHard">Glemt</button>
<button class="fc-btn fc-btn--good" id="fcGood">Ok</button>
<button class="fc-btn fc-btn--easy" id="fcEasy">Kunne</button>
<button class="fc-btn" id="fcNext">Neste →</button>
</div>
</div>
</div>
</template>
<template id="t-quiz">
<div class="page">
<div class="quiz-stage" id="quizStage"></div>
</div>
</template>
<template id="t-eksamen">
<div class="page">
<header class="lesson-header reveal">
<div class="lesson-header__num">Eksamenstrener</div>
<h1 class="lesson-header__title"><em>Tidligere</em> eksempelspørsmål</h1>
<div class="lesson-header__meta">
<span>Drøftingsspørsmål</span>
<span>Veiledede svar</span>
<span>Case-oppgaver</span>
</div>
</header>
<div id="examQuestions"></div>
</div>
</template>
<template id="t-tema">
<div class="page">
<header class="lesson-header reveal" id="temaHeader"></header>
<article class="lesson" id="temaBody"></article>
</div>
</template>
<template id="t-tldr">
<div class="page page--narrow tldr-page">
<header class="tldr-hero reveal">
<div class="tldr-hero__stamp">!</div>
<div class="tldr-hero__num">tl;dr</div>
<h1 class="tldr-hero__title">Eksamen <em>i morgen?</em><br>Dette må du kunne.</h1>
<div class="tldr-hero__sub">Det aller viktigste destillert til ett dokument. Skroll, scan, gå.</div>
</header>
<article class="lesson tldr-body" id="tldrBody">
<div class="is-loading" style="height: 400px;"></div>
</article>
</div>
</template>
<script src="js/data.js"></script>
<script src="js/render.js"></script>
<script src="js/search.js"></script>
<script src="js/flashcards.js"></script>
<script src="js/quiz.js"></script>
<script src="js/eksamen.js"></script>
<script src="js/app.js"></script>
</body>
</html>

179
app/js/app.js Normal file
View File

@@ -0,0 +1,179 @@
// =====================================================
// App — router, sidebar, theme toggle
// =====================================================
const view = document.getElementById('view');
const crumbCurrent = document.getElementById('crumbCurrent');
function parseRoute() {
const hash = location.hash.replace(/^#\/?/, '');
if (!hash || hash === '/') return { name: 'home' };
const parts = hash.split('/').filter(Boolean);
if (parts[0] === 'uke' && parts[1]) return { name: 'uke', weekId: parseInt(parts[1], 10) };
if (parts[0] === 'tema' && parts[1]) return { name: 'tema', temaId: parts[1] };
if (parts[0] === 'tldr') return { name: 'tldr' };
if (parts[0] === 'flashcards') return { name: 'flashcards' };
if (parts[0] === 'quiz') return { name: 'quiz' };
if (parts[0] === 'eksamen') return { name: 'eksamen' };
return { name: 'home' };
}
async function route() {
const r = parseRoute();
view.innerHTML = '';
let content;
let crumb = 'Oversikt';
switch (r.name) {
case 'home':
content = SMF.renderHome();
crumb = 'Oversikt';
break;
case 'uke':
content = await SMF.renderLesson(r.weekId);
const w = SMF.WEEKS.find(x => x.id === r.weekId);
crumb = w ? `Uke ${w.id} · ${w.title}` : 'Ukjent uke';
break;
case 'tema':
content = await SMF.renderTema(r.temaId);
const t = SMF.getTheme(r.temaId);
crumb = t ? t.label : 'Tema';
break;
case 'tldr':
content = await SMF.renderTldr();
crumb = 'tl;dr · i farta';
break;
case 'flashcards':
content = document.getElementById('t-flashcards').content.cloneNode(true);
crumb = 'Flashcards';
break;
case 'quiz':
content = document.getElementById('t-quiz').content.cloneNode(true);
crumb = 'Selvtest';
break;
case 'eksamen':
content = document.getElementById('t-eksamen').content.cloneNode(true);
crumb = 'Eksamenstrener';
break;
}
view.appendChild(content);
crumbCurrent.textContent = crumb;
// After DOM is in place, init relevant mode
if (r.name === 'flashcards') await SMF.fcInit();
else if (r.name === 'quiz') await SMF.quizInit();
else if (r.name === 'eksamen') await SMF.examInit();
updateActiveLinks(r);
closeSidebar();
window.scrollTo(0, 0);
}
function updateActiveLinks(r) {
document.querySelectorAll('.sidebar__link').forEach(a => {
a.classList.remove('sidebar__link--active');
});
if (r.name === 'home') {
document.querySelector('.sidebar__link[data-route="home"]')?.classList.add('sidebar__link--active');
} else if (r.name === 'tldr') {
document.querySelector('.sidebar__link[data-route="tldr"]')?.classList.add('sidebar__link--active');
} else if (r.name === 'flashcards') {
document.querySelector('.sidebar__link[data-route="flashcards"]')?.classList.add('sidebar__link--active');
} else if (r.name === 'quiz') {
document.querySelector('.sidebar__link[data-route="quiz"]')?.classList.add('sidebar__link--active');
} else if (r.name === 'eksamen') {
document.querySelector('.sidebar__link[data-route="eksamen"]')?.classList.add('sidebar__link--active');
} else if (r.name === 'uke') {
document.querySelector(`.sidebar__link[data-week="${r.weekId}"]`)?.classList.add('sidebar__link--active');
} else if (r.name === 'tema') {
// No specific active link for tema (could be added)
}
}
function renderWeekNav() {
const nav = document.getElementById('weekNav');
if (!nav) return;
nav.innerHTML = SMF.WEEKS.map(w => {
return `
<a href="#/uke/${w.id}" data-week="${w.id}" class="sidebar__link">
<span class="sidebar__link-num">${String(w.id).padStart(2, '0')}</span>
<span>${w.title}</span>
</a>
`;
}).join('');
}
// ============= Sidebar (mobile) =============
function openSidebar() {
document.getElementById('sidebar').classList.add('sidebar--open');
document.getElementById('sidebarScrim').classList.add('sidebar-scrim--open');
}
function closeSidebar() {
document.getElementById('sidebar').classList.remove('sidebar--open');
document.getElementById('sidebarScrim').classList.remove('sidebar-scrim--open');
}
document.getElementById('sidebarToggle')?.addEventListener('click', () => {
if (document.getElementById('sidebar').classList.contains('sidebar--open')) closeSidebar();
else openSidebar();
});
document.getElementById('sidebarScrim')?.addEventListener('click', closeSidebar);
// ============= Theme toggle =============
function applyTheme(theme) {
document.documentElement.dataset.theme = theme;
localStorage.setItem('smf-theme', theme);
// Update icon
const icon = document.getElementById('themeIcon');
if (theme === 'dark') {
icon.innerHTML = `<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>`;
} else {
icon.innerHTML = `<circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/>`;
}
}
function initTheme() {
// dark default; only switch to light if explicitly saved
const saved = localStorage.getItem('smf-theme');
applyTheme(saved === 'light' ? 'light' : 'dark');
}
document.getElementById('themeBtn').addEventListener('click', () => {
const current = document.documentElement.dataset.theme;
applyTheme(current === 'dark' ? 'light' : 'dark');
});
// ============= Countdown =============
function updateCountdown() {
const el = document.getElementById('examCountdown');
if (!el) return;
const c = SMF.daysToExam();
el.textContent = c.label;
}
// ============= Init =============
async function init() {
initTheme();
renderWeekNav();
updateCountdown();
SMF.attachSearch();
// Sidebar brand link
document.querySelectorAll('[data-route="home"]').forEach(a => {
a.addEventListener('click', (e) => {
e.preventDefault();
location.hash = '';
});
});
// Initial route
await route();
// Build search index in background
setTimeout(() => SMF.buildSearchIndex().catch(console.warn), 500);
}
window.addEventListener('hashchange', route);
window.addEventListener('DOMContentLoaded', init);
if (document.readyState !== 'loading') init();

161
app/js/data.js Normal file
View File

@@ -0,0 +1,161 @@
// =====================================================
// Data — uker, temaer, og metadata
// =====================================================
const COURSE = {
code: 'SMF2290',
name: 'Etikk, bærekraft og samfunnsansvar',
semester: 'Vår 2026',
lecturer: 'Martina Ortová',
exam: {
date: '2026-06-01',
time: '09:00',
duration_hours: 4,
platform: 'Inspera Assessment',
location: 'Campus Gjøvik',
aids: 'Kode E'
}
};
const WEEKS = [
{ id: 2, title: 'Introduksjon', theme: 'baerekraft', file: 'uke02-03-04.md', section: '#uke-2--introduksjon' },
{ id: 3, title: 'Etikk 1', theme: 'etikk', file: 'uke02-03-04.md', section: '#uke-3--etikk-1-diskusjons-uke' },
{ id: 4, title: 'Etikk 2', theme: 'etikk', file: 'uke02-03-04.md', section: '#uke-4--etikk-2' },
{ id: 5, title: 'Etikk 3', theme: 'etikk', file: 'uke05-06.md', section: '#uke-5--etikk-3' },
{ id: 6, title: 'Institusjon & Stakeholder', theme: 'samfunn', file: 'uke05-06.md', section: '#uke-6--institusjon-og-stakeholder' },
{ id: 7, title: 'Stakeholder & Historisk linje', theme: 'samfunn', file: 'uke07-08.md', section: '#uke-7--stakeholder-historisk-linje-og-fn' },
{ id: 8, title: 'Carroll, CSR & CSV', theme: 'samfunn', file: 'uke07-08.md', section: '#uke-8--carrolls-pyramide-csr-vs-csv-og-eksternaliteter-kap-8' },
{ id: 10, title: 'Sosial pilar', theme: 'samfunn', file: 'uke10-11.md', section: '#uke-10--den-sosiale-delen-av-csr' },
{ id: 11, title: 'Sirkulær økonomi & ESG', theme: 'baerekraft', file: 'uke10-11.md', section: '#uke-11--planetens-talegrenser-sirkulær-økonomi-og-esg-investeringer' },
{ id: 12, title: 'Verktøykasse', theme: 'verktoy', file: 'uke12-16.md', section: '#uke-12--verktøykasse-for-etikk-samfunnsansvar-og-bærekraft' },
{ id: 16, title: 'Implementering', theme: 'verktoy', file: 'uke12-16.md', section: '#uke-16--implementering' },
{ id: 17, title: 'Eksamen & oppsummering', theme: 'all', file: 'uke17-eksamen.md', section: '' }
];
const THEMES = {
etikk: {
id: 'etikk',
label: 'Etikk',
title: 'Etikk',
eyebrow: 'Oppgave I',
color: 'var(--theme-etikk)',
weeks: [3, 4, 5],
intro: 'Etikk er systematisk refleksjon over hva som er rett og galt i omgang mellom mennesker — et fag du lærer gjennom studier og trening i å anvende prinsipper og begreper.',
keyConcepts: [
{ term: 'Moral vs Etikk', def: 'Moral = personlige/felles oppfatninger av rett og galt, læres i samhandling. Etikk = systematisk refleksjon over moral, læres som fag.' },
{ term: 'Normativ etikk', def: 'Hva man bør gjøre — søker normer og prinsipper. Inkluderer konsekvensetikk, pliktetikk og dydsetikk.' },
{ term: 'Deskriptiv etikk', def: 'Hva folk faktisk mener er rett og galt — beskrivelse av moralpraksis.' },
{ term: 'Etisk dilemma', def: 'Situasjon hvor du må velge mellom alternativer som alle har gode etiske argumenter for seg — ingen er åpenbart riktige.' },
{ term: 'De 6 etiske prinsipper', def: 'Likhet, Autonomi, Velgjørenhet, Ikke-skade, Rettferdighet, Føre-var.' },
{ term: 'Konsekvensetikk (Mill)', def: 'Handlinger bedømmes ut fra konsekvensene. Utilitarisme: mest mulig lykke for flest mulig.' },
{ term: 'Pliktetikk (Kant)', def: 'Handlinger bedømmes ut fra plikt og prinsipp, ikke konsekvenser. Det kategoriske imperativ.' },
{ term: 'Dydsetikk (Aristoteles)', def: 'Fokus på karakter og dyder. Hva slags person ønsker du å være? Den gylne middelvei.' },
{ term: 'Diskursetikk', def: 'Etikk gjennom dialog og argumentasjon mellom likeverdige parter — Habermas.' },
{ term: 'Kvalnes Navigasjonshjul', def: '6-perspektiv-verktøy for etisk beslutning: Juss, Identitet, Etikk, Økonomi, Omdømme, Moral.' }
]
},
baerekraft: {
id: 'baerekraft',
label: 'Bærekraft',
title: 'Bærekraft',
eyebrow: 'Oppgave II',
color: 'var(--theme-baerekraft)',
weeks: [2, 11, 16],
intro: 'Bærekraftig utvikling er utvikling som imøtekommer dagens behov uten å ødelegge mulighetene for at kommende generasjoner skal få dekket sine behov (Brundtland 1987).',
keyConcepts: [
{ term: 'Brundtland-definisjonen (1987)', def: '«Utvikling som tilfredsstiller dagens behov uten å ødelegge fremtidige generasjoners muligheter for å tilfredsstille sine behov.»' },
{ term: 'Triple Bottom Line (Elkington 1994)', def: 'People, Planet, Profit — bedrifter skal måles på sosiale, miljømessige og økonomiske resultater samtidig.' },
{ term: 'De tre pilarene', def: 'Sosial (mennesker), Miljø (planet), Økonomi (profit). Snitt = bærekraft.' },
{ term: 'Svak vs Sterk bærekraft', def: 'Svak: natur kan erstattes av kapital. Sterk: naturkapital er kritisk og kan ikke erstattes.' },
{ term: 'Planetens tålegrenser', def: 'Stockholm Resilience Centre 2009 — 9 grenser som regulerer planetens stabilitet. Flere er allerede overskredet.' },
{ term: 'Sirkulær økonomi', def: 'Lukket loop: råmaterialer → bærekraftig design → produksjon → distribusjon → bruk/gjenbruk → innsamling → resirkulering.' },
{ term: '10R-rammeverket (Kirchher)', def: 'Refuse, Rethink, Reduce, Reuse, Repair, Refurbish, Remanufacture, Repurpose, Recycle, Recover.' },
{ term: 'Smultringmodellen (Raworth 2017)', def: 'Sosialt fundament (innside) og økologisk tak (utside). Trygt og rettferdig rom mellom dem.' },
{ term: 'FN 17 bærekraftsmål (SDG)', def: 'Vedtatt 2015. 169 delmål. Felles globalt rammeverk for utvikling fram til 2030.' },
{ term: 'Motvekst (Degrowth)', def: 'Bevegelse som utfordrer uendelig økonomisk vekst. 4 pilarer: ressursbevissthet, rettferdighet, lokalisering, livskvalitet.' }
]
},
samfunn: {
id: 'samfunn',
label: 'Samfunnsansvar',
title: 'Samfunnsansvar',
eyebrow: 'Oppgave III',
color: 'var(--theme-samfunn)',
weeks: [6, 7, 8, 10],
intro: 'CSR — Corporate Social Responsibility — er det ansvaret selskaper påtar seg for miljø, samfunn og mennesker som påvirkes av virksomheten, utover det som er lovpålagt.',
keyConcepts: [
{ term: 'CSR (Corporate Social Responsibility)', def: 'Ansvar selskaper påtar seg for miljø, samfunn og mennesker — utover det lovpålagte.' },
{ term: 'CSV (Creating Shared Value)', def: 'Porter & Kramer 2006. Integrert i strategi — kobler samfunnsforbedring til økonomisk verdiskaping.' },
{ term: 'CSR vs CSV', def: 'CSR drives ofte eksternt og er "ved siden av" kjernevirksomheten. CSV er strategi som skaper felles verdi.' },
{ term: 'Carrolls pyramide (1991)', def: '4 nivåer nedenfra: Økonomisk (vær lønnsom), Juridisk (adlyd loven), Etisk (vær etisk), Filantropisk (vær god bedriftsborger).' },
{ term: 'Friedman (1970)', def: '"The social responsibility of business is to increase its profits." Bedriftens eneste ansvar er å maksimere aksjonærverdi innenfor lovens rammer.' },
{ term: 'Stakeholder-teori (Freeman 1984)', def: 'God ledelse balanserer hensynet til alle som påvirkes av eller påvirker virksomheten — ikke bare aksjonærer.' },
{ term: 'Mitchells modell (1997)', def: '3 attributter: Makt, Legitimitet, Hastverk. Gir 7 typer interessenter (avgjørende = alle 3).' },
{ term: 'Institusjonell teori', def: 'Forklarer hvorfor organisasjoner blir like — press fra lover, normer og kulturelle koder.' },
{ term: 'Isomorfisme', def: 'Prosessen der organisasjoner blir mer like hverandre over tid pga press fra institusjonene.' },
{ term: 'Eksternaliteter', def: 'Kostnader eller fordeler som påvirker tredjeparter — uten å fanges av markedstransaksjonene. Kan være positive eller negative.' },
{ term: 'Sosial søyle (intern/ekstern)', def: 'Intern: obligatorisk sosialpolitikk + avtalt + frivillig (CSR). Ekstern: filantropi, Cause Related Marketing.' }
]
},
verktoy: {
id: 'verktoy',
label: 'Verktøy & implementering',
title: 'Verktøy',
eyebrow: 'Oppgave IV · Case',
color: 'var(--theme-verktoy)',
weeks: [12, 16],
intro: 'For å gå fra teori til praksis trenger bedrifter konkrete verktøy: kodekser, standarder, rapportering, og en strukturert implementeringsprosess fra planlegging til oppfølging.',
keyConcepts: [
{ term: 'Obligatoriske vs frivillige verktøy', def: 'Obligatorisk: lover, regulering, rapporteringskrav (CSRD, Åpenhetsloven). Frivillig: ISO, GRI, miljømerker.' },
{ term: 'Code of Conduct', def: 'Etisk kodeks — interne retningslinjer for atferd. Eksempel: Telenors Code of Conduct.' },
{ term: 'ISO 26000', def: 'Internasjonal standard for samfunnsansvar. Veiledende, ikke sertifiserbar.' },
{ term: 'ISO 14001 / 9001', def: '14001: miljøledelse. 9001: kvalitetsledelse. Begge er sertifiserbare.' },
{ term: 'GRI (Global Reporting Initiative)', def: 'Globalt rammeverk for bærekraftsrapportering. Standardiserer hva og hvordan man rapporterer.' },
{ term: 'CSRD', def: 'EUs Corporate Sustainability Reporting Directive. Krav om bærekraftsrapportering fra 2024/2025/2026 avhengig av størrelse.' },
{ term: 'Dobbel vesentlighet', def: 'CSRD-prinsipp: rapporter både hvordan virksomheten påvirker omgivelsene (impact) og hvordan bærekraft påvirker virksomheten (financial).' },
{ term: 'Green Deal', def: 'EUs strategi for å gjøre Europa klimanøytralt innen 2050. Bred politikkpakke som CSRD og taksonomien er del av.' },
{ term: 'EUs taksonomi', def: 'Klassifiseringssystem for hvilke økonomiske aktiviteter som er miljømessig bærekraftige.' },
{ term: 'Åpenhetsloven (2022)', def: 'Norsk lov: virksomheter må gjennomføre aktsomhetsvurderinger og rapportere om menneskerettigheter og arbeidsforhold.' },
{ term: '5 implementeringssteg', def: 'Planlegging → Interessentdialog → Rapportering → Verifikasjon → Oppfølging.' },
{ term: 'SRI (Social Responsible Investments)', def: 'Investeringsstrategi som integrerer etiske, miljømessige og sosiale betraktninger. Mål: avkastning + samfunnsansvar.' }
]
}
};
// Mapping from theme to color name
const THEME_COLORS = {
etikk: { color: '#D89AA2', soft: '#4A2027', bg: '#2A1A1D' },
baerekraft: { color: '#9CC089', soft: '#2D4029', bg: '#1A2419' },
samfunn: { color: '#E6B777', soft: '#5A3D17', bg: '#2A2014' },
verktoy: { color: '#A2BDD9', soft: '#1F3149', bg: '#161E2A' },
all: { color: '#E07B5F', soft: '#5A2317', bg: '#2A1A14' }
};
function themeOf(weekId) {
const w = WEEKS.find(x => x.id === weekId);
return w ? w.theme : 'all';
}
function getTheme(id) {
return THEMES[id];
}
// Countdown
function daysToExam() {
const exam = new Date('2026-06-01T09:00:00');
const now = new Date();
const diffMs = exam - now;
if (diffMs <= 0) return { days: 0, hours: 0, label: 'I dag!' };
const days = Math.floor(diffMs / (1000 * 60 * 60 * 24));
const hours = Math.floor((diffMs / (1000 * 60 * 60)) % 24);
return { days, hours, label: days === 0 ? `${hours}t` : days === 1 ? '1 dag' : `${days} dager` };
}
window.SMF = window.SMF || {};
SMF.COURSE = COURSE;
SMF.WEEKS = WEEKS;
SMF.THEMES = THEMES;
SMF.THEME_COLORS = THEME_COLORS;
SMF.themeOf = themeOf;
SMF.getTheme = getTheme;
SMF.daysToExam = daysToExam;

125
app/js/eksamen.js Normal file
View File

@@ -0,0 +1,125 @@
// =====================================================
// Eksamenstrener — practice questions with guided answers
// =====================================================
let examData = null;
let examFilter = 'all';
async function examLoad() {
if (examData) return examData;
try {
const res = await fetch('data/exam.json');
if (!res.ok) throw new Error('Not ready');
examData = await res.json();
} catch (e) {
console.warn('Eksamen-data ikke klar ennå:', e.message);
examData = [];
}
return examData;
}
// Normalize category names — agents sometimes used "samfunnsansvar"
function normalizeCat(cat) {
if (cat === 'samfunnsansvar') return 'samfunn';
return cat;
}
function examFilteredQuestions() {
if (examFilter === 'all') return examData;
return examData.filter(q => normalizeCat(q.category) === examFilter);
}
function examCategoryLabel(cat) {
return {
etikk: 'Oppgave I · Etikk',
baerekraft: 'Oppgave II · Bærekraft',
samfunn: 'Oppgave III · Samfunnsansvar',
case: 'Oppgave IV · Case-drøfting'
}[normalizeCat(cat)] || cat;
}
function examCategoryColor(cat) {
return {
etikk: 'var(--theme-etikk)',
baerekraft: 'var(--theme-baerekraft)',
samfunn: 'var(--theme-samfunn)',
case: 'var(--theme-verktoy)'
}[normalizeCat(cat)] || 'var(--accent)';
}
function examRender() {
const container = document.getElementById('examQuestions');
if (!container) return;
// Filter chips at top
container.innerHTML = `
<div class="fc-filters reveal" id="examFilters" style="margin-bottom:var(--sp-7)">
<button class="fc-filter ${examFilter==='all'?'fc-filter--active':''}" data-filter="all">Alle</button>
<button class="fc-filter ${examFilter==='etikk'?'fc-filter--active':''}" data-filter="etikk">Etikk</button>
<button class="fc-filter ${examFilter==='baerekraft'?'fc-filter--active':''}" data-filter="baerekraft">Bærekraft</button>
<button class="fc-filter ${examFilter==='samfunn'?'fc-filter--active':''}" data-filter="samfunn">Samfunnsansvar</button>
<button class="fc-filter ${examFilter==='case'?'fc-filter--active':''}" data-filter="case">Case</button>
</div>
<div id="examList"></div>
`;
const list = document.getElementById('examList');
const questions = examFilteredQuestions();
let counter = 0;
questions.forEach(q => {
counter++;
const num = String(counter).padStart(2, '0');
const color = examCategoryColor(q.category);
const div = document.createElement('div');
div.className = 'exam-q reveal';
div.innerHTML = `
<div class="exam-q__head">
<div class="exam-q__num" style="color:${color}">${num}</div>
<div class="exam-q__head-info">
<span class="exam-q__category">${examCategoryLabel(q.category)}</span>
<span class="exam-q__weight">${q.title || ''}</span>
</div>
</div>
<p class="exam-q__sub">${q.question}</p>
${q.checklist ? `
<h4 style="margin-top:var(--sp-5); font-family:var(--f-mono); font-size:var(--s-0); letter-spacing:0.15em; text-transform:uppercase; color:var(--muted); font-weight:600">Hva må svaret inneholde</h4>
<ul style="margin-top:var(--sp-2); padding-left:var(--sp-5)">
${q.checklist.map(c => `<li>${c}</li>`).join('')}
</ul>
` : ''}
<button class="exam-q__toggle" data-toggle>Vis veiledet svar ↓</button>
<div class="exam-q__reveal" style="display:none" data-answer>
<div class="exam-q__reveal-label">Veiledet svar</div>
<div class="markdown-content">${SMF.renderMarkdown(q.guidedAnswer || '')}</div>
${q.tips ? `<div style="margin-top:var(--sp-4); padding-top:var(--sp-3); border-top:1px solid var(--line); font-family:var(--f-display); font-style:italic; font-size:var(--s-2); color:var(--ink-2)"><strong style="font-family:var(--f-mono); font-size:0.6875rem; letter-spacing:0.15em; text-transform:uppercase; color:var(--accent); font-weight:600; font-style:normal; display:block; margin-bottom:6px">Tips</strong>${q.tips}</div>` : ''}
</div>
`;
list.appendChild(div);
});
// Attach toggles
list.querySelectorAll('[data-toggle]').forEach(btn => {
btn.addEventListener('click', () => {
const reveal = btn.nextElementSibling;
const isOpen = reveal.style.display !== 'none';
reveal.style.display = isOpen ? 'none' : 'block';
btn.textContent = isOpen ? 'Vis veiledet svar ↓' : 'Skjul veiledet svar ↑';
});
});
// Attach filters
document.getElementById('examFilters').addEventListener('click', (e) => {
const f = e.target.closest('[data-filter]');
if (f) {
examFilter = f.dataset.filter;
examRender();
}
});
}
async function examInit() {
await examLoad();
examRender();
}
SMF.examInit = examInit;

196
app/js/flashcards.js Normal file
View File

@@ -0,0 +1,196 @@
// =====================================================
// Flashcards — flippable cards with category filter
// =====================================================
let fcData = null;
let fcState = {
filter: 'all',
index: 0,
flipped: false,
cards: [],
known: new Set(), // localStorage-backed
hard: new Set()
};
async function fcLoad() {
if (fcData) return fcData;
try {
const res = await fetch('data/flashcards.json');
fcData = await res.json();
} catch (e) {
console.error('Klarte ikke laste flashcards:', e);
fcData = [];
}
// Load saved state
try {
const saved = JSON.parse(localStorage.getItem('smf-fc-state') || '{}');
if (saved.known) fcState.known = new Set(saved.known);
if (saved.hard) fcState.hard = new Set(saved.hard);
} catch {}
return fcData;
}
function fcSaveState() {
localStorage.setItem('smf-fc-state', JSON.stringify({
known: [...fcState.known],
hard: [...fcState.hard]
}));
}
function fcFilterCards(filter) {
if (filter === 'all') return fcData;
if (filter === 'hard') return fcData.filter(c => fcState.hard.has(c.id));
if (filter === 'new') return fcData.filter(c => !fcState.known.has(c.id) && !fcState.hard.has(c.id));
return fcData.filter(c => c.category === filter);
}
function fcSetFilter(filter) {
fcState.filter = filter;
fcState.cards = fcFilterCards(filter);
// shuffle once when filter changes
fcShuffle(fcState.cards);
fcState.index = 0;
fcState.flipped = false;
fcRender();
}
function fcShuffle(arr) {
for (let i = arr.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[arr[i], arr[j]] = [arr[j], arr[i]];
}
}
function fcRender() {
const total = fcState.cards.length;
document.getElementById('fcCurrent').textContent = total > 0 ? (fcState.index + 1) : 0;
document.getElementById('fcTotal').textContent = total;
document.getElementById('fcKnown').textContent = fcState.known.size;
const card = document.getElementById('fcCard');
if (total === 0) {
document.getElementById('fcFront').textContent = 'Ingen kort i denne kategorien';
document.getElementById('fcBack').textContent = 'Prøv et annet filter';
document.getElementById('fcCategory').textContent = '—';
card.classList.remove('fc-card--flipped');
return;
}
const c = fcState.cards[fcState.index];
document.getElementById('fcFront').textContent = c.front;
document.getElementById('fcBack').innerHTML = c.back;
document.getElementById('fcCategory').textContent = (c.subcategory || categoryLabel(c.category));
card.classList.toggle('fc-card--flipped', fcState.flipped);
}
function categoryLabel(cat) {
return {
etikk: 'Etikk',
baerekraft: 'Bærekraft',
samfunn: 'Samfunnsansvar',
verktoy: 'Verktøy',
case: 'Case'
}[cat] || cat;
}
function fcRenderFilters() {
const container = document.getElementById('fcFilters');
if (!container) return;
const filters = [
{ id: 'all', label: 'Alle' },
{ id: 'new', label: 'Nye' },
{ id: 'hard', label: 'Glemt' },
{ id: 'etikk', label: 'Etikk' },
{ id: 'baerekraft', label: 'Bærekraft' },
{ id: 'samfunn', label: 'Samfunnsansvar' },
{ id: 'verktoy', label: 'Verktøy' },
{ id: 'case', label: 'Case' }
];
container.innerHTML = filters.map(f => {
const active = fcState.filter === f.id ? 'fc-filter--active' : '';
return `<button class="fc-filter ${active}" data-filter="${f.id}">${f.label}</button>`;
}).join('');
}
function fcNext() {
if (!fcState.cards.length) return;
fcState.flipped = false;
fcState.index = (fcState.index + 1) % fcState.cards.length;
fcRender();
}
function fcPrev() {
if (!fcState.cards.length) return;
fcState.flipped = false;
fcState.index = (fcState.index - 1 + fcState.cards.length) % fcState.cards.length;
fcRender();
}
function fcMark(level) {
if (!fcState.cards.length) return;
const c = fcState.cards[fcState.index];
if (level === 'hard') {
fcState.hard.add(c.id);
fcState.known.delete(c.id);
} else if (level === 'good') {
fcState.hard.delete(c.id);
} else if (level === 'easy') {
fcState.known.add(c.id);
fcState.hard.delete(c.id);
}
fcSaveState();
fcNext();
}
async function fcInit() {
await fcLoad();
fcState.cards = fcFilterCards(fcState.filter);
fcShuffle(fcState.cards);
fcState.index = 0;
fcState.flipped = false;
fcRenderFilters();
fcRender();
// Card click → flip
const card = document.getElementById('fcCard');
card.addEventListener('click', () => {
fcState.flipped = !fcState.flipped;
fcRender();
});
document.getElementById('fcNext').addEventListener('click', (e) => { e.stopPropagation(); fcNext(); });
document.getElementById('fcPrev').addEventListener('click', (e) => { e.stopPropagation(); fcPrev(); });
document.getElementById('fcHard').addEventListener('click', (e) => { e.stopPropagation(); fcMark('hard'); });
document.getElementById('fcGood').addEventListener('click', (e) => { e.stopPropagation(); fcMark('good'); });
document.getElementById('fcEasy').addEventListener('click', (e) => { e.stopPropagation(); fcMark('easy'); });
document.getElementById('fcFilters').addEventListener('click', (e) => {
const btn = e.target.closest('[data-filter]');
if (btn) {
fcSetFilter(btn.dataset.filter);
fcRenderFilters();
}
});
// Keyboard
const handler = (e) => {
if (location.hash !== '#/flashcards') {
document.removeEventListener('keydown', handler);
return;
}
const tag = document.activeElement?.tagName;
if (tag === 'INPUT' || tag === 'TEXTAREA') return;
if (e.key === ' ' || e.key === 'Enter') { e.preventDefault(); fcState.flipped = !fcState.flipped; fcRender(); }
else if (e.key === 'ArrowRight') { e.preventDefault(); fcNext(); }
else if (e.key === 'ArrowLeft') { e.preventDefault(); fcPrev(); }
else if (e.key === '1') { fcMark('hard'); }
else if (e.key === '2') { fcMark('good'); }
else if (e.key === '3') { fcMark('easy'); }
};
document.addEventListener('keydown', handler);
}
SMF.fcInit = fcInit;

225
app/js/quiz.js Normal file
View File

@@ -0,0 +1,225 @@
// =====================================================
// Quiz — multiple choice with explanations
// =====================================================
let quizData = null;
let quizState = {
filter: 'all',
questions: [],
current: 0,
selected: null,
answered: false,
correct: 0,
wrong: 0,
finished: false
};
async function quizLoad() {
if (quizData) return quizData;
try {
const res = await fetch('data/quiz.json');
quizData = await res.json();
} catch (e) {
console.error('Klarte ikke laste quiz:', e);
quizData = [];
}
return quizData;
}
function quizFilterQuestions(filter) {
if (filter === 'all') return [...quizData];
return quizData.filter(q => q.category === filter);
}
function quizShuffle(arr) {
for (let i = arr.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[arr[i], arr[j]] = [arr[j], arr[i]];
}
return arr;
}
function quizRenderStart() {
const stage = document.getElementById('quizStage');
const counts = {
all: quizData.length,
etikk: quizData.filter(q => q.category === 'etikk').length,
baerekraft: quizData.filter(q => q.category === 'baerekraft').length,
samfunn: quizData.filter(q => q.category === 'samfunn').length,
verktoy: quizData.filter(q => q.category === 'verktoy').length
};
stage.innerHTML = `
<header class="lesson-header reveal" style="text-align:center; border:none; padding-bottom:var(--sp-5)">
<div class="lesson-header__num">Studiemodus</div>
<h1 class="lesson-header__title"><em>Selvtest</em></h1>
<div class="lesson-header__meta" style="justify-content:center"><span>Velg kategori — flervalg med forklaringer</span></div>
</header>
<div class="themes__grid reveal" style="grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--sp-4); margin-top: var(--sp-7)">
<button class="theme-card" data-cat="all" style="--theme-color: var(--accent); --theme-color-bg: transparent; text-align: left">
<div class="theme-card__eyebrow">Mix</div>
<h3 class="theme-card__title">Alle spørsmål</h3>
<div class="theme-card__foot"><span>${counts.all} spørsmål</span><span class="theme-card__arrow">Start →</span></div>
</button>
<button class="theme-card theme-card--etikk" data-cat="etikk">
<div class="theme-card__eyebrow">I</div>
<h3 class="theme-card__title"><em>Etikk</em></h3>
<div class="theme-card__foot"><span>${counts.etikk} spørsmål</span><span class="theme-card__arrow">Start →</span></div>
</button>
<button class="theme-card theme-card--baerekraft" data-cat="baerekraft">
<div class="theme-card__eyebrow">II</div>
<h3 class="theme-card__title"><em>Bærekraft</em></h3>
<div class="theme-card__foot"><span>${counts.baerekraft} spørsmål</span><span class="theme-card__arrow">Start →</span></div>
</button>
<button class="theme-card theme-card--samfunn" data-cat="samfunn">
<div class="theme-card__eyebrow">III</div>
<h3 class="theme-card__title">Samfunns<em>ansvar</em></h3>
<div class="theme-card__foot"><span>${counts.samfunn} spørsmål</span><span class="theme-card__arrow">Start →</span></div>
</button>
<button class="theme-card theme-card--verktoy" data-cat="verktoy">
<div class="theme-card__eyebrow">IV</div>
<h3 class="theme-card__title"><em>Verktøy</em></h3>
<div class="theme-card__foot"><span>${counts.verktoy} spørsmål</span><span class="theme-card__arrow">Start →</span></div>
</button>
</div>
`;
stage.querySelectorAll('[data-cat]').forEach(btn => {
btn.addEventListener('click', () => {
quizStart(btn.dataset.cat);
});
});
}
function quizStart(category) {
quizState.filter = category;
quizState.questions = quizShuffle(quizFilterQuestions(category));
quizState.current = 0;
quizState.selected = null;
quizState.answered = false;
quizState.correct = 0;
quizState.wrong = 0;
quizState.finished = false;
quizRenderCurrent();
}
function quizRenderCurrent() {
const stage = document.getElementById('quizStage');
if (quizState.finished) return quizRenderResult();
const total = quizState.questions.length;
const q = quizState.questions[quizState.current];
if (!q) return;
const progress = ((quizState.current) / total) * 100;
const letters = ['A', 'B', 'C', 'D', 'E'];
stage.innerHTML = `
<div class="quiz-bar"><div class="quiz-bar__fill" style="width:${progress}%"></div></div>
<div class="quiz-meta">
<span><strong>${quizState.current + 1}</strong> / ${total}</span>
<span>${categoryLabelQuiz(q.category)}</span>
<span>Riktig: <strong>${quizState.correct}</strong></span>
</div>
<h2 class="quiz-question reveal">${q.question}</h2>
<div class="quiz-options" id="quizOptions">
${q.options.map((opt, i) => `
<button class="quiz-option reveal" data-i="${i}">
<span class="quiz-option__letter">${letters[i]}</span>
<span>${opt}</span>
</button>
`).join('')}
</div>
<div id="quizExplanation"></div>
<div class="quiz-actions">
<button class="btn btn--ghost" id="quizCancel">Avslutt</button>
<button class="btn btn--primary" id="quizNext" disabled>Neste →</button>
</div>
`;
stage.querySelectorAll('.quiz-option').forEach(opt => {
opt.addEventListener('click', () => {
if (quizState.answered) return;
const i = parseInt(opt.dataset.i, 10);
quizSelect(i);
});
});
document.getElementById('quizNext').addEventListener('click', quizAdvance);
document.getElementById('quizCancel').addEventListener('click', () => {
if (confirm('Avslutte testen?')) quizRenderStart();
});
}
function quizSelect(i) {
const q = quizState.questions[quizState.current];
quizState.selected = i;
quizState.answered = true;
const opts = document.querySelectorAll('.quiz-option');
opts.forEach((opt, idx) => {
opt.classList.add('quiz-option--disabled');
if (idx === q.correct) opt.classList.add('quiz-option--correct');
if (idx === i && i !== q.correct) opt.classList.add('quiz-option--wrong');
if (idx === i) opt.classList.add('quiz-option--selected');
});
if (i === q.correct) quizState.correct++;
else quizState.wrong++;
const exp = document.getElementById('quizExplanation');
exp.innerHTML = `
<div class="quiz-explanation reveal">
<div class="quiz-explanation__label">${i === q.correct ? 'Riktig — ' : 'Forklaring — '}</div>
<div>${q.explanation}</div>
</div>
`;
document.getElementById('quizNext').disabled = false;
}
function quizAdvance() {
quizState.current++;
quizState.selected = null;
quizState.answered = false;
if (quizState.current >= quizState.questions.length) {
quizState.finished = true;
}
quizRenderCurrent();
}
function quizRenderResult() {
const stage = document.getElementById('quizStage');
const total = quizState.questions.length;
const pct = total ? Math.round((quizState.correct / total) * 100) : 0;
let verdict, vColor;
if (pct >= 90) { verdict = 'Fremragende.'; vColor = 'var(--theme-baerekraft)'; }
else if (pct >= 80) { verdict = 'Meget god.'; vColor = 'var(--theme-baerekraft)'; }
else if (pct >= 65) { verdict = 'Solid forståelse.'; vColor = 'var(--theme-samfunn)'; }
else if (pct >= 50) { verdict = 'Greit, men trener videre.'; vColor = 'var(--theme-samfunn)'; }
else { verdict = 'Repeter mer av dette temaet.'; vColor = 'var(--theme-etikk)'; }
stage.innerHTML = `
<div class="quiz-result reveal">
<div class="quiz-result__score">${quizState.correct}<span style="color:var(--muted)">/${total}</span></div>
<div class="quiz-result__label">${pct} % riktig</div>
<div class="quiz-result__verdict" style="color:${vColor}">${verdict}</div>
<div class="quiz-actions" style="justify-content:center; margin-top: var(--sp-7)">
<button class="btn" id="quizRestart">Test på nytt</button>
<button class="btn btn--primary" id="quizMore">Andre kategori</button>
</div>
</div>
`;
document.getElementById('quizRestart').addEventListener('click', () => quizStart(quizState.filter));
document.getElementById('quizMore').addEventListener('click', () => quizRenderStart());
}
function categoryLabelQuiz(cat) {
return {
etikk: 'Etikk',
baerekraft: 'Bærekraft',
samfunn: 'Samfunnsansvar',
verktoy: 'Verktøy & implementering'
}[cat] || cat;
}
async function quizInit() {
await quizLoad();
quizRenderStart();
}
SMF.quizInit = quizInit;

263
app/js/render.js Normal file
View File

@@ -0,0 +1,263 @@
// =====================================================
// Render — markdown loading and lesson rendering
// =====================================================
const noteCache = new Map();
async function loadNote(file) {
if (noteCache.has(file)) return noteCache.get(file);
const res = await fetch(`notes/${file}`);
if (!res.ok) throw new Error(`Klarte ikke laste ${file}`);
const text = await res.text();
noteCache.set(file, text);
return text;
}
// Split markdown by week sections — looking for headers like "## Uke X — ..." or "# UKE X"
function extractWeekSection(markdown, weekId) {
const lines = markdown.split('\n');
// Match #, ##, ### at start; "Uke" or "UKE"; the week id as separate token
const headerRe = new RegExp(`^#{1,3}\\s+UKE\\s+${weekId}(?!\\d)`, 'i');
let start = -1;
let startLevel = 0;
for (let i = 0; i < lines.length; i++) {
const m = lines[i].match(headerRe);
if (m) {
start = i;
// Count leading hashes
const hashMatch = lines[i].match(/^(#+)/);
startLevel = hashMatch ? hashMatch[1].length : 2;
break;
}
}
if (start === -1) return null;
// Find next header at same or higher level that starts a NEW week
const nextHeaderRe = new RegExp(`^#{1,${startLevel}}\\s+UKE\\s+\\d+`, 'i');
let end = lines.length;
for (let i = start + 1; i < lines.length; i++) {
if (nextHeaderRe.test(lines[i])) { end = i; break; }
}
let section = lines.slice(start, end).join('\n');
// Strip the first heading entirely (we show the title in the lesson-header)
section = section.replace(/^#{1,3}\s+[^\n]+\n+/, '');
// Normalize remaining heading levels: bring everything to H2/H3/H4 starting fresh.
// Original starting level (after stripped header) was startLevel + 1 typically.
// We want the deepest visible header in the section to start at H2.
const subLines = section.split('\n');
// Find the minimum heading level inside section
let minLevel = Infinity;
for (const l of subLines) {
const m = l.match(/^(#{1,6})\s/);
if (m) minLevel = Math.min(minLevel, m[1].length);
}
if (minLevel === Infinity) return section;
const shift = 2 - minLevel; // bring minLevel up to 2
if (shift !== 0) {
section = subLines.map(l => {
const m = l.match(/^(#{1,6})\s/);
if (!m) return l;
const newLevel = Math.min(6, Math.max(1, m[1].length + shift));
return '#'.repeat(newLevel) + l.slice(m[1].length);
}).join('\n');
}
return section;
}
// Custom marked renderer for tighter HTML
function renderMarkdown(md) {
marked.setOptions({
gfm: true,
breaks: false,
headerIds: true,
mangle: false
});
return marked.parse(md);
}
// ============= Home view =============
function renderHome() {
const tpl = document.getElementById('t-home').content.cloneNode(true);
return tpl;
}
// ============= Lesson view =============
async function renderLesson(weekId) {
const tpl = document.getElementById('t-lesson').content.cloneNode(true);
const week = SMF.WEEKS.find(w => w.id === weekId);
if (!week) {
tpl.getElementById('lessonNum').textContent = 'Ikke funnet';
tpl.getElementById('lessonTitle').textContent = 'Ukjent uke';
return tpl;
}
const themeColors = SMF.THEME_COLORS[week.theme] || SMF.THEME_COLORS.all;
// Header
const num = tpl.getElementById('lessonNum');
num.textContent = `Uke ${String(weekId).padStart(2, '0')} · ${themeLabel(week.theme)}`;
num.style.color = themeColors.color;
const title = tpl.getElementById('lessonTitle');
title.innerHTML = formatTitleWithEm(week.title);
// Meta
const meta = tpl.getElementById('lessonMeta');
const tag = document.createElement('span');
tag.className = 'tag';
tag.textContent = themeLabel(week.theme);
tag.style.setProperty('--theme-color', themeColors.color);
tag.style.setProperty('--theme-color-bg', themeColors.bg);
meta.appendChild(tag);
// Body — load and render
const body = tpl.getElementById('lessonBody');
try {
const md = await loadNote(week.file);
let weekMd = extractWeekSection(md, weekId);
if (!weekMd) {
// Fallback: entire file (Uke 17 case)
weekMd = md.replace(/^#\s+[^\n]+\n+/, '');
}
body.innerHTML = renderMarkdown(weekMd);
} catch (e) {
body.innerHTML = `<p>Klarte ikke laste ukens innhold: ${e.message}</p>`;
}
// Pager
const idx = SMF.WEEKS.findIndex(w => w.id === weekId);
const prev = idx > 0 ? SMF.WEEKS[idx - 1] : null;
const next = idx < SMF.WEEKS.length - 1 ? SMF.WEEKS[idx + 1] : null;
const pager = tpl.getElementById('lessonPager');
if (prev) {
const a = document.createElement('a');
a.href = `#/uke/${prev.id}`;
a.className = 'pager-link pager-link--prev';
a.innerHTML = `<div class="pager-link__dir">← Forrige · Uke ${prev.id}</div><div class="pager-link__title">${prev.title}</div>`;
pager.appendChild(a);
} else {
pager.appendChild(spacer());
}
if (next) {
const a = document.createElement('a');
a.href = `#/uke/${next.id}`;
a.className = 'pager-link pager-link--next';
a.innerHTML = `<div class="pager-link__dir">Neste · Uke ${next.id} →</div><div class="pager-link__title">${next.title}</div>`;
pager.appendChild(a);
} else {
pager.appendChild(spacer());
}
return tpl;
}
function spacer() {
const d = document.createElement('div');
d.style.flex = '1';
return d;
}
function themeLabel(theme) {
return {
etikk: 'Etikk',
baerekraft: 'Bærekraft',
samfunn: 'Samfunnsansvar',
verktoy: 'Verktøy & implementering',
all: 'Oversikt'
}[theme] || theme;
}
function formatTitleWithEm(title) {
// Wrap "Etikk", "bærekraft" osv. in <em> for visual rhythm
const parts = title.split(/\s+/);
if (parts.length === 1) return `<em>${title}</em>`;
// pick the last word for em treatment
return parts.slice(0, -1).join(' ') + ' <em>' + parts.at(-1) + '</em>';
}
// ============= Tema view =============
async function renderTema(temaId) {
const tpl = document.getElementById('t-tema').content.cloneNode(true);
const tema = SMF.getTheme(temaId);
if (!tema) return tpl;
const themeColors = SMF.THEME_COLORS[temaId];
const header = tpl.getElementById('temaHeader');
header.innerHTML = `
<div class="lesson-header__num" style="color:${themeColors.color}">${tema.eyebrow}</div>
<h1 class="lesson-header__title">${tema.title}</h1>
<div class="lesson-header__meta">
<span>Uker: ${tema.weeks.join(' · ')}</span>
</div>
`;
const body = tpl.getElementById('temaBody');
// Intro blockquote
const intro = document.createElement('blockquote');
intro.textContent = tema.intro;
body.appendChild(intro);
// Concepts
const conceptsH = document.createElement('h2');
conceptsH.textContent = 'Kjernebegreper';
body.appendChild(conceptsH);
tema.keyConcepts.forEach(c => {
const wrap = document.createElement('div');
wrap.className = 'concept';
wrap.innerHTML = `<div class="concept__term">${c.term}</div><div class="concept__def">${c.def}</div>`;
body.appendChild(wrap);
});
// Weeks
const weeksH = document.createElement('h2');
weeksH.textContent = 'Uker i dette temaet';
body.appendChild(weeksH);
const weekList = document.createElement('div');
weekList.className = 'lesson-pager';
weekList.style.flexWrap = 'wrap';
weekList.style.borderTop = '0';
weekList.style.paddingTop = '0';
weekList.style.marginTop = '0';
tema.weeks.forEach(wid => {
const w = SMF.WEEKS.find(x => x.id === wid);
if (!w) return;
const a = document.createElement('a');
a.href = `#/uke/${w.id}`;
a.className = 'pager-link';
a.style.flexBasis = '260px';
a.style.flexGrow = '0';
a.innerHTML = `<div class="pager-link__dir">Uke ${w.id}</div><div class="pager-link__title">${w.title}</div>`;
weekList.appendChild(a);
});
body.appendChild(weekList);
return tpl;
}
// ============= TL;DR view =============
async function renderTldr() {
const tpl = document.getElementById('t-tldr').content.cloneNode(true);
const body = tpl.getElementById('tldrBody');
try {
const md = await loadNote('tldr.md');
// Strip the first H1 since we have it in the hero
const stripped = md.replace(/^#\s+[^\n]+\n+/, '');
body.innerHTML = renderMarkdown(stripped);
} catch (e) {
body.innerHTML = `<p>Klarte ikke laste tl;dr: ${e.message}</p>`;
}
return tpl;
}
SMF.renderHome = renderHome;
SMF.renderLesson = renderLesson;
SMF.renderTema = renderTema;
SMF.renderTldr = renderTldr;
SMF.loadNote = loadNote;
SMF.renderMarkdown = renderMarkdown;
SMF.extractWeekSection = extractWeekSection;
SMF.themeLabel = themeLabel;

202
app/js/search.js Normal file
View File

@@ -0,0 +1,202 @@
// =====================================================
// Search — index across all notes and concepts
// =====================================================
let searchIndex = null;
async function buildSearchIndex() {
if (searchIndex) return searchIndex;
const idx = [];
// Index concepts from THEMES
Object.values(SMF.THEMES).forEach(theme => {
theme.keyConcepts.forEach(c => {
idx.push({
type: 'concept',
category: theme.label,
title: c.term,
snippet: c.def,
href: `#/tema/${theme.id}`,
searchText: `${c.term} ${c.def}`.toLowerCase()
});
});
});
// Index weeks
SMF.WEEKS.forEach(w => {
idx.push({
type: 'uke',
category: SMF.themeLabel(w.theme),
title: `Uke ${w.id}: ${w.title}`,
snippet: '',
href: `#/uke/${w.id}`,
searchText: `uke ${w.id} ${w.title}`.toLowerCase()
});
});
// Load all notes and extract headings + paragraphs
const noteFiles = ['uke02-03-04.md', 'uke05-06.md', 'uke07-08.md', 'uke10-11.md', 'uke12-16.md', 'uke17-eksamen.md'];
for (const file of noteFiles) {
try {
const md = await SMF.loadNote(file);
const lines = md.split('\n');
let currentWeek = null;
let currentH = null;
let buffer = [];
const flush = () => {
if (buffer.length && currentH) {
const txt = buffer.join(' ').trim();
if (txt.length > 20) {
idx.push({
type: 'avsnitt',
category: currentWeek ? `Uke ${currentWeek}` : 'Pensum',
title: currentH,
snippet: txt.slice(0, 220) + (txt.length > 220 ? '…' : ''),
href: currentWeek ? `#/uke/${currentWeek}` : `#/uke/17`,
searchText: (currentH + ' ' + txt).toLowerCase()
});
}
}
buffer = [];
};
for (const line of lines) {
const ukeMatch = line.match(/^##\s+Uke\s+(\d+)/i);
if (ukeMatch) {
flush();
currentWeek = parseInt(ukeMatch[1], 10);
currentH = line.replace(/^#+\s+/, '');
continue;
}
const hMatch = line.match(/^#{3,4}\s+(.+)/);
if (hMatch) {
flush();
currentH = hMatch[1].trim();
continue;
}
if (line.trim() && !line.startsWith('|') && !line.startsWith('---')) {
buffer.push(line.replace(/[*_`]/g, ''));
}
}
flush();
} catch (e) {
console.warn('Could not load note for indexing:', file, e);
}
}
searchIndex = idx;
return idx;
}
function searchQuery(q) {
if (!searchIndex || !q || q.length < 2) return [];
const qLow = q.toLowerCase();
const terms = qLow.split(/\s+/).filter(t => t.length > 1);
if (!terms.length) return [];
const scored = [];
for (const item of searchIndex) {
let score = 0;
let titleHits = 0;
const titleLow = item.title.toLowerCase();
terms.forEach(t => {
if (titleLow.includes(t)) { score += 10; titleHits++; }
if (item.searchText.includes(t)) { score += 2; }
});
// Bonus: type-priority — concepts > weeks > paragraphs
if (item.type === 'concept') score += 3;
else if (item.type === 'uke') score += 2;
// Bonus: title contains whole query
if (titleLow.includes(qLow)) score += 8;
if (score > 0) scored.push({ item, score, titleHits });
}
scored.sort((a, b) => b.score - a.score);
return scored.slice(0, 12).map(s => s.item);
}
function highlight(text, q) {
if (!q) return text;
const terms = q.toLowerCase().split(/\s+/).filter(t => t.length > 1);
let out = text;
terms.forEach(t => {
const re = new RegExp(`(${t.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')})`, 'gi');
out = out.replace(re, '<mark>$1</mark>');
});
return out;
}
function attachSearch() {
const input = document.getElementById('searchInput');
const results = document.getElementById('searchResults');
if (!input || !results) return;
let timer = null;
input.addEventListener('input', async (e) => {
const q = e.target.value.trim();
if (!q || q.length < 2) {
results.classList.remove('search-results--open');
results.innerHTML = '';
return;
}
await buildSearchIndex();
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
const matches = searchQuery(q);
if (!matches.length) {
results.innerHTML = `<div class="search-result"><div class="search-result__title">Ingen treff på "${q}"</div></div>`;
} else {
results.innerHTML = matches.map(m => `
<a class="search-result" href="${m.href}">
<div class="search-result__type">${m.type} · ${m.category}</div>
<div class="search-result__title">${highlight(m.title, q)}</div>
${m.snippet ? `<div class="search-result__snippet">${highlight(m.snippet, q)}</div>` : ''}
</a>
`).join('');
}
results.classList.add('search-results--open');
}, 80);
});
input.addEventListener('focus', () => {
if (input.value.length >= 2) {
results.classList.add('search-results--open');
}
});
// Hide on outside click
document.addEventListener('click', (e) => {
if (!input.contains(e.target) && !results.contains(e.target)) {
results.classList.remove('search-results--open');
}
});
// Click result -> close
results.addEventListener('click', (e) => {
const a = e.target.closest('.search-result');
if (a) {
results.classList.remove('search-results--open');
input.value = '';
input.blur();
}
});
// Keyboard: '/' to focus
document.addEventListener('keydown', (e) => {
if (e.key === '/' && document.activeElement !== input && !e.metaKey && !e.ctrlKey) {
const tag = document.activeElement?.tagName;
if (tag !== 'INPUT' && tag !== 'TEXTAREA') {
e.preventDefault();
input.focus();
input.select();
}
}
if (e.key === 'Escape') {
results.classList.remove('search-results--open');
input.blur();
}
});
}
SMF.attachSearch = attachSearch;
SMF.buildSearchIndex = buildSearchIndex;

1
app/notes Symbolic link
View File

@@ -0,0 +1 @@
../notes

69
app/vendor/marked.min.js vendored Normal file

File diff suppressed because one or more lines are too long