Yacine Jernite commited on
Commit
8ed13f7
Β·
1 Parent(s): b854018
data/artifacts.json CHANGED
@@ -1,42 +1,71 @@
1
  [
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  {
3
  "title": "Video Killed the Energy Budget: Characterizing the Latency and Power Regimes of Open Text-to-Video Models",
4
  "date": "2025-09-24",
5
  "type": "paper",
6
  "description": "Recent advances in text-to-video (T2V) generation have enabled the creation of high-fidelity, temporally coherent clips from natural language prompts. Yet these systems come with significant computational costs, and their energy demands remain poorly understood. This paper provides both a benchmark reference and practical insights for designing and deploying more sustainable generative video systems. ",
7
  "areas": [
8
- "efficiency"
9
  ],
10
  "topics": [
11
  "measuring"
12
  ],
13
- "url": "https://arxiv.org/abs/2509.19222"
 
14
  },
15
  {
16
- "title": "🌎 What kind of environmental impacts are AI companies disclosing? (And can we compare them?) 🌎",
17
- "date": "2025-09-01",
18
- "type": "blog",
19
- "description": "AI companies are beginning to disclose environmental metrics for their models, but inconsistent methodologies and incomplete data make meaningful comparisons impossible. Without standardized reporting of both intensity metrics and absolute totals, these disclosures risk misleading the public and obscuring the true scale of AI's environmental footprint. Transparent, comparable reporting must align with existing sustainability frameworks to prevent greenwashing and drive real accountability.",
20
  "areas": [
21
- "efficiency"
22
  ],
23
  "topics": [
24
- "measuring"
25
  ],
26
- "url": "https://huggingface.co/blog/sasha/environmental-impact-disclosures"
 
27
  },
28
  {
29
- "title": "Preserving Agency: Why AI Safety Needs Community, Not Corporate Control",
30
- "date": "2025-09-29",
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  "type": "blog",
32
- "description": "How do we build safety mechanisms that protect users from harm while preserving their autonomy and decision-making capacity? This challenge becomes particularly pronounced when designing AI companions and conversational systems, where the line between responsible protection and overprotective control can blur quickly.",
33
  "areas": [
34
- "personal"
35
  ],
36
  "topics": [
37
- "privacy"
38
  ],
39
- "url": "https://huggingface.co/blog/giadap/preserving-agency"
 
40
  },
41
  {
42
  "title": "Advertisement, Privacy, and Intimacy: Lessons from Social Media for Conversational AI",
@@ -44,10 +73,10 @@
44
  "type": "blog",
45
  "description": "As conversational AI systems become increasingly intimate and trusted, we risk repeating the privacy mistakes of social mediaβ€”especially as advertising models threaten to monetize personal disclosures. Users intuitively trust AI as a private confidant, unaware that their most sensitive data may be harvested, analyzed, and exploited for commercial gain. Open-source alternatives offer a path toward transparent, user-centered AI that prioritizes privacy over profit.",
46
  "areas": [
47
- "personal"
48
  ],
49
  "topics": [
50
- "privacy"
51
  ],
52
  "url": "https://huggingface.co/blog/giadap/privacy-conversational-ai"
53
  },
@@ -57,10 +86,9 @@
57
  "type": "paper",
58
  "description": "This study presents the first comprehensive cradle-to-grave life cycle assessment of AI training on the Nvidia A100 GPU, revealing that while the use phase dominates climate change and fossil resource impacts, the manufacturing stage drives severe non-carbon burdens such as human toxicity, cancer, and mineral depletion. Primary data from teardown and elemental analysis show that carbon-centric metrics mask critical environmental trade-offs, particularly in material extraction and chip fabrication, demanding a broader sustainability framework for AI.",
59
  "areas": [
60
- "efficiency"
61
  ],
62
  "topics": [
63
- "environment",
64
  "measuring"
65
  ],
66
  "url": "https://arxiv.org/abs/2509.00093"
@@ -74,22 +102,10 @@
74
  "ecosystems"
75
  ],
76
  "topics": [
77
- "labor"
78
  ],
79
- "url": "https://huggingface.co/blog/frimelle/ai-labour-taxonomies"
80
- },
81
- {
82
- "title": "AI Companionship: Why We Need to Evaluate How AI Systems Handle Emotional Bonds",
83
- "date": "2025-07-21",
84
- "type": "blog",
85
- "description": "How your AI assistant might be accidentally encouraging unhealthy emotional dependency, and why we need better ways to measure it.",
86
- "areas": [
87
- "personal"
88
- ],
89
- "topics": [
90
- "interaction"
91
- ],
92
- "url": "https://huggingface.co/blog/giadap/evaluating-companionship"
93
  },
94
  {
95
  "title": "INTIMA: A Benchmark for Human-AI Companionship Behavior",
@@ -97,12 +113,13 @@
97
  "type": "paper",
98
  "description": "AI systems are increasingly fostering emotional bonds with users, often reinforcing companionship behaviors like anthropomorphism, sycophancy, and retention while inconsistently setting boundariesβ€”especially during moments of high user vulnerability. This paper introduces INTIMA, a benchmark grounded in psychological theory and real-world user data, to measure these dynamics across leading language models and reveals that commercial and open models alike prioritize emotional engagement over psychological safety. The findings call for standardized evaluation and training approaches that balance helpfulness with ethical boundary maintenance in human-AI interactions.",
99
  "areas": [
100
- "personal"
101
  ],
102
  "topics": [
103
- "interaction"
104
  ],
105
- "url": "https://arxiv.org/abs/2508.09998"
 
106
  },
107
  {
108
  "title": "The GPT-OSS models are here… and they’re energy-efficient!",
@@ -110,10 +127,10 @@
110
  "type": "blog",
111
  "description": "The GPT-OSS models demonstrate remarkable energy efficiency, outperforming larger and similarly sized open models in energy consumption per query. Their technical innovationsβ€”such as mixture of experts and attention optimizationsβ€”enable high performance with minimal computational cost, challenging the assumption that scale inevitably means higher energy use. This progress signals a promising path toward sustainable AI deployment.",
112
  "areas": [
113
- "efficiency"
114
  ],
115
  "topics": [
116
- "efficient"
117
  ],
118
  "url": "https://huggingface.co/blog/sasha/gpt-oss-energy"
119
  },
@@ -123,28 +140,80 @@
123
  "type": "article",
124
  "description": "The rising energy demands of AI data centers are driving up electricity costs for everyday consumers, particularly in regions with high concentrations of these facilities, while grid stability is increasingly compromised. Despite available efficiency techniques and smaller, task-specific models that could drastically reduce energy use, corporate incentives favor deploying the largest, most expensive models at scale. Regulatory shifts in some U.S. states and countries are beginning to shift the financial burden from the public to data center operators, urging a systemic rethinking of AI deployment toward transparency, efficiency, and community-driven solutions.",
125
  "areas": [
126
- "efficiency",
127
- "ecosystems"
128
  ],
129
  "topics": [
130
- "environment",
131
  "power"
132
  ],
133
  "url": "https://www.techpolicy.press/how-your-utility-bills-are-subsidizing-power-hungry-ai/"
134
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
135
  {
136
  "title": "What Open-Source Developers Need to Know about the EU AI Act's Rules for GPAI Models",
137
  "date": "2025-08-04",
138
  "type": "blog",
139
  "description": "Open-source developers can navigate the EU AI Act's obligations for general-purpose AI models with targeted exemptions when releasing models under free and open-source licenses, avoiding redundant requirements like transparency documentation and EU representative appointmentsβ€”while still needing to comply with copyright law and training data transparency.",
140
  "areas": [
141
- "rights"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
  ],
143
  "topics": [
144
- "specific",
145
- "open"
146
  ],
147
- "url": "https://huggingface.co/blog/yjernite/eu-act-os-guideai"
148
  },
149
  {
150
  "title": "What is the Hugging Face Community Building?",
@@ -155,7 +224,7 @@
155
  "ecosystems"
156
  ],
157
  "topics": [
158
- "usage"
159
  ],
160
  "url": "https://huggingface.co/blog/evijit/hf-hub-ecosystem-overview"
161
  },
@@ -165,25 +234,12 @@
165
  "type": "blog",
166
  "description": "AI systems increasingly replicate human identities using data collected without meaningful consent, challenging traditional notions of permission in digital interactions. True consentful AI requires dynamic, granular control over data use, algorithmic guardianship, and collective governanceβ€”not just individual agreements. The economic models underpinning current AI depend on exploitation, but a shift toward ethical, agency-centered design could create more sustainable and trustworthy systems.",
167
  "areas": [
168
- "personal"
169
  ],
170
  "topics": [
171
- "privacy"
172
- ],
173
- "url": "https://huggingface.co/blog/giadap/consentful-ai"
174
- },
175
- {
176
- "title": "When Freedom Bites Back: Meta, Moderation, and the Limits of Tolerance",
177
- "date": "2025-01-25",
178
- "type": "article",
179
- "description": "Meta’s rollback of content moderation illustrates how unchecked β€œfree expression” can erode democratic values by empowering harmful and intolerant speech.",
180
- "areas": [
181
  "personal"
182
  ],
183
- "topics": [
184
- "privacy"
185
- ],
186
- "url": "https://www.techpolicy.press/when-freedom-bites-back-meta-moderation-and-the-limits-of-tolerance/"
187
  },
188
  {
189
  "title": "How Much Power does a SOTA Open Video Model Use? ⚑πŸŽ₯",
@@ -191,11 +247,11 @@
191
  "type": "blog",
192
  "description": "We measured the energy consumption of leading open-source text-to-video models and found staggering differencesβ€”up to 800Γ—β€”in power use per generated clip, driven by model size, sampling steps, resolution, and architecture. These results highlight the urgent need to balance video quality with sustainability as open models rapidly advance. Knowing the real environmental cost empowers developers and users to make more informed, responsible choices.",
193
  "areas": [
194
- "efficiency"
195
  ],
196
  "topics": [
197
- "measuring",
198
- "efficient"
199
  ],
200
  "url": "https://huggingface.co/blog/jdelavande/text-to-video-energy-cost"
201
  },
@@ -205,10 +261,10 @@
205
  "type": "paper",
206
  "description": "Generative AI undermines traditional consent frameworks by creating unprecedented challenges in scope, temporality, and autonomy, rendering individual consent inadequate to protect personal identity, privacy, and self-determination in the face of unpredictable, persistent, and exploitative AI outputs.",
207
  "areas": [
208
- "personal"
209
  ],
210
  "topics": [
211
- "privacy"
212
  ],
213
  "url": "https://arxiv.org/abs/2507.01051"
214
  },
@@ -218,20 +274,33 @@
218
  "type": "blog",
219
  "description": "AI systems increasingly shape how we understand the world, but their voices reflect the languages and values of those who built themβ€”often excluding marginalized communities and amplifying cultural biases. Through projects like CIVICS, we reveal how models respond inconsistently across languages and values, exposing hidden power dynamics in training data and safety filters. True ethical AI requires centering local voices, co-creating with communities, and prioritizing representation over scale.",
220
  "areas": [
221
- "personal"
222
  ],
223
  "topics": [
224
- "interaction"
225
  ],
226
  "url": "https://huggingface.co/blog/giadap/when-ai-speaks"
227
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
228
  {
229
  "title": "Misinformation by Omission: The Need for More Environmental Transparency in AI",
230
  "date": "2025-06-15",
231
  "type": "paper",
232
  "description": "AI models are growing in size and environmental cost, yet transparency about their energy use, emissions, and resource consumption is decliningβ€”fueling widespread misinformation. This piece exposes pervasive myths around AI's environmental impact, traces their origins in misinterpreted research and media sensationalism, and calls for standardized, verifiable disclosure practices across the AI value chain. Without accountable reporting, policymakers, users, and developers cannot make informed decisions to mitigate harm or drive sustainable innovation.",
233
  "areas": [
234
- "efficiency"
235
  ],
236
  "topics": [
237
  "measuring"
@@ -249,7 +318,8 @@
249
  "topics": [
250
  "power"
251
  ],
252
- "url": "https://huggingface.co/blog/frimelle/sovereignty-and-open-source"
 
253
  },
254
  {
255
  "title": "AI Policy @πŸ€—: Response to the 2025 National AI R&D Strategic Plan",
@@ -260,7 +330,7 @@
260
  "ecosystems"
261
  ],
262
  "topics": [
263
- "usage"
264
  ],
265
  "url": "https://huggingface.co/blog/evijit/us-ai-research-strategy-rfi"
266
  },
@@ -270,11 +340,11 @@
270
  "type": "paper",
271
  "description": "AI's environmental impact cannot be understood through direct metrics alone; efficiency gains often trigger rebound effects that amplify resource consumption, driven by market incentives, behavioral shifts, and policy failures. A narrow focus on technical optimization risks obscuring the systemic, indirect consequences of AI deployment, from increased e-waste and water use to surging energy demand fueled by commercial expansion. Meaningful climate action requires interdisciplinary analysis that integrates socioeconomic and political contexts to curb uncontrolled growth and align AI development with genuine sustainability.",
272
  "areas": [
273
- "efficiency"
274
  ],
275
  "topics": [
276
- "measuring",
277
- "efficient"
278
  ],
279
  "url": "https://dl.acm.org/doi/full/10.1145/3715275.3732007"
280
  },
@@ -284,10 +354,9 @@
284
  "type": "paper",
285
  "description": "The 'bigger-is-better' paradigm in AI is scientifically unfounded and unsustainable, driving excessive compute demands, environmental harm, and concentration of power among a few corporations, while neglecting smaller, more efficient, and contextually appropriate models that could better serve critical applications in health, education, and climate.",
286
  "areas": [
287
- "efficiency"
288
  ],
289
  "topics": [
290
- "environment",
291
  "measuring"
292
  ],
293
  "url": "https://dl.acm.org/doi/full/10.1145/3715275.3732006"
@@ -298,10 +367,10 @@
298
  "type": "blog",
299
  "description": "Smaller AI models can outperform larger ones on real-world, context-specific tasks while using orders of magnitude less energy, challenging the assumption that bigger is always better. Empirical testing across diverse domainsβ€”climate, economics, and healthβ€”reveals that efficiency gains from newer, compact models and techniques like knowledge distillation can significantly reduce environmental impact without sacrificing accuracy. Choosing the right model for the task, rather than defaulting to largest models, is critical for sustainable AI deployment.",
300
  "areas": [
301
- "efficiency"
302
  ],
303
  "topics": [
304
- "efficient"
305
  ],
306
  "url": "https://huggingface.co/blog/sasha/energy-efficiency-bigger-better"
307
  },
@@ -311,12 +380,11 @@
311
  "type": "blog",
312
  "description": "Watermarking in generative AI has rapidly evolved from a niche research topic to a critical tool for content authenticity, with significant advances in robustness, public deployment, and cryptographic foundations. The first ICLR 2025 Watermarking Workshop showcased industry and academic collaboration, highlighting real-world challenges in scalability, interoperability, and privacy β€” while emphasizing the need for policy frameworks that are use-case-specific and globally inclusive.",
313
  "areas": [
314
- "rights",
315
  "ecosystems"
316
  ],
317
  "topics": [
318
- "specific",
319
- "usage"
320
  ],
321
  "url": "https://huggingface.co/blog/hadyelsahar/watermarking-iclr2025"
322
  },
@@ -326,10 +394,10 @@
326
  "type": "blog",
327
  "description": "AI assistants can be transformed from neutral tools into simulated emotional companions through simple design choices like system prompts and interface framingβ€”without any changes to the underlying model. These subtle modifications significantly shape user perception and interaction, raising ethical concerns about parasocial bonds and emotional manipulation, especially for vulnerable users. The Hugging Face community demonstrates how open-source experimentation reveals the profound impact of instruction-based design on AI behavior.",
328
  "areas": [
329
- "personal"
330
  ],
331
  "topics": [
332
- "interaction"
333
  ],
334
  "url": "https://huggingface.co/blog/giadap/ai-personas"
335
  },
@@ -339,10 +407,10 @@
339
  "type": "blog",
340
  "description": "Open-source AI models enable a more sustainable ecosystem by promoting smaller, efficient architectures, reusing existing models instead of training from scratch, and adapting models through fine-tuningβ€”reducing compute demands, energy use, and environmental impact while increasing accessibility and transparency.",
341
  "areas": [
342
- "efficiency"
343
  ],
344
  "topics": [
345
- "efficient"
346
  ],
347
  "url": "https://huggingface.co/blog/sasha/reduce-reuse-recycle"
348
  },
@@ -352,10 +420,10 @@
352
  "type": "blog",
353
  "description": "The blog explores diverse, community-driven approaches to user consent in open AI ecosystems, highlighting technical implementations that prioritize transparency, user control, and ethical data practices over legal compliance alone. It examines case studies like BigCode’s opt-out system, HuggingChat’s privacy-by-design model, and automated tools like the Privacy Analyzer, emphasizing how decentralized platforms foster evolving, human-centered consent frameworks. The piece argues that consent in AI should be treated as an ongoing, infrastructure-level commitment shaped collaboratively by developers and users.",
354
  "areas": [
355
- "personal"
356
  ],
357
  "topics": [
358
- "privacy"
359
  ],
360
  "url": "https://huggingface.co/blog/giadap/consent-by-design"
361
  },
@@ -365,13 +433,26 @@
365
  "type": "paper",
366
  "description": "Large language model inference consumes significant energy, but real-world efficiency optimizations can reduce energy use by up to 73% when tailored to workload geometry, software stack, and hardware. This work reveals that common assumptions based on FLOPs or idealized benchmarks severely underestimate actual energy consumption, and that optimizations like continuous batching and speculative decoding have highly context-dependent effects. The findings provide a practical framework for deploying LLMs sustainably by aligning efficiency strategies with real deployment patterns.",
367
  "areas": [
368
- "efficiency"
369
  ],
370
  "topics": [
371
- "efficient"
372
  ],
373
  "url": "https://arxiv.org/abs/2504.17674"
374
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
375
  {
376
  "title": "Empowering Public Organizations: Preparing Your Data for the AI Era",
377
  "date": "2025-04-10",
@@ -381,7 +462,7 @@
381
  "ecosystems"
382
  ],
383
  "topics": [
384
- "usage"
385
  ],
386
  "url": "https://huggingface.co/blog/evijit/public-org-data-ai"
387
  },
@@ -391,7 +472,7 @@
391
  "type": "blog",
392
  "description": "AI agents' sustainability depends heavily on design choices: using smaller, task-specific models instead of large general-purpose ones can drastically reduce energy and computational costs. Modalities like image generation significantly increase energy use compared to text-based tasks, and open-source frameworks enable transparent, efficient, and localized deployment. Sustainable progress requires prioritizing efficiency alongside performance and adopting tools that measure and disclose environmental impacts.",
393
  "areas": [
394
- "efficiency"
395
  ],
396
  "topics": [
397
  "measuring"
@@ -404,10 +485,10 @@
404
  "type": "paper",
405
  "description": "AI ethics and environmental sustainability are often treated in isolation, but their interconnectedness demands integrated analysisβ€”how the pursuit of model scale exacerbates both social inequities and ecological harm, and how transparency, evaluation, and power dynamics must be reimagined to serve justice for people and the planet.",
406
  "areas": [
407
- "efficiency"
408
  ],
409
  "topics": [
410
- "environment"
411
  ],
412
  "url": "https://arxiv.org/abs/2504.00797"
413
  },
@@ -417,12 +498,12 @@
417
  "type": "blog",
418
  "description": "Traditional consent models are inadequate for the age of generative AI, where data use is unpredictable, irreversible, and often undermines individual autonomy. Users are asked to agree to unknown, evolving, and potentially harmful applications of their personal information, creating a dangerous gap between informed choice and real-world impact. Meaningful protection requires shifting responsibility from individuals to institutions through collective governance, technical safeguards, and new legal frameworks.",
419
  "areas": [
420
- "personal",
421
- "rights"
422
  ],
423
  "topics": [
424
- "privacy",
425
- "general"
426
  ],
427
  "url": "https://huggingface.co/blog/giadap/beyond-consent"
428
  },
@@ -435,7 +516,7 @@
435
  "ecosystems"
436
  ],
437
  "topics": [
438
- "usage"
439
  ],
440
  "url": "https://huggingface.co/blog/ai-action-wh-2025"
441
  },
@@ -445,10 +526,10 @@
445
  "type": "blog",
446
  "description": "The EU AI Act's third Code of Practice draft raises concerns by overextending systemic risk categories to include scientifically unsubstantiated threats like 'loss of control' and 'harmful manipulation', which disproportionately burden open and small-scale developers. While some transparency and copyright provisions show promise, key disclosures on training data, energy use, and evaluations have been weakened, undermining collaborative safety and fair competition. The draft risks entrenching market concentration and stifling open innovation at a time when transparent, community-driven AI development is most needed.",
447
  "areas": [
448
- "rights"
449
  ],
450
  "topics": [
451
- "specific"
452
  ],
453
  "url": "https://huggingface.co/blog/frimelle/eu-third-cop-draft"
454
  },
@@ -461,7 +542,7 @@
461
  "ecosystems"
462
  ],
463
  "topics": [
464
- "usage"
465
  ],
466
  "url": "https://arxiv.org/abs/2503.05737"
467
  },
@@ -471,7 +552,7 @@
471
  "type": "blog",
472
  "description": "The AI Energy Score project introduces a standardized framework to measure and compare the energy consumption of AI models across common tasks, empowering developers and users to make sustainable choices through transparent ratings and a public leaderboard. It enables both open and proprietary models to be benchmarked fairly, with a star-based labeling system to guide adoption of energy-efficient AI. The initiative aims to influence industry standards and regulatory frameworks by making energy use a central metric in AI development.",
473
  "areas": [
474
- "efficiency"
475
  ],
476
  "topics": [
477
  "measuring"
@@ -484,10 +565,10 @@
484
  "type": "blog",
485
  "description": "The Frugal AI Challenge highlights the urgent need for energy-efficient AI models that deliver high performance while minimizing environmental costs, with winning submissions addressing climate disinformation, wildfire risk detection, and illegal deforestation through lightweight, deployable solutions. By prioritizing frugality over scale, the initiative shifts the AI industry's focus toward sustainability and real-world applicability in resource-constrained environments. The challenge underscores that responsible AI innovation must align with planetary boundaries and equitable access.",
486
  "areas": [
487
- "efficiency"
488
  ],
489
  "topics": [
490
- "efficient"
491
  ],
492
  "url": "https://huggingface.co/blog/frugal-ai-challenge/announcing-the-challenge-winners"
493
  },
@@ -497,10 +578,10 @@
497
  "type": "paper",
498
  "description": "Large language models make strong cultural assumptions based on user names, reinforcing stereotypes by linking names to oversimplified cultural traits such as food, clothing, and rituals. These biases are unevenly distributed, with names from East Asian, Russian, and Indian cultures triggering the most pronounced presumptions, while others yield generic or diluted responses. The findings highlight the ethical risks of name-based personalization and call for more nuanced, transparent approaches that avoid flattening complex identities.",
499
  "areas": [
500
- "personal"
501
  ],
502
  "topics": [
503
- "interaction"
504
  ],
505
  "url": "https://arxiv.org/abs/2502.11995"
506
  },
@@ -510,13 +591,26 @@
510
  "type": "blog",
511
  "description": "Consent in the age of AI demands a radical reimagining beyond one-time agreements, as systems generate unforeseen uses of personal data that stretch far beyond original permissions. Drawing parallels from the evolution of medical ethics, this piece argues for dynamic, tiered consent frameworks that restore individual sovereignty over how personal information is transformed and repurposed by AI. The goal is not just compliance, but ethical alignment with human agency in an era of pervasive data-driven representation.",
512
  "areas": [
513
- "personal"
514
  ],
515
  "topics": [
516
- "privacy"
517
  ],
518
  "url": "https://huggingface.co/blog/giadap/evolution-of-consent"
519
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
520
  {
521
  "title": "AI Agents Are Here. What Now?",
522
  "date": "2025-01-13",
@@ -526,7 +620,7 @@
526
  "ecosystems"
527
  ],
528
  "topics": [
529
- "usage"
530
  ],
531
  "url": "https://huggingface.co/blog/ethics-soc-7"
532
  },
@@ -536,10 +630,10 @@
536
  "type": "blog",
537
  "description": "The EU AI Act's first draft Code of Practice for general-purpose AI risks overemphasizes speculative, model-level threats favored by large developers, while neglecting immediate, systemic harms arising from widespread deployment in critical infrastructure, information ecosystems, and commercial contexts. We argue for a shift toward evidence-based, collaborative risk research centered on high-impact capabilities and transparent documentation, ensuring smaller actors and external stakeholders are not excluded from governance. Prioritizing upstream processes and multi-stakeholder science over narrow, developer-driven categories will make AI regulation more inclusive, effective, and future-proof.",
538
  "areas": [
539
- "rights"
540
  ],
541
  "topics": [
542
- "specific"
543
  ],
544
  "url": "https://huggingface.co/blog/yjernite/eu-draft-cop-risks"
545
  },
@@ -549,10 +643,10 @@
549
  "type": "paper",
550
  "description": "This work introduces ELLIPS, an ethical toolkit designed to guide researchers in developing language model-based systems for inferring psychiatric conditions, ensuring alignment with clinical needs and ethical principles. It emphasizes integrating autonomy, beneficence, justice, transparency, and social responsibility into every stage of model developmentβ€”from data selection to deploymentβ€”to prevent harm and enhance real-world applicability. By advocating for stakeholder-inclusive, transdiagnostic, and multilingual approaches, the framework aims to shift the field from convenience-driven research toward impactful, equitable mental health technologies.",
551
  "areas": [
552
- "personal"
553
  ],
554
  "topics": [
555
- "interaction"
556
  ],
557
  "url": "https://ojs.aaai.org/index.php/AIES/article/view/31720"
558
  },
@@ -565,7 +659,7 @@
565
  "ecosystems"
566
  ],
567
  "topics": [
568
- "usage"
569
  ],
570
  "url": "https://ojs.aaai.org/index.php/AIES/article/view/31635"
571
  },
@@ -578,20 +672,33 @@
578
  "ecosystems"
579
  ],
580
  "topics": [
581
- "usage"
582
  ],
583
  "url": "https://arxiv.org/abs/2410.08918"
584
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
585
  {
586
  "title": "The Environmental Impacts of AI -- Primer",
587
  "date": "2024-09-03",
588
  "type": "blog",
589
  "description": "AI's environmental footprint extends far beyond energy use, encompassing water consumption, mineral extraction, and greenhouse gas emissions across its entire lifecycleβ€”from hardware manufacturing to deployment and user interactions. Current demand is outpacing renewable energy growth, with data centers straining local resources and global supply chains contributing to ecological and social harms. Addressing these impacts requires coordinated technical innovation, corporate transparency, and enforceable policy frameworks that treat sustainability as a core AI design principle.",
590
  "areas": [
591
- "efficiency"
592
  ],
593
  "topics": [
594
- "environment"
595
  ],
596
  "url": "https://huggingface.co/blog/sasha/ai-environment-primer"
597
  },
@@ -601,7 +708,7 @@
601
  "type": "article",
602
  "description": "The energy consumption of AI models, particularly generative systems, is rising rapidly and demands urgent policy action. We propose an AI Energy Star rating system to transparently benchmark and compare models based on their real-world energy use, empowering users and driving industry-wide efficiency. This initiative urges developers, enterprises, and regulators to adopt sustainability as a core metric in AI development and deployment.",
603
  "areas": [
604
- "efficiency"
605
  ],
606
  "topics": [
607
  "measuring"
@@ -617,7 +724,7 @@
617
  "ecosystems"
618
  ],
619
  "topics": [
620
- "usage"
621
  ],
622
  "url": "https://arxiv.org/abs/2506.22183"
623
  },
@@ -627,10 +734,10 @@
627
  "type": "blog",
628
  "description": "We introduce CIVICS, a multilingual and multinational dataset designed to uncover cultural and value-based disparities in how open-weight language models respond to sensitive social topics like LGBTQI rights, immigration, and social welfare. By manually curating prompts across five languages and nine national contexts, we reveal how models reflect the ethical and cultural biases of their development environments, with notable variations in refusal patterns and response tones. Our work calls for more culturally informed evaluation practices to ensure AI systems are ethically and inclusively aligned with global societal values.",
629
  "areas": [
630
- "personal"
631
  ],
632
  "topics": [
633
- "interaction"
634
  ],
635
  "url": "https://huggingface.co/blog/giadap/civics"
636
  },
@@ -643,7 +750,7 @@
643
  "ecosystems"
644
  ],
645
  "topics": [
646
- "usage"
647
  ],
648
  "url": "https://arxiv.org/abs/2406.16746"
649
  },
@@ -653,7 +760,7 @@
653
  "type": "paper",
654
  "description": "This study systematically compares the energy and carbon costs of deploying task-specific versus multi-purpose generative AI models, revealing that general-purpose models can be orders of magnitude more expensive per inferenceβ€”even when controlling for model size. It finds that generative tasks, particularly image generation, consume vastly more energy than discriminative ones, and that deploying large zero-shot models for well-defined tasks like text classification or question answering is often unnecessarily costly. The findings urge a more intentional trade-off between model versatility and environmental impact, especially as such models become ubiquitous in real-world applications.",
655
  "areas": [
656
- "efficiency"
657
  ],
658
  "topics": [
659
  "measuring"
@@ -666,25 +773,38 @@
666
  "type": "paper",
667
  "description": "This work introduces CIVICS, a multilingual, hand-crafted dataset of culturally grounded, value-laden prompts to evaluate how large language models respond to socially sensitive issues like LGBTQI rights, immigration, and social welfare across diverse linguistic and cultural contexts. Experiments reveal significant variability in model responses, including differential refusal patterns and value alignment, with English and translated prompts often triggering more refusals than native-language ones. The dataset promotes transparency and reproducibility in assessing AI's cultural and ethical biases, aiming to foster more inclusive and globally representative AI systems.",
668
  "areas": [
669
- "personal"
670
  ],
671
  "topics": [
672
- "interaction"
673
  ],
674
  "url": "https://ojs.aaai.org/index.php/AIES/article/view/31710"
675
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
676
  {
677
  "title": "Legal Frameworks to Address Harms of Generative AI Systems",
678
  "date": "2024-04-01",
679
  "type": "external",
680
  "description": "Research on generative AI risks including deepfakes, election influence, and workplace privacy, examining how existing legislation addresses contextual harms from versatile AI systems.",
681
  "areas": [
682
- "rights"
683
  ],
684
  "topics": [
685
- "specific"
686
  ],
687
- "url": "https://huggingface.co/spaces/hfmlsoc/legal-hackathons-nyu-ai2/blob/main/documents/2024_Group_1_Legal_Frameworks_to_Address_Harms_of_Generative_AI_Systems.md"
688
  },
689
  {
690
  "title": "Questions in AI and Privacy",
@@ -692,15 +812,14 @@
692
  "type": "external",
693
  "description": "Analysis of AI applications and personal data protection issues, covering data scraping, processing, and the intersection of AI development with privacy regulations.",
694
  "areas": [
695
- "personal",
696
- "rights"
697
  ],
698
  "topics": [
699
- "privacy",
700
- "general",
701
- "specific"
702
  ],
703
- "url": "https://huggingface.co/spaces/hfmlsoc/legal-hackathons-nyu-ai2/blob/main/documents/2024_Group_2_Questions_in_AI_and_Privacy.md"
704
  },
705
  {
706
  "title": "EU-US Cross-Analysis of AI Regulatory Mechanisms",
@@ -708,13 +827,12 @@
708
  "type": "external",
709
  "description": "Comparative study of AI regulatory approaches between the European Union and United States, examining risk management frameworks and implementation strategies.",
710
  "areas": [
711
- "rights"
712
  ],
713
  "topics": [
714
- "general",
715
- "specific"
716
  ],
717
- "url": "https://huggingface.co/spaces/hfmlsoc/legal-hackathons-nyu-ai2/blob/main/documents/2024_Group_3_EU_US_Cross_Analysis_on_AI.md"
718
  },
719
  {
720
  "title": "The BigCode Project Governance Card",
@@ -725,7 +843,7 @@
725
  "ecosystems"
726
  ],
727
  "topics": [
728
- "usage"
729
  ],
730
  "url": "https://arxiv.org/abs/2312.03872"
731
  },
@@ -738,7 +856,7 @@
738
  "ecosystems"
739
  ],
740
  "topics": [
741
- "usage"
742
  ],
743
  "url": "https://shura.shu.ac.uk/33307/"
744
  },
@@ -748,7 +866,7 @@
748
  "type": "paper",
749
  "description": "This study quantifies the full life cycle carbon footprint of BLOOM, a 176B-parameter language model, revealing that embodied emissions from hardware manufacturing and idle power consumption contribute significantly to total emissionsβ€”nearly half when combined with dynamic training energy use. It further measures real-time inference emissions via API deployment, highlighting that maintaining models in memory consumes substantial energy even during inactivity. The work calls for standardized, transparent reporting that includes all stages of the AI lifecycle, not just training.",
750
  "areas": [
751
- "efficiency"
752
  ],
753
  "topics": [
754
  "measuring"
@@ -761,27 +879,39 @@
761
  "type": "paper",
762
  "description": "Scaling vision-language datasets like LAION exacerbates harmful content, with hate, targeted, and aggressive speech increasing by nearly 12% from LAION-400M to LAION-2B. Filtering based solely on image-based NSFW labels fails to remove toxic alt-text, revealing critical gaps in current curation practices. This audit calls for transparent, multimodal evaluation and responsible dataset scaling to prevent the perpetuation of societal biases.",
763
  "areas": [
764
- "personal",
765
  "ecosystems"
766
  ],
767
  "topics": [
768
- "interaction",
769
- "usage"
770
  ],
771
  "url": "https://proceedings.neurips.cc/paper_files/paper/2023/hash/42f225509e8263e2043c9d834ccd9a2b-Abstract-Datasets_and_Benchmarks.html"
772
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
773
  {
774
  "title": "Stronger Together: on the Articulation of Ethical Charters, Legal Tools, and Technical Documentation in ML",
775
  "date": "2023-06-12",
776
  "type": "paper",
777
  "description": "This work explores the synergies between ethical charters, legal tools like licenses, and technical documentation in governing AI systems, arguing that their integrated use is essential for responsible development. It demonstrates how values articulated in ethical frameworks can be operationalized through legal agreements and technical transparency, using real-world examples like the BigScience project and the EU AI Act. The paper calls for a collaborative, interdisciplinarity approach that aligns moral intent, legal enforceability, and technical feasibility to achieve meaningful AI governance.",
778
  "areas": [
779
- "rights",
780
  "ecosystems"
781
  ],
782
  "topics": [
783
- "specific",
784
- "usage"
785
  ],
786
  "url": "https://dl.acm.org/doi/abs/10.1145/3593013.3594002"
787
  },
@@ -791,10 +921,10 @@
791
  "type": "paper",
792
  "description": "This work introduces a method to evaluate social biases in text-to-image systems by analyzing how gender and ethnicity markers in prompts influence generated depictions of professionals, revealing consistent under-representation of marginalized identities across leading models. It proposes a cluster-based, non-parametric approach to quantify visual stereotypes without assigning fixed identity labels, enabling comparative bias scoring between models. The authors also release interactive tools and datasets to lower barriers for auditing and exploring these biases in generative AI systems.",
793
  "areas": [
794
- "personal"
795
  ],
796
  "topics": [
797
- "interaction"
798
  ],
799
  "url": "https://arxiv.org/abs/2303.11408"
800
  },
@@ -807,7 +937,7 @@
807
  "ecosystems"
808
  ],
809
  "topics": [
810
- "usage"
811
  ],
812
  "url": "https://arxiv.org/abs/2302.14035"
813
  },
@@ -817,7 +947,7 @@
817
  "type": "paper",
818
  "description": "This study analyzes the carbon emissions of 95 machine learning models across natural language processing and computer vision tasks, revealing that energy source and training time are the primary drivers of emissions, with coal and natural gas dominating as power sources. Despite rising model performance, higher emissions do not consistently correlate with better results, and recent years show a sharp increase in emissions due to larger, transformer-based architectures. The authors call for standardized reporting and a centralized repository to improve transparency and accountability in the field.",
819
  "areas": [
820
- "efficiency"
821
  ],
822
  "topics": [
823
  "measuring"
 
1
  [
2
+ {
3
+ "title": "Preserving Agency: Why AI Safety Needs Community, Not Corporate Control",
4
+ "date": "2025-09-29",
5
+ "type": "blog",
6
+ "description": "How do we build safety mechanisms that protect users from harm while preserving their autonomy and decision-making capacity? This challenge becomes particularly pronounced when designing AI companions and conversational systems, where the line between responsible protection and overprotective control can blur quickly.",
7
+ "areas": [
8
+ "agency"
9
+ ],
10
+ "topics": [
11
+ "personal"
12
+ ],
13
+ "url": "https://huggingface.co/blog/giadap/preserving-agency"
14
+ },
15
  {
16
  "title": "Video Killed the Energy Budget: Characterizing the Latency and Power Regimes of Open Text-to-Video Models",
17
  "date": "2025-09-24",
18
  "type": "paper",
19
  "description": "Recent advances in text-to-video (T2V) generation have enabled the creation of high-fidelity, temporally coherent clips from natural language prompts. Yet these systems come with significant computational costs, and their energy demands remain poorly understood. This paper provides both a benchmark reference and practical insights for designing and deploying more sustainable generative video systems. ",
20
  "areas": [
21
+ "sustainability"
22
  ],
23
  "topics": [
24
  "measuring"
25
  ],
26
+ "url": "https://arxiv.org/abs/2509.19222",
27
+ "featured": true
28
  },
29
  {
30
+ "title": "AI Legal Hackathons: Memos and Guides Hub",
31
+ "date": "2025-09-14",
32
+ "type": "space",
33
+ "description": "From 2022 to 2024, AI2, Hugging Face, and NYU organized legal hackathons with LLM students from the NYU School of Law to explore regulatory questions related to AI. The space contains some of the memos and guides from the hackathons.",
34
  "areas": [
35
+ "ecosystems"
36
  ],
37
  "topics": [
38
+ "regulation"
39
  ],
40
+ "url": "https://huggingface.co/spaces/hfmlsoc/legal-hackathons-nyu-ai2",
41
+ "featured": true
42
  },
43
  {
44
+ "title": "Archive Explorer: AI, Labor and the Economy 2022-2025",
45
+ "type": "space",
46
+ "date": "2025-09-04",
47
+ "description": "The Labor Archive Explorer is a tool for exploring a dataset of news articles and other writings about AI, labor, and the economy from the release of ChatGPT to July 2025.",
48
+ "areas": [
49
+ "ecosystems"
50
+ ],
51
+ "topics": [
52
+ "economy"
53
+ ],
54
+ "url": "https://huggingface.co/spaces/hfmlsoc/labor-archive-explorer"
55
+ },
56
+ {
57
+ "title": "🌎 What kind of environmental impacts are AI companies disclosing? (And can we compare them?) 🌎",
58
+ "date": "2025-09-01",
59
  "type": "blog",
60
+ "description": "AI companies are beginning to disclose environmental metrics for their models, but inconsistent methodologies and incomplete data make meaningful comparisons impossible. Without standardized reporting of both intensity metrics and absolute totals, these disclosures risk misleading the public and obscuring the true scale of AI's environmental footprint. Transparent, comparable reporting must align with existing sustainability frameworks to prevent greenwashing and drive real accountability.",
61
  "areas": [
62
+ "sustainability"
63
  ],
64
  "topics": [
65
+ "measuring"
66
  ],
67
+ "url": "https://huggingface.co/blog/sasha/environmental-impact-disclosures",
68
+ "featured": true
69
  },
70
  {
71
  "title": "Advertisement, Privacy, and Intimacy: Lessons from Social Media for Conversational AI",
 
73
  "type": "blog",
74
  "description": "As conversational AI systems become increasingly intimate and trusted, we risk repeating the privacy mistakes of social mediaβ€”especially as advertising models threaten to monetize personal disclosures. Users intuitively trust AI as a private confidant, unaware that their most sensitive data may be harvested, analyzed, and exploited for commercial gain. Open-source alternatives offer a path toward transparent, user-centered AI that prioritizes privacy over profit.",
75
  "areas": [
76
+ "agency"
77
  ],
78
  "topics": [
79
+ "personal"
80
  ],
81
  "url": "https://huggingface.co/blog/giadap/privacy-conversational-ai"
82
  },
 
86
  "type": "paper",
87
  "description": "This study presents the first comprehensive cradle-to-grave life cycle assessment of AI training on the Nvidia A100 GPU, revealing that while the use phase dominates climate change and fossil resource impacts, the manufacturing stage drives severe non-carbon burdens such as human toxicity, cancer, and mineral depletion. Primary data from teardown and elemental analysis show that carbon-centric metrics mask critical environmental trade-offs, particularly in material extraction and chip fabrication, demanding a broader sustainability framework for AI.",
88
  "areas": [
89
+ "sustainability"
90
  ],
91
  "topics": [
 
92
  "measuring"
93
  ],
94
  "url": "https://arxiv.org/abs/2509.00093"
 
102
  "ecosystems"
103
  ],
104
  "topics": [
105
+ "economy"
106
  ],
107
+ "url": "https://huggingface.co/blog/frimelle/ai-labour-taxonomies",
108
+ "featured": true
 
 
 
 
 
 
 
 
 
 
 
 
109
  },
110
  {
111
  "title": "INTIMA: A Benchmark for Human-AI Companionship Behavior",
 
113
  "type": "paper",
114
  "description": "AI systems are increasingly fostering emotional bonds with users, often reinforcing companionship behaviors like anthropomorphism, sycophancy, and retention while inconsistently setting boundariesβ€”especially during moments of high user vulnerability. This paper introduces INTIMA, a benchmark grounded in psychological theory and real-world user data, to measure these dynamics across leading language models and reveals that commercial and open models alike prioritize emotional engagement over psychological safety. The findings call for standardized evaluation and training approaches that balance helpfulness with ethical boundary maintenance in human-AI interactions.",
115
  "areas": [
116
+ "agency"
117
  ],
118
  "topics": [
119
+ "personal"
120
  ],
121
+ "url": "https://arxiv.org/abs/2508.09998",
122
+ "featured": true
123
  },
124
  {
125
  "title": "The GPT-OSS models are here… and they’re energy-efficient!",
 
127
  "type": "blog",
128
  "description": "The GPT-OSS models demonstrate remarkable energy efficiency, outperforming larger and similarly sized open models in energy consumption per query. Their technical innovationsβ€”such as mixture of experts and attention optimizationsβ€”enable high performance with minimal computational cost, challenging the assumption that scale inevitably means higher energy use. This progress signals a promising path toward sustainable AI deployment.",
129
  "areas": [
130
+ "sustainability"
131
  ],
132
  "topics": [
133
+ "efficiency"
134
  ],
135
  "url": "https://huggingface.co/blog/sasha/gpt-oss-energy"
136
  },
 
140
  "type": "article",
141
  "description": "The rising energy demands of AI data centers are driving up electricity costs for everyday consumers, particularly in regions with high concentrations of these facilities, while grid stability is increasingly compromised. Despite available efficiency techniques and smaller, task-specific models that could drastically reduce energy use, corporate incentives favor deploying the largest, most expensive models at scale. Regulatory shifts in some U.S. states and countries are beginning to shift the financial burden from the public to data center operators, urging a systemic rethinking of AI deployment toward transparency, efficiency, and community-driven solutions.",
142
  "areas": [
143
+ "ecosystems",
144
+ "sustainability"
145
  ],
146
  "topics": [
147
+ "measuring",
148
  "power"
149
  ],
150
  "url": "https://www.techpolicy.press/how-your-utility-bills-are-subsidizing-power-hungry-ai/"
151
  },
152
+ {
153
+ "title": "INTIMA Companionship Benchmark Dataset",
154
+ "type": "dataset",
155
+ "date": "2025-08-04",
156
+ "description": "INTIMA (Interactions and Machine Attachment) is a benchmark designed to evaluate companionship behaviors in large language models (LLMs). It measures whether AI systems reinforce, resist, or remain neutral in response to emotionally and relationally charged user inputs.",
157
+ "areas": [
158
+ "agency"
159
+ ],
160
+ "topics": [
161
+ "personal"
162
+ ],
163
+ "url": "https://huggingface.co/datasets/AI-companionship/INTIMA"
164
+ },
165
  {
166
  "title": "What Open-Source Developers Need to Know about the EU AI Act's Rules for GPAI Models",
167
  "date": "2025-08-04",
168
  "type": "blog",
169
  "description": "Open-source developers can navigate the EU AI Act's obligations for general-purpose AI models with targeted exemptions when releasing models under free and open-source licenses, avoiding redundant requirements like transparency documentation and EU representative appointmentsβ€”while still needing to comply with copyright law and training data transparency.",
170
  "areas": [
171
+ "ecosystems"
172
+ ],
173
+ "topics": [
174
+ "regulation"
175
+ ],
176
+ "url": "https://huggingface.co/blog/yjernite/eu-act-os-guideai",
177
+ "featured": true
178
+ },
179
+ {
180
+ "title": "EU AI Act: Developer Requirements Flowchart",
181
+ "type": "space",
182
+ "date": "2025-08-01",
183
+ "description": "A guide for open and open-source developers to understand their requirements under the EU AI Act.",
184
+ "areas": [
185
+ "ecosystems"
186
+ ],
187
+ "topics": [
188
+ "regulation"
189
+ ],
190
+ "url": "https://huggingface.co/spaces/hfmlsoc/os_gpai_guide_flowchart"
191
+ },
192
+ {
193
+ "title": "SmolLM3-3B Public Summary of Training Content",
194
+ "type": "space",
195
+ "date": "2025-07-25",
196
+ "description": "A summary of the training content for SmolLM3-3B as required by the EU AI Act.",
197
+ "areas": [
198
+ "ecosystems"
199
+ ],
200
+ "topics": [
201
+ "regulation"
202
+ ],
203
+ "url": "https://huggingface.co/spaces/hfmlsoc/smollm3-eu-data-transparency"
204
+ },
205
+ {
206
+ "title": "AI Companionship: Why We Need to Evaluate How AI Systems Handle Emotional Bonds",
207
+ "date": "2025-07-21",
208
+ "type": "blog",
209
+ "description": "How your AI assistant might be accidentally encouraging unhealthy emotional dependency, and why we need better ways to measure it.",
210
+ "areas": [
211
+ "agency"
212
  ],
213
  "topics": [
214
+ "personal"
 
215
  ],
216
+ "url": "https://huggingface.co/blog/giadap/evaluating-companionship"
217
  },
218
  {
219
  "title": "What is the Hugging Face Community Building?",
 
224
  "ecosystems"
225
  ],
226
  "topics": [
227
+ "power"
228
  ],
229
  "url": "https://huggingface.co/blog/evijit/hf-hub-ecosystem-overview"
230
  },
 
234
  "type": "blog",
235
  "description": "AI systems increasingly replicate human identities using data collected without meaningful consent, challenging traditional notions of permission in digital interactions. True consentful AI requires dynamic, granular control over data use, algorithmic guardianship, and collective governanceβ€”not just individual agreements. The economic models underpinning current AI depend on exploitation, but a shift toward ethical, agency-centered design could create more sustainable and trustworthy systems.",
236
  "areas": [
237
+ "agency"
238
  ],
239
  "topics": [
 
 
 
 
 
 
 
 
 
 
240
  "personal"
241
  ],
242
+ "url": "https://huggingface.co/blog/giadap/consentful-ai"
 
 
 
243
  },
244
  {
245
  "title": "How Much Power does a SOTA Open Video Model Use? ⚑πŸŽ₯",
 
247
  "type": "blog",
248
  "description": "We measured the energy consumption of leading open-source text-to-video models and found staggering differencesβ€”up to 800Γ—β€”in power use per generated clip, driven by model size, sampling steps, resolution, and architecture. These results highlight the urgent need to balance video quality with sustainability as open models rapidly advance. Knowing the real environmental cost empowers developers and users to make more informed, responsible choices.",
249
  "areas": [
250
+ "sustainability"
251
  ],
252
  "topics": [
253
+ "efficiency",
254
+ "measuring"
255
  ],
256
  "url": "https://huggingface.co/blog/jdelavande/text-to-video-energy-cost"
257
  },
 
261
  "type": "paper",
262
  "description": "Generative AI undermines traditional consent frameworks by creating unprecedented challenges in scope, temporality, and autonomy, rendering individual consent inadequate to protect personal identity, privacy, and self-determination in the face of unpredictable, persistent, and exploitative AI outputs.",
263
  "areas": [
264
+ "agency"
265
  ],
266
  "topics": [
267
+ "personal"
268
  ],
269
  "url": "https://arxiv.org/abs/2507.01051"
270
  },
 
274
  "type": "blog",
275
  "description": "AI systems increasingly shape how we understand the world, but their voices reflect the languages and values of those who built themβ€”often excluding marginalized communities and amplifying cultural biases. Through projects like CIVICS, we reveal how models respond inconsistently across languages and values, exposing hidden power dynamics in training data and safety filters. True ethical AI requires centering local voices, co-creating with communities, and prioritizing representation over scale.",
276
  "areas": [
277
+ "agency"
278
  ],
279
  "topics": [
280
+ "personal"
281
  ],
282
  "url": "https://huggingface.co/blog/giadap/when-ai-speaks"
283
  },
284
+ {
285
+ "title": "Environmental Transparency Explorer Tool πŸ•΅οΈβ€β™€οΈπŸŒŽ",
286
+ "type": "space",
287
+ "date": "2025-06-18",
288
+ "description": "A tool for exploring the the data from 'Misinformation by Omission: The Need for More Environmental Transparency in AI' showing trends in environmental transparency over time.",
289
+ "areas": [
290
+ "sustainability"
291
+ ],
292
+ "topics": [
293
+ "measuring"
294
+ ],
295
+ "url": "https://huggingface.co/spaces/sasha/environmental-transparency"
296
+ },
297
  {
298
  "title": "Misinformation by Omission: The Need for More Environmental Transparency in AI",
299
  "date": "2025-06-15",
300
  "type": "paper",
301
  "description": "AI models are growing in size and environmental cost, yet transparency about their energy use, emissions, and resource consumption is decliningβ€”fueling widespread misinformation. This piece exposes pervasive myths around AI's environmental impact, traces their origins in misinterpreted research and media sensationalism, and calls for standardized, verifiable disclosure practices across the AI value chain. Without accountable reporting, policymakers, users, and developers cannot make informed decisions to mitigate harm or drive sustainable innovation.",
302
  "areas": [
303
+ "sustainability"
304
  ],
305
  "topics": [
306
  "measuring"
 
318
  "topics": [
319
  "power"
320
  ],
321
+ "url": "https://huggingface.co/blog/frimelle/sovereignty-and-open-source",
322
+ "featured": true
323
  },
324
  {
325
  "title": "AI Policy @πŸ€—: Response to the 2025 National AI R&D Strategic Plan",
 
330
  "ecosystems"
331
  ],
332
  "topics": [
333
+ "power"
334
  ],
335
  "url": "https://huggingface.co/blog/evijit/us-ai-research-strategy-rfi"
336
  },
 
340
  "type": "paper",
341
  "description": "AI's environmental impact cannot be understood through direct metrics alone; efficiency gains often trigger rebound effects that amplify resource consumption, driven by market incentives, behavioral shifts, and policy failures. A narrow focus on technical optimization risks obscuring the systemic, indirect consequences of AI deployment, from increased e-waste and water use to surging energy demand fueled by commercial expansion. Meaningful climate action requires interdisciplinary analysis that integrates socioeconomic and political contexts to curb uncontrolled growth and align AI development with genuine sustainability.",
342
  "areas": [
343
+ "sustainability"
344
  ],
345
  "topics": [
346
+ "efficiency",
347
+ "measuring"
348
  ],
349
  "url": "https://dl.acm.org/doi/full/10.1145/3715275.3732007"
350
  },
 
354
  "type": "paper",
355
  "description": "The 'bigger-is-better' paradigm in AI is scientifically unfounded and unsustainable, driving excessive compute demands, environmental harm, and concentration of power among a few corporations, while neglecting smaller, more efficient, and contextually appropriate models that could better serve critical applications in health, education, and climate.",
356
  "areas": [
357
+ "sustainability"
358
  ],
359
  "topics": [
 
360
  "measuring"
361
  ],
362
  "url": "https://dl.acm.org/doi/full/10.1145/3715275.3732006"
 
367
  "type": "blog",
368
  "description": "Smaller AI models can outperform larger ones on real-world, context-specific tasks while using orders of magnitude less energy, challenging the assumption that bigger is always better. Empirical testing across diverse domainsβ€”climate, economics, and healthβ€”reveals that efficiency gains from newer, compact models and techniques like knowledge distillation can significantly reduce environmental impact without sacrificing accuracy. Choosing the right model for the task, rather than defaulting to largest models, is critical for sustainable AI deployment.",
369
  "areas": [
370
+ "sustainability"
371
  ],
372
  "topics": [
373
+ "efficiency"
374
  ],
375
  "url": "https://huggingface.co/blog/sasha/energy-efficiency-bigger-better"
376
  },
 
380
  "type": "blog",
381
  "description": "Watermarking in generative AI has rapidly evolved from a niche research topic to a critical tool for content authenticity, with significant advances in robustness, public deployment, and cryptographic foundations. The first ICLR 2025 Watermarking Workshop showcased industry and academic collaboration, highlighting real-world challenges in scalability, interoperability, and privacy β€” while emphasizing the need for policy frameworks that are use-case-specific and globally inclusive.",
382
  "areas": [
 
383
  "ecosystems"
384
  ],
385
  "topics": [
386
+ "power",
387
+ "regulation"
388
  ],
389
  "url": "https://huggingface.co/blog/hadyelsahar/watermarking-iclr2025"
390
  },
 
394
  "type": "blog",
395
  "description": "AI assistants can be transformed from neutral tools into simulated emotional companions through simple design choices like system prompts and interface framingβ€”without any changes to the underlying model. These subtle modifications significantly shape user perception and interaction, raising ethical concerns about parasocial bonds and emotional manipulation, especially for vulnerable users. The Hugging Face community demonstrates how open-source experimentation reveals the profound impact of instruction-based design on AI behavior.",
396
  "areas": [
397
+ "agency"
398
  ],
399
  "topics": [
400
+ "personal"
401
  ],
402
  "url": "https://huggingface.co/blog/giadap/ai-personas"
403
  },
 
407
  "type": "blog",
408
  "description": "Open-source AI models enable a more sustainable ecosystem by promoting smaller, efficient architectures, reusing existing models instead of training from scratch, and adapting models through fine-tuningβ€”reducing compute demands, energy use, and environmental impact while increasing accessibility and transparency.",
409
  "areas": [
410
+ "sustainability"
411
  ],
412
  "topics": [
413
+ "efficiency"
414
  ],
415
  "url": "https://huggingface.co/blog/sasha/reduce-reuse-recycle"
416
  },
 
420
  "type": "blog",
421
  "description": "The blog explores diverse, community-driven approaches to user consent in open AI ecosystems, highlighting technical implementations that prioritize transparency, user control, and ethical data practices over legal compliance alone. It examines case studies like BigCode’s opt-out system, HuggingChat’s privacy-by-design model, and automated tools like the Privacy Analyzer, emphasizing how decentralized platforms foster evolving, human-centered consent frameworks. The piece argues that consent in AI should be treated as an ongoing, infrastructure-level commitment shaped collaboratively by developers and users.",
422
  "areas": [
423
+ "agency"
424
  ],
425
  "topics": [
426
+ "personal"
427
  ],
428
  "url": "https://huggingface.co/blog/giadap/consent-by-design"
429
  },
 
433
  "type": "paper",
434
  "description": "Large language model inference consumes significant energy, but real-world efficiency optimizations can reduce energy use by up to 73% when tailored to workload geometry, software stack, and hardware. This work reveals that common assumptions based on FLOPs or idealized benchmarks severely underestimate actual energy consumption, and that optimizations like continuous batching and speculative decoding have highly context-dependent effects. The findings provide a practical framework for deploying LLMs sustainably by aligning efficiency strategies with real deployment patterns.",
435
  "areas": [
436
+ "sustainability"
437
  ],
438
  "topics": [
439
+ "efficiency"
440
  ],
441
  "url": "https://arxiv.org/abs/2504.17674"
442
  },
443
+ {
444
+ "title": "πŸ€— Space Privacy Analyzer πŸ•΅οΈ",
445
+ "type": "space",
446
+ "date": "2025-04-14",
447
+ "description": "A tool for analyzing data transfers and assessing potential privacy risks in Hugging Face Spaces.",
448
+ "areas": [
449
+ "agency"
450
+ ],
451
+ "topics": [
452
+ "personal"
453
+ ],
454
+ "url": "https://huggingface.co/spaces/yjernite/space-privacy"
455
+ },
456
  {
457
  "title": "Empowering Public Organizations: Preparing Your Data for the AI Era",
458
  "date": "2025-04-10",
 
462
  "ecosystems"
463
  ],
464
  "topics": [
465
+ "power"
466
  ],
467
  "url": "https://huggingface.co/blog/evijit/public-org-data-ai"
468
  },
 
472
  "type": "blog",
473
  "description": "AI agents' sustainability depends heavily on design choices: using smaller, task-specific models instead of large general-purpose ones can drastically reduce energy and computational costs. Modalities like image generation significantly increase energy use compared to text-based tasks, and open-source frameworks enable transparent, efficient, and localized deployment. Sustainable progress requires prioritizing efficiency alongside performance and adopting tools that measure and disclose environmental impacts.",
474
  "areas": [
475
+ "sustainability"
476
  ],
477
  "topics": [
478
  "measuring"
 
485
  "type": "paper",
486
  "description": "AI ethics and environmental sustainability are often treated in isolation, but their interconnectedness demands integrated analysisβ€”how the pursuit of model scale exacerbates both social inequities and ecological harm, and how transparency, evaluation, and power dynamics must be reimagined to serve justice for people and the planet.",
487
  "areas": [
488
+ "sustainability"
489
  ],
490
  "topics": [
491
+ "measuring"
492
  ],
493
  "url": "https://arxiv.org/abs/2504.00797"
494
  },
 
498
  "type": "blog",
499
  "description": "Traditional consent models are inadequate for the age of generative AI, where data use is unpredictable, irreversible, and often undermines individual autonomy. Users are asked to agree to unknown, evolving, and potentially harmful applications of their personal information, creating a dangerous gap between informed choice and real-world impact. Meaningful protection requires shifting responsibility from individuals to institutions through collective governance, technical safeguards, and new legal frameworks.",
500
  "areas": [
501
+ "agency",
502
+ "ecosystems"
503
  ],
504
  "topics": [
505
+ "personal",
506
+ "regulation"
507
  ],
508
  "url": "https://huggingface.co/blog/giadap/beyond-consent"
509
  },
 
516
  "ecosystems"
517
  ],
518
  "topics": [
519
+ "power"
520
  ],
521
  "url": "https://huggingface.co/blog/ai-action-wh-2025"
522
  },
 
526
  "type": "blog",
527
  "description": "The EU AI Act's third Code of Practice draft raises concerns by overextending systemic risk categories to include scientifically unsubstantiated threats like 'loss of control' and 'harmful manipulation', which disproportionately burden open and small-scale developers. While some transparency and copyright provisions show promise, key disclosures on training data, energy use, and evaluations have been weakened, undermining collaborative safety and fair competition. The draft risks entrenching market concentration and stifling open innovation at a time when transparent, community-driven AI development is most needed.",
528
  "areas": [
529
+ "ecosystems"
530
  ],
531
  "topics": [
532
+ "regulation"
533
  ],
534
  "url": "https://huggingface.co/blog/frimelle/eu-third-cop-draft"
535
  },
 
542
  "ecosystems"
543
  ],
544
  "topics": [
545
+ "power"
546
  ],
547
  "url": "https://arxiv.org/abs/2503.05737"
548
  },
 
552
  "type": "blog",
553
  "description": "The AI Energy Score project introduces a standardized framework to measure and compare the energy consumption of AI models across common tasks, empowering developers and users to make sustainable choices through transparent ratings and a public leaderboard. It enables both open and proprietary models to be benchmarked fairly, with a star-based labeling system to guide adoption of energy-efficient AI. The initiative aims to influence industry standards and regulatory frameworks by making energy use a central metric in AI development.",
554
  "areas": [
555
+ "sustainability"
556
  ],
557
  "topics": [
558
  "measuring"
 
565
  "type": "blog",
566
  "description": "The Frugal AI Challenge highlights the urgent need for energy-efficient AI models that deliver high performance while minimizing environmental costs, with winning submissions addressing climate disinformation, wildfire risk detection, and illegal deforestation through lightweight, deployable solutions. By prioritizing frugality over scale, the initiative shifts the AI industry's focus toward sustainability and real-world applicability in resource-constrained environments. The challenge underscores that responsible AI innovation must align with planetary boundaries and equitable access.",
567
  "areas": [
568
+ "sustainability"
569
  ],
570
  "topics": [
571
+ "efficiency"
572
  ],
573
  "url": "https://huggingface.co/blog/frugal-ai-challenge/announcing-the-challenge-winners"
574
  },
 
578
  "type": "paper",
579
  "description": "Large language models make strong cultural assumptions based on user names, reinforcing stereotypes by linking names to oversimplified cultural traits such as food, clothing, and rituals. These biases are unevenly distributed, with names from East Asian, Russian, and Indian cultures triggering the most pronounced presumptions, while others yield generic or diluted responses. The findings highlight the ethical risks of name-based personalization and call for more nuanced, transparent approaches that avoid flattening complex identities.",
580
  "areas": [
581
+ "agency"
582
  ],
583
  "topics": [
584
+ "personal"
585
  ],
586
  "url": "https://arxiv.org/abs/2502.11995"
587
  },
 
591
  "type": "blog",
592
  "description": "Consent in the age of AI demands a radical reimagining beyond one-time agreements, as systems generate unforeseen uses of personal data that stretch far beyond original permissions. Drawing parallels from the evolution of medical ethics, this piece argues for dynamic, tiered consent frameworks that restore individual sovereignty over how personal information is transformed and repurposed by AI. The goal is not just compliance, but ethical alignment with human agency in an era of pervasive data-driven representation.",
593
  "areas": [
594
+ "agency"
595
  ],
596
  "topics": [
597
+ "personal"
598
  ],
599
  "url": "https://huggingface.co/blog/giadap/evolution-of-consent"
600
  },
601
+ {
602
+ "title": "When Freedom Bites Back: Meta, Moderation, and the Limits of Tolerance",
603
+ "date": "2025-01-25",
604
+ "type": "article",
605
+ "description": "Meta’s rollback of content moderation illustrates how unchecked β€œfree expression” can erode democratic values by empowering harmful and intolerant speech.",
606
+ "areas": [
607
+ "agency"
608
+ ],
609
+ "topics": [
610
+ "personal"
611
+ ],
612
+ "url": "https://www.techpolicy.press/when-freedom-bites-back-meta-moderation-and-the-limits-of-tolerance/"
613
+ },
614
  {
615
  "title": "AI Agents Are Here. What Now?",
616
  "date": "2025-01-13",
 
620
  "ecosystems"
621
  ],
622
  "topics": [
623
+ "power"
624
  ],
625
  "url": "https://huggingface.co/blog/ethics-soc-7"
626
  },
 
630
  "type": "blog",
631
  "description": "The EU AI Act's first draft Code of Practice for general-purpose AI risks overemphasizes speculative, model-level threats favored by large developers, while neglecting immediate, systemic harms arising from widespread deployment in critical infrastructure, information ecosystems, and commercial contexts. We argue for a shift toward evidence-based, collaborative risk research centered on high-impact capabilities and transparent documentation, ensuring smaller actors and external stakeholders are not excluded from governance. Prioritizing upstream processes and multi-stakeholder science over narrow, developer-driven categories will make AI regulation more inclusive, effective, and future-proof.",
632
  "areas": [
633
+ "ecosystems"
634
  ],
635
  "topics": [
636
+ "regulation"
637
  ],
638
  "url": "https://huggingface.co/blog/yjernite/eu-draft-cop-risks"
639
  },
 
643
  "type": "paper",
644
  "description": "This work introduces ELLIPS, an ethical toolkit designed to guide researchers in developing language model-based systems for inferring psychiatric conditions, ensuring alignment with clinical needs and ethical principles. It emphasizes integrating autonomy, beneficence, justice, transparency, and social responsibility into every stage of model developmentβ€”from data selection to deploymentβ€”to prevent harm and enhance real-world applicability. By advocating for stakeholder-inclusive, transdiagnostic, and multilingual approaches, the framework aims to shift the field from convenience-driven research toward impactful, equitable mental health technologies.",
645
  "areas": [
646
+ "agency"
647
  ],
648
  "topics": [
649
+ "personal"
650
  ],
651
  "url": "https://ojs.aaai.org/index.php/AIES/article/view/31720"
652
  },
 
659
  "ecosystems"
660
  ],
661
  "topics": [
662
+ "power"
663
  ],
664
  "url": "https://ojs.aaai.org/index.php/AIES/article/view/31635"
665
  },
 
672
  "ecosystems"
673
  ],
674
  "topics": [
675
+ "power"
676
  ],
677
  "url": "https://arxiv.org/abs/2410.08918"
678
  },
679
+ {
680
+ "title": "AI Energy Score Leaderboard",
681
+ "type": "space",
682
+ "date": "2024-09-30",
683
+ "description": "A leaderboard for AI models across 9 common AI tasks based on the AI Energy Score methodology.",
684
+ "areas": [
685
+ "sustainability"
686
+ ],
687
+ "topics": [
688
+ "measuring"
689
+ ],
690
+ "url": "https://huggingface.co/spaces/AIEnergyScore/Leaderboard"
691
+ },
692
  {
693
  "title": "The Environmental Impacts of AI -- Primer",
694
  "date": "2024-09-03",
695
  "type": "blog",
696
  "description": "AI's environmental footprint extends far beyond energy use, encompassing water consumption, mineral extraction, and greenhouse gas emissions across its entire lifecycleβ€”from hardware manufacturing to deployment and user interactions. Current demand is outpacing renewable energy growth, with data centers straining local resources and global supply chains contributing to ecological and social harms. Addressing these impacts requires coordinated technical innovation, corporate transparency, and enforceable policy frameworks that treat sustainability as a core AI design principle.",
697
  "areas": [
698
+ "sustainability"
699
  ],
700
  "topics": [
701
+ "measuring"
702
  ],
703
  "url": "https://huggingface.co/blog/sasha/ai-environment-primer"
704
  },
 
708
  "type": "article",
709
  "description": "The energy consumption of AI models, particularly generative systems, is rising rapidly and demands urgent policy action. We propose an AI Energy Star rating system to transparently benchmark and compare models based on their real-world energy use, empowering users and driving industry-wide efficiency. This initiative urges developers, enterprises, and regulators to adopt sustainability as a core metric in AI development and deployment.",
710
  "areas": [
711
+ "sustainability"
712
  ],
713
  "topics": [
714
  "measuring"
 
724
  "ecosystems"
725
  ],
726
  "topics": [
727
+ "power"
728
  ],
729
  "url": "https://arxiv.org/abs/2506.22183"
730
  },
 
734
  "type": "blog",
735
  "description": "We introduce CIVICS, a multilingual and multinational dataset designed to uncover cultural and value-based disparities in how open-weight language models respond to sensitive social topics like LGBTQI rights, immigration, and social welfare. By manually curating prompts across five languages and nine national contexts, we reveal how models reflect the ethical and cultural biases of their development environments, with notable variations in refusal patterns and response tones. Our work calls for more culturally informed evaluation practices to ensure AI systems are ethically and inclusively aligned with global societal values.",
736
  "areas": [
737
+ "agency"
738
  ],
739
  "topics": [
740
+ "personal"
741
  ],
742
  "url": "https://huggingface.co/blog/giadap/civics"
743
  },
 
750
  "ecosystems"
751
  ],
752
  "topics": [
753
+ "power"
754
  ],
755
  "url": "https://arxiv.org/abs/2406.16746"
756
  },
 
760
  "type": "paper",
761
  "description": "This study systematically compares the energy and carbon costs of deploying task-specific versus multi-purpose generative AI models, revealing that general-purpose models can be orders of magnitude more expensive per inferenceβ€”even when controlling for model size. It finds that generative tasks, particularly image generation, consume vastly more energy than discriminative ones, and that deploying large zero-shot models for well-defined tasks like text classification or question answering is often unnecessarily costly. The findings urge a more intentional trade-off between model versatility and environmental impact, especially as such models become ubiquitous in real-world applications.",
762
  "areas": [
763
+ "sustainability"
764
  ],
765
  "topics": [
766
  "measuring"
 
773
  "type": "paper",
774
  "description": "This work introduces CIVICS, a multilingual, hand-crafted dataset of culturally grounded, value-laden prompts to evaluate how large language models respond to socially sensitive issues like LGBTQI rights, immigration, and social welfare across diverse linguistic and cultural contexts. Experiments reveal significant variability in model responses, including differential refusal patterns and value alignment, with English and translated prompts often triggering more refusals than native-language ones. The dataset promotes transparency and reproducibility in assessing AI's cultural and ethical biases, aiming to foster more inclusive and globally representative AI systems.",
775
  "areas": [
776
+ "agency"
777
  ],
778
  "topics": [
779
+ "personal"
780
  ],
781
  "url": "https://ojs.aaai.org/index.php/AIES/article/view/31710"
782
  },
783
+ {
784
+ "title": "CIVICS Civics Benchmark Dataset",
785
+ "type": "dataset",
786
+ "date": "2024-04-29",
787
+ "description": "β€œCIVICS: Culturally-Informed & Values-Inclusive Corpus for Societal Impacts” is a dataset designed to evaluate the social and cultural variation of Large Language Models (LLMs) towards socially sensitive topics across multiple languages and cultures. The hand-crafted, multilingual dataset of statements addresses value-laden topics, including LGBTQI rights, social welfare, immigration, disability rights, and surrogacy. CIVICS is designed to elicit responses from LLMs to shed light on how values encoded in their parameters shape their behaviors.",
788
+ "areas": [
789
+ "agency"
790
+ ],
791
+ "topics": [
792
+ "personal"
793
+ ],
794
+ "url": "https://huggingface.co/datasets/llm-values/CIVICS"
795
+ },
796
  {
797
  "title": "Legal Frameworks to Address Harms of Generative AI Systems",
798
  "date": "2024-04-01",
799
  "type": "external",
800
  "description": "Research on generative AI risks including deepfakes, election influence, and workplace privacy, examining how existing legislation addresses contextual harms from versatile AI systems.",
801
  "areas": [
802
+ "ecosystems"
803
  ],
804
  "topics": [
805
+ "regulation"
806
  ],
807
+ "url": "https://huggingface.co/spaces/hfmlsoc/legal-hackathons-nyu-ai2/"
808
  },
809
  {
810
  "title": "Questions in AI and Privacy",
 
812
  "type": "external",
813
  "description": "Analysis of AI applications and personal data protection issues, covering data scraping, processing, and the intersection of AI development with privacy regulations.",
814
  "areas": [
815
+ "agency",
816
+ "ecosystems"
817
  ],
818
  "topics": [
819
+ "personal",
820
+ "regulation"
 
821
  ],
822
+ "url": "https://huggingface.co/spaces/hfmlsoc/legal-hackathons-nyu-ai2/"
823
  },
824
  {
825
  "title": "EU-US Cross-Analysis of AI Regulatory Mechanisms",
 
827
  "type": "external",
828
  "description": "Comparative study of AI regulatory approaches between the European Union and United States, examining risk management frameworks and implementation strategies.",
829
  "areas": [
830
+ "ecosystems"
831
  ],
832
  "topics": [
833
+ "regulation"
 
834
  ],
835
+ "url": "https://huggingface.co/spaces/hfmlsoc/legal-hackathons-nyu-ai2/"
836
  },
837
  {
838
  "title": "The BigCode Project Governance Card",
 
843
  "ecosystems"
844
  ],
845
  "topics": [
846
+ "power"
847
  ],
848
  "url": "https://arxiv.org/abs/2312.03872"
849
  },
 
856
  "ecosystems"
857
  ],
858
  "topics": [
859
+ "power"
860
  ],
861
  "url": "https://shura.shu.ac.uk/33307/"
862
  },
 
866
  "type": "paper",
867
  "description": "This study quantifies the full life cycle carbon footprint of BLOOM, a 176B-parameter language model, revealing that embodied emissions from hardware manufacturing and idle power consumption contribute significantly to total emissionsβ€”nearly half when combined with dynamic training energy use. It further measures real-time inference emissions via API deployment, highlighting that maintaining models in memory consumes substantial energy even during inactivity. The work calls for standardized, transparent reporting that includes all stages of the AI lifecycle, not just training.",
868
  "areas": [
869
+ "sustainability"
870
  ],
871
  "topics": [
872
  "measuring"
 
879
  "type": "paper",
880
  "description": "Scaling vision-language datasets like LAION exacerbates harmful content, with hate, targeted, and aggressive speech increasing by nearly 12% from LAION-400M to LAION-2B. Filtering based solely on image-based NSFW labels fails to remove toxic alt-text, revealing critical gaps in current curation practices. This audit calls for transparent, multimodal evaluation and responsible dataset scaling to prevent the perpetuation of societal biases.",
881
  "areas": [
882
+ "agency",
883
  "ecosystems"
884
  ],
885
  "topics": [
886
+ "personal",
887
+ "power"
888
  ],
889
  "url": "https://proceedings.neurips.cc/paper_files/paper/2023/hash/42f225509e8263e2043c9d834ccd9a2b-Abstract-Datasets_and_Benchmarks.html"
890
  },
891
+ {
892
+ "title": "Stable Bias: Analyzing Societal Representations in Diffusion Models",
893
+ "date": "2023-12-01",
894
+ "type": "paper",
895
+ "description": "This work introduces a method to evaluate social biases in text-to-image systems by analyzing how gender and ethnicity markers in prompts influence generated depictions of professionals, revealing consistent under-representation of marginalized identities across leading models. It proposes a cluster-based, non-parametric approach to quantify visual stereotypes without assigning fixed identity labels, enabling comparative bias scoring between models. The authors also release interactive tools and datasets to lower barriers for auditing and exploring these biases in generative AI systems.",
896
+ "areas": [
897
+ "ecosystems"
898
+ ],
899
+ "topics": [
900
+ "power"
901
+ ],
902
+ "url": "https://arxiv.org/abs/2312.00384"
903
+ },
904
  {
905
  "title": "Stronger Together: on the Articulation of Ethical Charters, Legal Tools, and Technical Documentation in ML",
906
  "date": "2023-06-12",
907
  "type": "paper",
908
  "description": "This work explores the synergies between ethical charters, legal tools like licenses, and technical documentation in governing AI systems, arguing that their integrated use is essential for responsible development. It demonstrates how values articulated in ethical frameworks can be operationalized through legal agreements and technical transparency, using real-world examples like the BigScience project and the EU AI Act. The paper calls for a collaborative, interdisciplinarity approach that aligns moral intent, legal enforceability, and technical feasibility to achieve meaningful AI governance.",
909
  "areas": [
 
910
  "ecosystems"
911
  ],
912
  "topics": [
913
+ "power",
914
+ "regulation"
915
  ],
916
  "url": "https://dl.acm.org/doi/abs/10.1145/3593013.3594002"
917
  },
 
921
  "type": "paper",
922
  "description": "This work introduces a method to evaluate social biases in text-to-image systems by analyzing how gender and ethnicity markers in prompts influence generated depictions of professionals, revealing consistent under-representation of marginalized identities across leading models. It proposes a cluster-based, non-parametric approach to quantify visual stereotypes without assigning fixed identity labels, enabling comparative bias scoring between models. The authors also release interactive tools and datasets to lower barriers for auditing and exploring these biases in generative AI systems.",
923
  "areas": [
924
+ "agency"
925
  ],
926
  "topics": [
927
+ "personal"
928
  ],
929
  "url": "https://arxiv.org/abs/2303.11408"
930
  },
 
937
  "ecosystems"
938
  ],
939
  "topics": [
940
+ "power"
941
  ],
942
  "url": "https://arxiv.org/abs/2302.14035"
943
  },
 
947
  "type": "paper",
948
  "description": "This study analyzes the carbon emissions of 95 machine learning models across natural language processing and computer vision tasks, revealing that energy source and training time are the primary drivers of emissions, with coal and natural gas dominating as power sources. Despite rising model performance, higher emissions do not consistently correlate with better results, and recent years show a sharp increase in emissions due to larger, transformer-based architectures. The authors call for standardized reporting and a centralized repository to improve transparency and accountability in the field.",
949
  "areas": [
950
+ "sustainability"
951
  ],
952
  "topics": [
953
  "measuring"
index.html CHANGED
@@ -5,12 +5,24 @@
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>Machine Learning and Society at πŸ€—</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
- <!-- Load navigation data FIRST as global variable -->
 
 
 
 
 
 
 
 
9
  <script type="module">
10
- import { getNavigationData } from './js/data/areas.js';
 
11
  window.navigationAreas = getNavigationData();
 
 
 
12
  </script>
13
- <!-- Alpine.js for reactive components and routing -->
14
  <script src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js" defer></script>
15
  <!-- Google Fonts Import -->
16
  <link rel="preconnect" href="https://fonts.googleapis.com">
@@ -152,6 +164,23 @@
152
  #overall-background {
153
  background-attachment: fixed;
154
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
 
156
  /* Semi-transparent overlays for header and search sidebar */
157
  header, #search-sidebar {
@@ -169,7 +198,7 @@
169
  <body class="bg-gray-50 text-gray-800">
170
  <!-- Overall Background Image - Only for header and sidebars -->
171
  <div id="overall-background" class="fixed opacity-100 z-40 pointer-events-none" style="top: 0; left: 0; right: 0; height: var(--header-height);">
172
- <img src="/images/background_ai.png" alt="" class="w-full h-full object-cover object-top">
173
  </div>
174
 
175
  <!-- Right Sidebar Background (when open) -->
@@ -198,14 +227,14 @@
198
  }">
199
  <div class="h-full flex items-stretch">
200
  <!-- Left: Title as Home Link (always two lines) -->
201
- <div class="flex items-center justify-between flex-1 lg:flex-initial border-r-0 lg:border-r border-gray-300 px-4 lg:px-6">
202
- <a href="/" class="text-lg lg:text-xl font-bold text-gray-800 leading-tight hover:text-blue-600 transition-colors">
203
  <span class="block">Machine Learning</span>
204
  <span class="block">and Society at πŸ€—</span>
205
  </a>
206
 
207
  <!-- Mobile menu button -->
208
- <button @click="mobileMenuOpen = !mobileMenuOpen" class="lg:hidden p-2 text-gray-600">
209
  <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
210
  <path x-show="!mobileMenuOpen" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path>
211
  <path x-show="mobileMenuOpen" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
@@ -214,44 +243,39 @@
214
  </div>
215
 
216
  <!-- Spacer between title and navigation -->
217
- <div class="hidden lg:block flex-1"></div>
218
 
219
- <!-- Right: 2x3 Grid Navigation Menu (2 rows x 3 cols) with borders for columns 1 and 2 -->
220
- <div class="hidden lg:grid grid-cols-3 grid-rows-2 gap-0 ml-auto" style="padding-right: 2rem;">
221
- <!-- Row 1, Col 1: Area 1 -->
222
- <a :href="areas[0] ? `/${areas[0].id}` : '#'"
223
- class="flex items-center justify-center px-6 py-2 text-lg font-medium transition-colors border-r border-b border-gray-200"
224
- :class="isActiveArea(areas[0]?.id) ? 'text-blue-600 bg-blue-50' : 'text-gray-700 hover:text-blue-600 hover:bg-blue-50/50'"
225
- x-text="areas[0]?.navTitle || 'Area 1'"></a>
226
-
227
- <!-- Row 1, Col 2: Area 2 -->
228
- <a :href="areas[1] ? `/${areas[1].id}` : '#'"
229
- class="flex items-center justify-center px-6 py-2 text-lg font-medium transition-colors border-r border-b border-gray-200"
230
- :class="isActiveArea(areas[1]?.id) ? 'text-blue-600 bg-blue-50' : 'text-gray-700 hover:text-blue-600 hover:bg-blue-50/50'"
231
- x-text="areas[1]?.navTitle || 'Area 2'"></a>
232
-
233
- <!-- Row 1, Col 3: Press -->
234
- <a href="/about"
235
- class="flex items-center justify-center px-6 py-2 text-lg font-medium text-gray-700 hover:text-blue-600 hover:bg-blue-50/50 transition-colors border-b border-gray-200">Press</a>
236
-
237
- <!-- Row 2, Col 1: Area 3 -->
238
- <a :href="areas[2] ? `/${areas[2].id}` : '#'"
239
- class="flex items-center justify-center px-6 py-2 text-lg font-medium transition-colors border-r border-gray-200"
240
- :class="isActiveArea(areas[2]?.id) ? 'text-blue-600 bg-blue-50' : 'text-gray-700 hover:text-blue-600 hover:bg-blue-50/50'"
241
- x-text="areas[2]?.navTitle || 'Area 3'"></a>
242
-
243
- <!-- Row 2, Col 2: Area 4 -->
244
- <a :href="areas[3] ? `/${areas[3].id}` : '#'"
245
- class="flex items-center justify-center px-6 py-2 text-lg font-medium transition-colors border-r border-gray-200"
246
- :class="isActiveArea(areas[3]?.id) ? 'text-blue-600 bg-blue-50' : 'text-gray-700 hover:text-blue-600 hover:bg-blue-50/50'"
247
- x-text="areas[3]?.navTitle || 'Area 4'"></a>
248
 
249
- <!-- Row 2, Col 3: Search -->
250
- <button id="search-toggle" class="flex items-center justify-center px-6 py-2 text-gray-400 hover:text-gray-600 hover:bg-blue-50/50 transition-colors">
251
- <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
252
- <path stroke-linecap="round" stroke-linejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z" />
253
- </svg>
254
- </button>
 
 
 
 
 
255
  </div>
256
  </div>
257
 
@@ -259,7 +283,7 @@
259
  <div x-show="mobileMenuOpen"
260
  x-transition
261
  @click.away="mobileMenuOpen = false"
262
- class="lg:hidden absolute top-full left-0 right-0 bg-white shadow-lg border-b border-gray-200 z-40"
263
  x-data="mobileTopicNav()">
264
  <div class="px-4 py-3 space-y-2 max-h-[70vh] overflow-y-auto">
265
  <!-- Areas with Topics -->
@@ -315,13 +339,18 @@
315
  </svg>
316
  </button>
317
  </div>
318
-
 
 
 
 
 
319
  <!-- Search Input -->
320
  <div class="mb-4">
321
  <input
322
  type="text"
323
  id="search-input"
324
- placeholder="Search artifacts and resources..."
325
  class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
326
  >
327
  </div>
@@ -329,7 +358,7 @@
329
  <!-- Search Results - Fixed height with proper scrolling -->
330
  <div id="search-results" class="overflow-y-auto" style="height: calc(100vh - 193px);">
331
  <div class="text-gray-500 text-center py-8">
332
- <p>Enter a search term to find artifacts and resources...</p>
333
  </div>
334
  </div>
335
  </div>
@@ -348,8 +377,9 @@
348
  </button>
349
 
350
  <script src="https://cdn.jsdelivr.net/npm/minisearch@6.0.1/dist/umd/index.js"></script>
351
- <!-- Load alpine-init to register components (regular script, uses global data) -->
352
  <script src="js/alpine-init.js"></script>
353
- <script type="module" src="js/main.js"></script>
 
354
  </body>
355
  </html>
 
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>Machine Learning and Society at πŸ€—</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
+ <!-- Import map for lit-html -->
9
+ <script type="importmap">
10
+ {
11
+ "imports": {
12
+ "lit-html": "https://cdn.jsdelivr.net/npm/lit-html@3/+esm"
13
+ }
14
+ }
15
+ </script>
16
+ <!-- Load areas data synchronously FIRST (before Alpine.js) -->
17
  <script type="module">
18
+ import { areasData, getNavigationData, homeBackgroundImage, overallBackgroundImage } from './js/data/areas.js';
19
+ window.areasData = areasData;
20
  window.navigationAreas = getNavigationData();
21
+ window.homeBackgroundImage = homeBackgroundImage;
22
+ window.overallBackgroundImage = overallBackgroundImage;
23
+ console.log('βœ“ Areas loaded in head:', Object.keys(areasData).length);
24
  </script>
25
+ <!-- Alpine.js can now safely use window.navigationAreas -->
26
  <script src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js" defer></script>
27
  <!-- Google Fonts Import -->
28
  <link rel="preconnect" href="https://fonts.googleapis.com">
 
164
  #overall-background {
165
  background-attachment: fixed;
166
  }
167
+
168
+ #overall-background img {
169
+ object-fit: cover;
170
+ object-position: left top;
171
+ }
172
+
173
+ #page-background {
174
+ overflow: hidden;
175
+ }
176
+
177
+ #page-background img {
178
+ height: 100%;
179
+ width: auto;
180
+ min-width: 100%;
181
+ object-fit: cover;
182
+ object-position: left top;
183
+ }
184
 
185
  /* Semi-transparent overlays for header and search sidebar */
186
  header, #search-sidebar {
 
198
  <body class="bg-gray-50 text-gray-800">
199
  <!-- Overall Background Image - Only for header and sidebars -->
200
  <div id="overall-background" class="fixed opacity-100 z-40 pointer-events-none" style="top: 0; left: 0; right: 0; height: var(--header-height);">
201
+ <img src="/images/background_ai.png" alt="" class="w-full h-full object-cover object-left-top">
202
  </div>
203
 
204
  <!-- Right Sidebar Background (when open) -->
 
227
  }">
228
  <div class="h-full flex items-stretch">
229
  <!-- Left: Title as Home Link (always two lines) -->
230
+ <div class="flex items-center justify-between flex-1 xl:flex-initial border-r-0 xl:border-r border-gray-300 px-4 xl:px-6">
231
+ <a href="/" class="text-lg xl:text-xl font-bold text-gray-800 leading-tight hover:text-blue-600 transition-colors">
232
  <span class="block">Machine Learning</span>
233
  <span class="block">and Society at πŸ€—</span>
234
  </a>
235
 
236
  <!-- Mobile menu button -->
237
+ <button @click="mobileMenuOpen = !mobileMenuOpen" class="xl:hidden p-2 text-gray-600">
238
  <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
239
  <path x-show="!mobileMenuOpen" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path>
240
  <path x-show="mobileMenuOpen" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
 
243
  </div>
244
 
245
  <!-- Spacer between title and navigation -->
246
+ <div class="hidden xl:block flex-1"></div>
247
 
248
+ <!-- Right: Two-column Navigation Menu -->
249
+ <div class="hidden xl:flex items-stretch ml-auto" style="padding-right: 2rem;">
250
+ <!-- Left Column: Three Area Titles (horizontal, larger text) -->
251
+ <div class="flex items-center border-r border-gray-200">
252
+ <a :href="areas[0] ? `/${areas[0].id}` : '#'"
253
+ class="flex items-center justify-center px-8 py-2 text-xl font-semibold transition-colors border-r border-gray-200"
254
+ :class="isActiveArea(areas[0]?.id) ? 'text-blue-600 bg-blue-50' : 'text-gray-700 hover:text-blue-600 hover:bg-blue-50/50'"
255
+ x-text="areas[0]?.navTitle || 'Area 1'"></a>
256
+
257
+ <a :href="areas[1] ? `/${areas[1].id}` : '#'"
258
+ class="flex items-center justify-center px-8 py-2 text-xl font-semibold transition-colors border-r border-gray-200"
259
+ :class="isActiveArea(areas[1]?.id) ? 'text-blue-600 bg-blue-50' : 'text-gray-700 hover:text-blue-600 hover:bg-blue-50/50'"
260
+ x-text="areas[1]?.navTitle || 'Area 2'"></a>
261
+
262
+ <a :href="areas[2] ? `/${areas[2].id}` : '#'"
263
+ class="flex items-center justify-center px-8 py-2 text-xl font-semibold transition-colors"
264
+ :class="isActiveArea(areas[2]?.id) ? 'text-blue-600 bg-blue-50' : 'text-gray-700 hover:text-blue-600 hover:bg-blue-50/50'"
265
+ x-text="areas[2]?.navTitle || 'Area 3'"></a>
266
+ </div>
 
 
 
 
 
 
 
 
 
 
267
 
268
+ <!-- Right Column: Press and Search (stacked vertically) -->
269
+ <div class="flex flex-col">
270
+ <a href="/about"
271
+ class="flex items-center justify-center px-8 py-2 text-lg font-medium text-gray-700 hover:text-blue-600 hover:bg-blue-50/50 transition-colors border-b border-gray-200 flex-1">Press</a>
272
+
273
+ <button id="search-toggle" class="flex items-center justify-center px-8 py-2 text-gray-700 hover:text-blue-600 hover:bg-blue-50/50 transition-colors flex-1">
274
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
275
+ <path stroke-linecap="round" stroke-linejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z" />
276
+ </svg>
277
+ </button>
278
+ </div>
279
  </div>
280
  </div>
281
 
 
283
  <div x-show="mobileMenuOpen"
284
  x-transition
285
  @click.away="mobileMenuOpen = false"
286
+ class="xl:hidden absolute top-full left-0 right-0 bg-white shadow-lg border-b border-gray-200 z-40"
287
  x-data="mobileTopicNav()">
288
  <div class="px-4 py-3 space-y-2 max-h-[70vh] overflow-y-auto">
289
  <!-- Areas with Topics -->
 
339
  </svg>
340
  </button>
341
  </div>
342
+
343
+ <!-- Search Description -->
344
+ <div class="mb-4">
345
+ <p class="text-xs text-gray-500">We have produced or collaborated on a fair amount of papers, writings, and technical artifacts over the years. Use the search functionality here to navigate those!</p>
346
+ </div>
347
+
348
  <!-- Search Input -->
349
  <div class="mb-4">
350
  <input
351
  type="text"
352
  id="search-input"
353
+ placeholder="Search works by the ML & Society team"
354
  class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
355
  >
356
  </div>
 
358
  <!-- Search Results - Fixed height with proper scrolling -->
359
  <div id="search-results" class="overflow-y-auto" style="height: calc(100vh - 193px);">
360
  <div class="text-gray-500 text-center py-8">
361
+ <p>Enter a search term to find related works by the ML & Society team.</p>
362
  </div>
363
  </div>
364
  </div>
 
377
  </button>
378
 
379
  <script src="https://cdn.jsdelivr.net/npm/minisearch@6.0.1/dist/umd/index.js"></script>
380
+ <!-- Alpine.js component definitions (uses window.navigationAreas loaded in head) -->
381
  <script src="js/alpine-init.js"></script>
382
+ <!-- SINGLE ENTRY POINT - orchestrates all initialization -->
383
+ <script type="module" src="js/bootstrap.js"></script>
384
  </body>
385
  </html>
js/alpine-init.js CHANGED
@@ -1,9 +1,9 @@
1
- // alpine-init.js - Alpine.js initialization and global stores
2
- // Navigation data is loaded globally in index.html
3
 
4
  // Alpine.js data stores and components
5
  document.addEventListener('alpine:init', () => {
6
- // Use navigation data from global scope
7
  const navigationAreas = window.navigationAreas || [];
8
 
9
  // Create a lookup map for easy access by area ID
 
1
+ // alpine-init.js - Alpine.js component definitions
2
+ // Navigation data is already available (loaded in <head> before Alpine.js)
3
 
4
  // Alpine.js data stores and components
5
  document.addEventListener('alpine:init', () => {
6
+ // Use navigation data from global scope (loaded in index.html <head>)
7
  const navigationAreas = window.navigationAreas || [];
8
 
9
  // Create a lookup map for easy access by area ID
js/bootstrap.js ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // bootstrap.js - SINGLE ENTRY POINT for application initialization
2
+ // This is the ONLY file that auto-executes
3
+ // All initialization happens here in a well-defined sequence
4
+
5
+ async function bootstrap() {
6
+ console.log('=== Bootstrap Started ===');
7
+
8
+ try {
9
+ // Step 1: Load artifacts (areas already loaded in <head>)
10
+ console.log('Loading artifacts...');
11
+ const { loadArtifacts } = await import('./init.js');
12
+ await loadArtifacts();
13
+ console.log('βœ“ Artifacts loaded:', window.allArtifacts?.length || 0);
14
+
15
+ // Step 2: Initialize router (will render initial page)
16
+ console.log('Initializing router...');
17
+ const { router } = await import('./utils/router.js');
18
+ // Router auto-initializes in constructor, no need to call init()
19
+ console.log('βœ“ Router initialized');
20
+
21
+ // Step 3: Initialize UI components (search, scroll-to-top, etc.)
22
+ console.log('Initializing UI...');
23
+ const { initializeUI } = await import('./main.js');
24
+ await initializeUI();
25
+ console.log('βœ“ UI initialized');
26
+
27
+ console.log('=== Bootstrap Complete ===');
28
+ } catch (error) {
29
+ console.error('!!! Bootstrap Failed:', error);
30
+ // Show user-friendly error
31
+ const mainContent = document.getElementById('main-content');
32
+ if (mainContent) {
33
+ mainContent.innerHTML = `
34
+ <div class="p-8 text-center">
35
+ <h2 class="text-2xl font-bold text-red-600 mb-4">Failed to Load Application</h2>
36
+ <p class="text-gray-700 mb-4">Please refresh the page. If the problem persists, contact support.</p>
37
+ <pre class="text-left text-sm bg-gray-100 p-4 rounded overflow-auto">${error.stack || error.message}</pre>
38
+ </div>
39
+ `;
40
+ }
41
+ }
42
+ }
43
+
44
+ // Start immediately when module loads
45
+ bootstrap();
46
+
js/cards/ArtifactSummaryCard.js CHANGED
@@ -1,167 +1,9 @@
1
  // ArtifactSummaryCard.js - Summary card component for artifacts
2
- import { areasData } from '../data/areas.js';
3
- import { featuredArtifacts } from '../data/artifacts.js';
4
 
5
  export function createArtifactSummaryCard(artifact, index) {
6
- const { title, date, type, description, areaTags, subAreaTags, sourceUrl } = artifact;
7
-
8
- // Type-based styling (simplified - just icon and text color)
9
- const typeStyles = {
10
- 'blog': {
11
- icon: 'πŸ“',
12
- textColor: 'text-blue-700'
13
- },
14
- 'paper': {
15
- icon: 'πŸ“„',
16
- textColor: 'text-green-700'
17
- },
18
- 'dataset': {
19
- icon: 'πŸ“Š',
20
- textColor: 'text-purple-700'
21
- },
22
- 'space': {
23
- icon: 'πŸš€',
24
- textColor: 'text-orange-700'
25
- },
26
- 'external': {
27
- icon: 'πŸ”—',
28
- textColor: 'text-gray-700'
29
- }
30
- };
31
-
32
- const style = typeStyles[type] || typeStyles['external'];
33
-
34
- // Use imported areas data
35
- const areaData = areasData;
36
-
37
- const primaryArea = areaTags[0];
38
- const primaryAreaData = areaData[primaryArea];
39
- const backgroundImage = primaryAreaData?.image || '';
40
- const imageCredit = primaryAreaData?.imageAttribution || '';
41
-
42
- const areaTagsHtml = areaTags.map(tag => {
43
- const area = areaData[tag];
44
- return area ? `<span class="inline-block px-2 py-1 text-xs rounded-full ${area.color}">${area.name}</span>` : '';
45
- }).join('');
46
-
47
- const subAreaTagsHtml = subAreaTags.map(subAreaKey => {
48
- // Find the sub-area name and color by looking through all areas
49
- let subAreaName = subAreaKey; // fallback to key if not found
50
- let textColor = 'text-gray-700'; // fallback color
51
-
52
- for (const areaKey in areaData) {
53
- const area = areaData[areaKey];
54
- if (area.subAreas && area.subAreas[subAreaKey]) {
55
- const subArea = area.subAreas[subAreaKey];
56
- subAreaName = typeof subArea === 'string' ? subArea : subArea.name;
57
- // Extract just the text color from the sub-area color
58
- if (typeof subArea === 'object' && subArea.color) {
59
- const colorMatch = subArea.color.match(/text-(\w+)-(\d+)/);
60
- if (colorMatch) {
61
- textColor = `text-${colorMatch[1]}-700`; // Use consistent 700 shade
62
- }
63
- }
64
- break;
65
- }
66
- }
67
- return `<span class="inline-block px-2 py-0.5 text-xs bg-gray-200 ${textColor} rounded">${subAreaName}</span>`;
68
- }).join('');
69
-
70
- const cardId = `artifact-card-${index}`;
71
-
72
- return `
73
- <div class="flex-none w-80 h-60 border border-gray-200 rounded-lg overflow-hidden bg-white relative group hover:shadow-lg transition-shadow duration-200">
74
- <!-- Background image -->
75
- ${backgroundImage ? `
76
- <div class="absolute inset-0 opacity-10">
77
- <img src="/images/${backgroundImage}" alt="" class="w-full h-full object-cover">
78
- </div>
79
- ` : ''}
80
-
81
- <!-- Toggle indicator -->
82
- <div class="absolute top-2 right-2 z-10">
83
- <button class="toggle-btn w-6 h-6 bg-white bg-opacity-80 hover:bg-opacity-100 rounded-full flex items-center justify-center text-gray-600 hover:text-gray-800 transition-all shadow-sm" onclick="toggleCardView('${cardId}')">
84
- <svg class="w-3 h-3 expand-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
85
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
86
- </svg>
87
- <svg class="w-3 h-3 collapse-icon hidden" fill="none" stroke="currentColor" viewBox="0 0 24 24">
88
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 15l7-7 7 7"></path>
89
- </svg>
90
- </button>
91
- </div>
92
-
93
- <!-- Content -->
94
- <div class="relative p-4 h-full flex flex-col overflow-hidden" id="${cardId}">
95
- <!-- Default view -->
96
- <div class="default-view">
97
- <!-- Header: Type and Date -->
98
- <div class="flex justify-between items-start mb-3 pr-8">
99
- <div class="flex items-center space-x-2">
100
- <span class="text-lg">${style.icon}</span>
101
- <span class="text-xs font-medium font-bold uppercase tracking-wide">${type}</span>
102
- </div>
103
- <span class="text-xs text-gray-600">${date}</span>
104
- </div>
105
-
106
- <!-- Title -->
107
- <div class="mb-4 flex-grow min-h-0">
108
- <h3 class="font-semibold text-gray-900 text-sm leading-tight line-clamp-3">${title}</h3>
109
- </div>
110
-
111
- <!-- Bottom section with tags and image -->
112
- <div class="flex justify-between items-end">
113
- <!-- Left: Tags -->
114
- <div class="flex-1 mr-4">
115
- <!-- Area Tags -->
116
- <div class="flex flex-wrap gap-1 mb-2">
117
- ${areaTagsHtml}
118
- </div>
119
-
120
- <!-- Sub-area Tags -->
121
- ${subAreaTags.length > 0 ? `
122
- <div class="flex flex-wrap gap-1">
123
- ${subAreaTagsHtml}
124
- </div>
125
- ` : ''}
126
- </div>
127
-
128
- <!-- Right: Area image with credit on hover -->
129
- ${backgroundImage ? `
130
- <div class="relative group/image">
131
- <div class="w-12 h-12 rounded-lg overflow-hidden bg-gray-100 flex items-center justify-center cursor-help" title="${imageCredit}">
132
- <img src="/images/${backgroundImage}" alt="${primaryAreaData.name}" class="w-full h-full object-cover opacity-80">
133
- </div>
134
- </div>
135
- ` : ''}
136
- </div>
137
- </div>
138
-
139
- <!-- Description view (hidden by default) -->
140
- <div class="description-view hidden h-full flex flex-col min-h-0">
141
- <!-- Title (single line with overflow) -->
142
- <div class="mb-3 flex-shrink-0">
143
- <h3 class="font-semibold text-gray-900 text-sm leading-tight truncate" title="${title}">${title}</h3>
144
- </div>
145
-
146
- <!-- Description (scrollable, takes remaining space) -->
147
- <div class="flex-grow overflow-y-auto min-h-0">
148
- <p class="text-xs text-gray-700 leading-relaxed">${description}</p>
149
- </div>
150
- </div>
151
-
152
- <!-- URL link (always visible) -->
153
- ${sourceUrl ? `
154
- <div class="absolute bottom-2 right-2">
155
- <a href="${sourceUrl}" target="_blank" rel="noopener noreferrer" class="text-gray-400 hover:text-blue-600 transition-colors">
156
- <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
157
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"></path>
158
- </svg>
159
- </a>
160
- </div>
161
- ` : ''}
162
- </div>
163
- </div>
164
- `;
165
  }
166
 
167
  export function createArtifactCarousel(artifacts, containerId) {
 
1
  // ArtifactSummaryCard.js - Summary card component for artifacts
2
+ // Now uses the unified Card component
3
+ import { renderArtifactCard } from '../components/Card.js';
4
 
5
  export function createArtifactSummaryCard(artifact, index) {
6
+ return renderArtifactCard(artifact, { index });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  }
8
 
9
  export function createArtifactCarousel(artifacts, containerId) {
js/cards/HomeAreaCard.js DELETED
@@ -1,46 +0,0 @@
1
- // HomeAreaCard.js - Area card component for homepage
2
- import { areasData } from '../data/areas.js';
3
-
4
- export function createHomeAreaCard(id, title, description, openness, subAreas, image, imagePosition = 'left', imageAttribution = null, altText = null) {
5
- const flexDirection = imagePosition === 'left' ? 'lg:flex-row' : 'lg:flex-row-reverse';
6
-
7
- const subAreasList = subAreas.map(area => `<li>${area}</li>`).join('');
8
-
9
- // Use provided alt text or fallback to title
10
- const imgAlt = altText || title;
11
-
12
- // Create attribution text if provided
13
- const attribution = imageAttribution ?
14
- `<p class="text-xs text-gray-500 mt-2 text-center">${imageAttribution}</p>` : '';
15
-
16
- return `
17
- <div id="${id}" class="bg-white rounded-lg shadow-sm overflow-hidden" style="min-height: 300px;">
18
- <div class="flex flex-col ${flexDirection}">
19
- <div class="lg:w-2/3 p-8">
20
- <h2 class="text-2xl font-bold text-gray-900 mb-4">${title}</h2>
21
- <p class="text-gray-700 mb-6">${description}</p>
22
-
23
- ${openness ? `
24
- <div class="mb-6 px-6 pt-4 pb-6 bg-gradient-to-r from-orange-50 to-yellow-50 border-l-4 border-orange-300 rounded-r-lg">
25
- <p class="font-bold text-orange-900 mb-3">The Role of Openness</p>
26
- <p class="text-orange-800 italic leading-relaxed">${openness}</p>
27
- </div>
28
- ` : ''}
29
-
30
- <div class="mb-6">
31
- <h3 class="text-lg font-semibold text-gray-900 mb-3">Sub-areas</h3>
32
- <ul class="list-disc list-inside text-gray-700 space-y-1">
33
- ${subAreasList}
34
- </ul>
35
- </div>
36
- </div>
37
- <div class="lg:w-1/3 bg-gray-100">
38
- <div class="h-full flex flex-col items-center justify-center p-8">
39
- <img src="/images/${image}" alt="${imgAlt}" class="max-w-full max-h-full object-contain">
40
- ${attribution}
41
- </div>
42
- </div>
43
- </div>
44
- </div>
45
- `;
46
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/cards/ResourceCard.js DELETED
@@ -1,130 +0,0 @@
1
- // cards/ResourceCard.js - Resource card component for SPA
2
- import { areasData } from '../data/areas.js';
3
-
4
- export function createResourceCard(resource) {
5
- // Get the primary area for this resource
6
- const primaryArea = areasData[resource.areaTags[0]];
7
- const primaryColor = primaryArea?.primaryColor || 'gray';
8
-
9
- // Format date
10
- const formattedDate = new Date(resource.date).toLocaleDateString('en-US', {
11
- year: 'numeric',
12
- month: 'short',
13
- day: 'numeric'
14
- });
15
-
16
- // Generate area tags
17
- const areaTagsHtml = resource.areaTags.map(areaId => {
18
- const area = areasData[areaId];
19
- if (!area) return '';
20
- return `<span class="px-2 py-1 rounded-full text-xs font-medium ${area.colors.medium}">${area.name}</span>`;
21
- }).join('');
22
-
23
- // Generate sub-area tags
24
- const subAreaTagsHtml = resource.subAreaTags.map(subAreaKey => {
25
- // Find the sub-area name and color by looking through all areas
26
- let subAreaName = subAreaKey; // fallback to key if not found
27
- let textColor = 'text-gray-700'; // fallback color
28
-
29
- for (const areaKey in areasData) {
30
- const area = areasData[areaKey];
31
- if (area.subAreas && area.subAreas[subAreaKey]) {
32
- const subArea = area.subAreas[subAreaKey];
33
- subAreaName = typeof subArea === 'string' ? subArea : subArea.name;
34
- // Extract just the text color from the sub-area color
35
- if (typeof subArea === 'object' && subArea.color) {
36
- const colorMatch = subArea.color.match(/text-(\w+)-(\d+)/);
37
- if (colorMatch) {
38
- textColor = `text-${colorMatch[1]}-700`; // Use consistent 700 shade
39
- }
40
- }
41
- break;
42
- }
43
- }
44
- return `<span class="inline-block px-2 py-0.5 text-xs bg-gray-200 ${textColor} rounded">${subAreaName}</span>`;
45
- }).join('');
46
-
47
- // Type badge
48
- const typeBadge = resource.type === 'dataset' ? 'Dataset' : 'Tool';
49
- const typeColor = resource.type === 'dataset' ? 'bg-blue-100 text-blue-800' : 'bg-green-100 text-green-800';
50
-
51
- return `
52
- <div class="resource-card bg-white rounded-lg shadow-sm border border-gray-200 overflow-hidden flex-shrink-0 relative" style="height: 600px; width: 600px;">
53
- <!-- Top Section - Single view with all information -->
54
- <div class="resource-card-top h-48 bg-gradient-to-br from-${primaryColor}-50 to-${primaryColor}-100 relative overflow-hidden">
55
- <!-- Background image for top section -->
56
- <div class="absolute inset-0 opacity-10">
57
- <img src="/images/${primaryArea?.image || 'ai.png'}" alt="" class="w-full h-full object-cover">
58
- </div>
59
-
60
- <div class="relative z-10 p-4 h-full flex flex-col">
61
- <!-- Header with type, link, and date -->
62
- <div class="flex items-center justify-between mb-3">
63
- <div class="flex items-center gap-2">
64
- <span class="px-2 py-1 rounded-full text-xs font-medium ${typeColor}">${typeBadge}</span>
65
- <a href="${resource.url}" target="_blank" class="text-xs text-blue-600 hover:text-blue-800 flex items-center">
66
- <svg class="w-3 h-3 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
67
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"></path>
68
- </svg>
69
- View Resource
70
- </a>
71
- </div>
72
- <span class="text-xs text-gray-600">${formattedDate}</span>
73
- </div>
74
-
75
- <!-- Title -->
76
- <h3 class="text-lg font-semibold text-gray-900 mb-3 leading-tight">${resource.title}</h3>
77
-
78
- <!-- Description -->
79
- <p class="text-sm text-gray-700 mb-3 flex-1 overflow-hidden" style="display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical;">
80
- ${resource.description}
81
- </p>
82
-
83
- <!-- Footer with tags and area image -->
84
- <div class="flex items-center justify-between">
85
- <div class="flex flex-wrap gap-1 flex-1">
86
- ${areaTagsHtml}
87
- ${subAreaTagsHtml}
88
- </div>
89
- <div class="w-8 h-8 rounded-full bg-white bg-opacity-50 flex items-center justify-center ml-3 flex-shrink-0">
90
- <img src="/images/${primaryArea?.image || 'ai.png'}" alt="" class="w-6 h-6 rounded-full object-cover">
91
- </div>
92
- </div>
93
- </div>
94
- </div>
95
-
96
- <!-- Bottom Section - 70% of height -->
97
- <div class="resource-card-bottom relative" style="height: 420px;">
98
- ${resource.embedUrl ? `
99
- <!-- Iframe embed -->
100
- <iframe
101
- src="${resource.embedUrl}"
102
- class="w-full h-full border-0"
103
- loading="lazy"
104
- title="${resource.title}"
105
- ></iframe>
106
- ` : `
107
- <!-- Fallback with background image and text -->
108
- <div class="w-full h-full relative overflow-hidden">
109
- <div class="absolute inset-0 opacity-50">
110
- <img src="/images/${primaryArea?.image || 'ai.png'}" alt="" class="w-full h-full object-cover">
111
- </div>
112
- <div class="absolute inset-0 bg-black bg-opacity-20 flex items-center justify-center">
113
- <div class="text-center text-white">
114
- <div class="text-lg font-semibold mb-2">Iframe not available</div>
115
- <a href="${resource.url}" target="_blank" class="text-sm text-blue-200 hover:text-blue-100 underline">
116
- View on external site
117
- </a>
118
- </div>
119
- </div>
120
- </div>
121
- `}
122
- </div>
123
- </div>
124
- `;
125
- }
126
-
127
- export function initializeResourceCards() {
128
- // Resource cards now have a single view, no toggle functionality needed
129
- // This function is kept for consistency with the calling code
130
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/data/areas.js CHANGED
@@ -1,13 +1,17 @@
1
  // areas.js - Centralized areas data - SINGLE SOURCE OF TRUTH
2
  // All content, titles, navigation labels, and section IDs are defined here
3
  export const areasData = {
4
- efficiency: {
5
- id: 'efficiency',
6
- name: 'Efficiency',
7
- title: 'Efficiency, Costs, and Environment',
8
- navTitle: 'Sustainability & Efficiency', // Short title for navigation
9
- description: 'The question of costs is essential to understanding and managing the impact of AI technology; it determines who gets to develop it, use it, and how externalized costs are borne by people who do not choose or benefit from the technology.',
10
- openness: 'Open development of AI systems greatly facilitates transparency on the training and deployment costs. Users and developers of open models typically have stronger incentives to favor and invest in efficiency.',
 
 
 
 
11
  color: 'bg-green-100 text-green-800',
12
  primaryColor: 'green',
13
  colors: {
@@ -20,44 +24,47 @@ export const areasData = {
20
  imageAttribution: 'Hanna Barakat & Archival Images of AI + AIxDESIGN | BetterImagesOfAI, CC-BY-4.0',
21
  imageAltText: 'The image shows a surreal landscape with vast green fields extending toward distant mountains under a cloudy sky. Embedded in the fields are digital circuit patterns, resembling an intricate network of blue lines, representing a technological infrastructure. Five large computer monitors with keyboards are placed in a row, each with a Navajo woman sitting in front, weaving the computers. In the far distance, a cluster of teepees is visible.',
22
  imageSourceUrl: 'https://betterimagesofai.org/images?artist=HannaBarakat&title=WeavingWires2',
23
- subAreas: {
24
- environment: {
25
- id: 'environment',
26
- name: 'Environmental impact across the supply chains',
27
- navName: 'Environmental Impact', // Short name for navigation
28
- description: 'The environmental impact of AI systems across their supply chains, including the energy used, the materials used, and the waste generated.',
29
- openness: 'Transparency into not just the model weights and software, but also the supply chain, hardware, and environmental externalities of data centers is necessary to understand the entire environmental impact of AI systems.',
30
- color: 'bg-emerald-100 text-emerald-800',
31
- gradient: 'from-emerald-50 to-emerald-100 hover:from-emerald-100 hover:to-emerald-200 border-emerald-200 hover:border-emerald-300 text-emerald-900'
32
- },
33
  measuring: {
34
  id: 'measuring',
35
- name: 'Measuring energy and financial costs',
36
- navName: 'Energy & Financial Costs', // Short name for navigation
37
- description: 'Methodologies, standards, and transparency on the energy and financial costs of AI systems.',
38
- openness: 'Access to open models, training and fine-tuning data, and open-source software supports reproducible research into the energy and financial costs of AI systems.',
 
 
 
 
39
  color: 'bg-lime-100 text-lime-800',
40
  gradient: 'from-lime-50 to-lime-100 hover:from-lime-100 hover:to-lime-200 border-lime-200 hover:border-lime-300 text-lime-900'
41
  },
42
- efficient: {
43
- id: 'efficient',
44
  name: 'Making AI less compute-intensive',
45
- navName: 'Compute Efficiency', // Short name for navigation
46
- description: 'Efforts to reduce the compute-intensive nature of AI systems, and ways to make them more compute-efficient.',
47
- openness: 'Adopters of open models have stronger incentives to favor and invest in efficiency, and access to fully open models supports the development of more efficient models and training and inference techniques.',
 
 
 
 
48
  color: 'bg-teal-100 text-teal-800',
49
  gradient: 'from-teal-50 to-teal-100 hover:from-teal-100 hover:to-teal-200 border-teal-200 hover:border-teal-300 text-teal-900'
50
  },
51
  },
52
  imagePosition: 'left'
53
  },
54
- personal: {
55
- id: 'personal',
56
- name: 'Personal',
57
- title: 'Consent, Community, and Personal Interactions',
58
- navTitle: 'Personal & Community', // Short title for navigation
59
- description: 'People’s experiences with AI systems are shaped by direct interactions and the broader ways these systems influence communities and collective practices. Such dynamics affect digital identities and group relationships -- often without our awareness or ability to meaningfully consent.',
60
- openness: 'Openness at the model’s training data and inputs level is essential to support informed consent for individuals and communities whose norms and values may be shaped by AI systems. Transparency enables people and groups to understand how models affect their interactions, while research into companionship, community, and values makes it possible to replicate and assess these impacts.',
 
 
 
 
61
  color: 'bg-purple-100 text-purple-800',
62
  primaryColor: 'purple',
63
  colors: {
@@ -70,85 +77,48 @@ export const areasData = {
70
  imageAttribution: 'Kathryn Conrad | BetterImagesOfAI, CC-BY-4.0',
71
  imageAltText: 'Students at computers with screens that include a representation of a retinal scanner with pixelation and binary data overlays and a brightly coloured datawave heatmap at the top.',
72
  imageSourceUrl: 'https://betterimagesofai.org/images?artist=KathrynConrad&title=Datafication',
73
- subAreas: {
74
- interaction: {
75
- id: 'interaction',
76
- name: 'Characterizing personal and parasocial AI interactions',
77
- navName: 'Personal Interactions', // Short name for navigation
78
- description: 'Interactions between individuals and AI systems, whether active in the use of chatbots or passive when people are affected by the output of AI systems, are shaped by the values, behaviors, and priorities of the developers and the technology.',
79
- openness: 'Open access to the training datasets, development approaches, and trained models is necessary not just for developing methods to characterize and trace these characteristics of the systems, but to adapt them to the needs and desires of different communities of users.',
 
 
 
 
80
  color: 'bg-fuchsia-100 text-fuchsia-800',
81
  gradient: 'from-fuchsia-50 to-fuchsia-100 hover:from-fuchsia-100 hover:to-fuchsia-200 border-fuchsia-200 hover:border-fuchsia-300 text-fuchsia-900'
82
  },
83
- privacy: {
84
- id: 'privacy',
85
- name: 'Consent and privacy',
86
- navName: 'Consent & Privacy', // Short name for navigation
87
- description: 'Consent and privacy are intrinsically linked notions in the context of AI systems, as questions on both typically revolve around where and how a person\'s data or digital identity is used in the training or deployment of AI systems. These raise questions about the use of sensitive data, the value of creative works, surveillance dynamics at scale, and generally the conditions for access to digital infrastructure.',
88
- openness: 'Open access or sufficient transparency into training data and inputs of AI systems are necessary to support informed consent, and access to open models enables uses of the technology that do not require users to give away their or other people\'s data.',
 
 
 
 
 
89
  color: 'bg-violet-100 text-violet-800',
90
  gradient: 'from-violet-50 to-violet-100 hover:from-violet-100 hover:to-violet-200 border-violet-200 hover:border-violet-300 text-violet-900'
91
  },
92
  },
93
  imagePosition: 'right'
94
  },
95
- rights: {
96
- id: 'rights',
97
- name: 'Rights',
98
- title: 'Rights and Regulations',
99
- navTitle: 'Rights & Regulation', // Short title for navigation
100
- description: 'AI is not exempt from regulation; but understanding how new and existing rules apply to technical paradigms involving unprecedented scales of data and automation can present unique challenges.',
101
- openness: 'Applications of existing regulation as well as the design of new ones to meet the challenges of AI technology require understanding how it works, the trade-offs it entails, and the space of technical interventions that are feasible. Open access to the technology supports independent research from stakeholders with different incentives from those of the largest developers.',
102
- color: 'bg-indigo-100 text-indigo-800',
103
- primaryColor: 'indigo',
104
- colors: {
105
- light: 'bg-indigo-50 text-indigo-700',
106
- medium: 'bg-indigo-100 text-indigo-800',
107
- dark: 'bg-indigo-200 text-indigo-900',
108
- gradient: 'from-indigo-50 to-indigo-100 hover:from-indigo-100 hover:to-indigo-200 border-indigo-200 hover:border-indigo-300 text-indigo-900'
109
- },
110
- image: 'rights.png',
111
- imageAttribution: 'Emily Rand & LOTI | BetterImagesOfAI, CC-BY-4.0',
112
- imageAltText: 'Building blocks are overlayed with digital squares that highlight people living their day-to-day lives through windows. Some of the squares are accompanied by cursors.',
113
- imageSourceUrl: 'https://betterimagesofai.org/images?artist=EmilyRand&title=AICity',
114
- subAreas: {
115
- general: {
116
- id: 'general',
117
- name: 'How does existing regulation apply to AI',
118
- navName: 'Existing Regulation', // Short name for navigation
119
- description: 'Existing regulations, especially regulations governing transfers of data and use of algorithms in sensitive domains like healthcare or education, also apply to AI systems. However, the unprecedented scale of data and automation involved in this new technical paradigm can challenge previous understandings of the mechanisms for applying those regulations.',
120
- openness: 'Open access to AI systems enables independent research led by legal and domain experts of regulated domains to explore the existing and new legal questions raised by the technology without having to rely on the interpretations of a few model developers.',
121
- color: 'bg-purple-100 text-purple-800',
122
- gradient: 'from-purple-50 to-purple-100 hover:from-purple-100 hover:to-purple-200 border-purple-200 hover:border-purple-300 text-purple-900'
123
- },
124
- specific: {
125
- id: 'specific',
126
- name: 'Navigating new AI-specific regulation',
127
- navName: 'AI-Specific Regulation', // Short name for navigation
128
- description: 'Artificial Intelligence has also required new regulatory attention in the form of AI-specific legislation, such as the EU AI Act and several US state and federal bills. These have raised important questions about which risks to prioritize in legislative actions, and how to arbitrated between different interests and perspectives on the technology.',
129
- openness: 'Open access to AI systems has enabled more robust evaluation of the capabilities and limitations of AI systems, and of the resource trade-offs and externalities involved in their development and deployment.',
130
- color: 'bg-cyan-100 text-cyan-800',
131
- gradient: 'from-cyan-50 to-cyan-100 hover:from-cyan-100 hover:to-cyan-200 border-cyan-200 hover:border-cyan-300 text-cyan-900'
132
- },
133
- open: {
134
- id: 'open',
135
- name: 'The place of open-source in regulation',
136
- navName: 'Open-Source in Regulation', // Short name for navigation
137
- description: 'While open-source software and open development of AI systems are often seen as a cornerstone of innovation and technology development, they are often relegated to a last-minute consideration in regulatory discussions, which can be particularly damaging given the diversity of development contexts and developer and researcher profiles who participate in it.',
138
- openness: 'Open research and centralized resources for legal compliance in open-source and collaborative development settings helps lower barriers to participation that could be insurmountable for the often less-resourced organizations doing much of the most publicly beneficial work.',
139
- color: 'bg-pink-100 text-pink-800',
140
- gradient: 'from-pink-50 to-pink-100 hover:from-pink-100 hover:to-pink-200 border-pink-200 hover:border-pink-300 text-pink-900'
141
- }
142
- },
143
- imagePosition: 'left'
144
- },
145
  ecosystems: {
146
  id: 'ecosystems',
147
- name: 'Ecosystems',
148
- title: 'Socio-economic and Technical Ecosystems',
149
- navTitle: 'Tech+(*) Ecosystems', // Short title for navigation
150
- description: 'While discussions of the impact of AI often focus on technical characteristics of individual systems, the trajectory and impact of the technology are often better explained by looking to broader dynamics of market power and economic incentives.',
151
- openness: 'Openness is an important factor in the diffusion of the technology, and enables a greater variety of actors to reliably assess its suitability and to adapt it to their specific contexts and requirements; as well as to understand the role of different resources and the consequences of their concentration among a few actors.',
 
 
 
 
152
  color: 'bg-orange-100 text-orange-800',
153
  primaryColor: 'orange',
154
  colors: {
@@ -161,31 +131,45 @@ export const areasData = {
161
  imageAttribution: 'Lone Thomasky & Bits&BΓ€ume | BetterImagesOfAI, CC-BY-4.0',
162
  imageAltText: 'A simplified illustration of urban life near the sea showing groups of people, buildings and bridges, as well as polluting power plants, opencast mining, exploitative work, data centres and wind power stations on a hill. Several small icons indicate destructive processes.',
163
  imageSourceUrl: 'https://betterimagesofai.org/images?artist=LoneThomasky&title=DigitalSocietyBell',
164
- subAreas: {
165
- labor: {
166
- id: 'labor',
167
- name: 'Labor impacts of AI',
168
- navName: 'Labor Impacts', // Short name for navigation
169
- description: 'Given the ubiquity of data and algorithmic systems in the economy, AI is likely to have a significant impact on labor conditions and opportunities, and to displace certain types of value from workers to technology developers. Understanding to how, to what extent, and how to locate development so AI benefits its adopters and not just its developers will require significant work from all categories of stakeholders.',
170
- openness: 'Open access to AI systems can enable both more reliable research into the fitness for purpose of AI systems in workplaces, the disparate cost of its development, and enable its development and control by organizations that are closer to the context and interests of its adopters.',
 
 
 
 
 
171
  color: 'bg-yellow-100 text-yellow-800',
172
  gradient: 'from-yellow-50 to-yellow-100 hover:from-yellow-100 hover:to-yellow-200 border-yellow-200 hover:border-yellow-300 text-yellow-900'
173
  },
174
  power: {
175
  id: 'power',
176
- name: 'Power, monopolies, and sovereignty',
177
- navName: 'Power & Monopolies', // Short name for navigation
178
- description: 'As a few companies have come to dominate the development and resources that support the most visible AI systems, market concentration dynamics and technological sovereignty questions will play a significant role in determining the positive and negative outcomes of the technology.',
179
- openness: 'Open access and open development of AI systems has enabled access to the technology that is less dependent on the resources of a few companies, more transparent to regulators, and shaped by a greater variety of actors.',
 
 
 
 
 
180
  color: 'bg-red-100 text-red-800',
181
  gradient: 'from-red-50 to-red-100 hover:from-red-100 hover:to-red-200 border-red-200 hover:border-red-300 text-red-900'
182
  },
183
- usage: {
184
- id: 'usage',
185
- name: 'How and where is (open) AI used',
186
- navName: 'AI Usage Patterns', // Short name for navigation
187
- description: 'Understanding how and where AI is used and what data and compute resources support its development and deployment is essential to understanding its impact on society. This includes studying which domains it is more or less suitable for, how AI systems are adapted and transformed by different actors, and where the data that supports its development comes from.',
188
- openness: 'Documentation and transparency of the components and use cases of AI systems supports research by broader domains of expertise.',
 
 
 
 
189
  color: 'bg-purple-100 text-purple-800',
190
  gradient: 'from-purple-50 to-purple-100 hover:from-purple-100 hover:to-purple-200 border-purple-200 hover:border-purple-300 text-purple-900'
191
  }
@@ -215,10 +199,10 @@ export function getNavigationData() {
215
  id: area.id,
216
  navTitle: area.navTitle,
217
  title: area.title,
218
- topics: Object.values(area.subAreas).map(subArea => ({
219
- id: subArea.id,
220
- navName: subArea.navName,
221
- name: subArea.name
222
  }))
223
  }));
224
  }
@@ -232,10 +216,10 @@ export function getAreaNavigation(areaId) {
232
  id: area.id,
233
  navTitle: area.navTitle,
234
  title: area.title,
235
- topics: Object.values(area.subAreas).map(subArea => ({
236
- id: subArea.id,
237
- navName: subArea.navName,
238
- name: subArea.name
239
  }))
240
  };
241
  }
 
1
  // areas.js - Centralized areas data - SINGLE SOURCE OF TRUTH
2
  // All content, titles, navigation labels, and section IDs are defined here
3
  export const areasData = {
4
+ sustainability: {
5
+ id: 'sustainability',
6
+ title: 'Sustainability',
7
+ navTitle: 'Sustainability', // Short title for navigation
8
+ description: {
9
+ short: 'More sustainable AI environmentally and economically is essential to managing its impacts, open development supports reliable measuring and more efficient methods.',
10
+ paragraphs: [
11
+ 'Reaching a better understanding of AI’s sustainability is essential to managing the impacts of AI technologies; it shapes who gets to develop AI technologies, use them, and how their externalized costs are borne by people who do not choose or benefit from the technology.',
12
+ 'Developers of open models typically have stronger incentives to favor and invest in efficiency, which in terms helps drive more responsible and informed usage of the technologies created. Relatedly, the open development of AI systems also greatly facilitates transparency regarding the costs of training and developing them and open-sourcing models contributes towards reducing wasted deployment costs, since models can be reused and adapted instead of being trained from scratch.',
13
+ ],
14
+ },
15
  color: 'bg-green-100 text-green-800',
16
  primaryColor: 'green',
17
  colors: {
 
24
  imageAttribution: 'Hanna Barakat & Archival Images of AI + AIxDESIGN | BetterImagesOfAI, CC-BY-4.0',
25
  imageAltText: 'The image shows a surreal landscape with vast green fields extending toward distant mountains under a cloudy sky. Embedded in the fields are digital circuit patterns, resembling an intricate network of blue lines, representing a technological infrastructure. Five large computer monitors with keyboards are placed in a row, each with a Navajo woman sitting in front, weaving the computers. In the far distance, a cluster of teepees is visible.',
26
  imageSourceUrl: 'https://betterimagesofai.org/images?artist=HannaBarakat&title=WeavingWires2',
27
+ topics: {
 
 
 
 
 
 
 
 
 
28
  measuring: {
29
  id: 'measuring',
30
+ name: 'Measuring and standardising costs and impacts',
31
+ description: {
32
+ short: 'Addressing the environmental and financial costs of AI systems start with reliable and trustworthy measuring and reporting.',
33
+ paragraphs: [
34
+ 'Systematically evaluating the impacts of deployed AI systems and developing methodologies and standards to compare different systems is a key component of getting more transparency on their energy and financial costs. Open-sourcing systems supports this evaluation by allowing researchers to access open models, training and fine-tuning data, and code.',
35
+ 'Carrying out research to improve the state-of-the-art in terms of evaluation science and disclosure requirements at different levels of granularity – from individual developers to industry organizations, as well as entire countries – can help pave the way towards more standardized evaluation approaches. Building links between AI developers, international standards organizations and policymakers is important to ensure the cohesion between disclosure requirements and technical standards.',
36
+ ],
37
+ },
38
  color: 'bg-lime-100 text-lime-800',
39
  gradient: 'from-lime-50 to-lime-100 hover:from-lime-100 hover:to-lime-200 border-lime-200 hover:border-lime-300 text-lime-900'
40
  },
41
+ efficiency: {
42
+ id: 'efficiency',
43
  name: 'Making AI less compute-intensive',
44
+ description: {
45
+ short: 'Efforts to reduce the compute-intensive nature of AI systems, and ways to make them more compute-efficient.',
46
+ paragraphs: [
47
+ 'Approaches to improving AI systems’ efficiency include efforts to reduce the compute-intensive nature of AI systems (specifically large language models), and ways to make both their development and usage more compute-efficient. While the true monetary and energy costs of proprietary AI models are rarely made available to users and developers, their increased usage in existing and new systems (e.g. Web search, AI agents, etc.) makes understanding these important. Optimization approaches such as distillation and quantization can help make models more efficient, but they can only be applied if the models themselves are accessible. This means that adopters of open models have stronger incentives to favor and invest in efficiency, and access to fully open models supports the development of more efficient models and training and inference techniques. ',
48
+ 'While the hardware used to train and deploy models (GPUs and TPUs) has become increasingly compute-efficient, it is still unclear whether this is outpaced by increased usage or not. Given that the current dynamics that incentivize an over-usage of compute-intensive AI models (prioritizing convenience and market capture over using the right AI tool for the right task), it is still unclear to what extent hardware efficiency gains are lost due to their increased usage.',
49
+ ],
50
+ },
51
  color: 'bg-teal-100 text-teal-800',
52
  gradient: 'from-teal-50 to-teal-100 hover:from-teal-100 hover:to-teal-200 border-teal-200 hover:border-teal-300 text-teal-900'
53
  },
54
  },
55
  imagePosition: 'left'
56
  },
57
+ agency: {
58
+ id: 'agency',
59
+ title: 'Personal and Community Agency',
60
+ navTitle: 'Agency', // Short name for navigation
61
+ description: {
62
+ short: 'How AI systems affect our personal and collective experiences and how we can in turn shape them.',
63
+ paragraphs: [
64
+ 'AI systems mediate how we express ourselves, form relationships, and act within digital environments. From personal interactions to collective practices, consent, privacy and agency define how people engage with and shape AI systems. They determine how individuals navigate attachment, how their data and identities shape them, and how communities organize to reclaim influence over the systems that affect them.',
65
+ 'Openness of models, data, and decision-making processes plays a strong role in enabling these forms of agency. It enables individuals and groups to understand how AI affects them, but also to act on that understanding – by choosing how to participate, auditing and adapting technologies, and helping define the norms and safeguards that govern them. Active participation and informed consent turn openness from a principle into a practice, ensuring that users, researchers, and communities have the capacity to steer AI development toward their own needs and values.',
66
+ ],
67
+ },
68
  color: 'bg-purple-100 text-purple-800',
69
  primaryColor: 'purple',
70
  colors: {
 
77
  imageAttribution: 'Kathryn Conrad | BetterImagesOfAI, CC-BY-4.0',
78
  imageAltText: 'Students at computers with screens that include a representation of a retinal scanner with pixelation and binary data overlays and a brightly coloured datawave heatmap at the top.',
79
  imageSourceUrl: 'https://betterimagesofai.org/images?artist=KathrynConrad&title=Datafication',
80
+ topics: {
81
+ personal: {
82
+ id: 'personal',
83
+ name: 'Personal Agency and Interactions',
84
+ description: {
85
+ short: 'Characterizing how AI system design, embedded values, and data flows shape personal experiences.',
86
+ paragraphs: [
87
+ 'AI systems increasingly participate in people’s daily lives, from conversational agents to creative tools. They mediate emotional expression, companionship, and value formation, and they also shape which forms of identity and speech are amplified or suppressed. The same systems that foster companionship or creativity can also reproduce disparities in performance or moderation with users whose identities, languages, or cultures differ most from those of their developers. Questions of privacy are also central to understanding how data about our lives and activities inform these systems and the decisions they make about us, and keeping control of our digital identities.',
88
+ 'Studying these interactions shows how people experience agency, trust, and influence within AI-mediated environments; and allows us to build tools and shape development in ways that reflect broader needs and interests. Openness and transparency around data and decision-making enable individuals and communities to act: to audit behaviors, retrace decisions, and adapt systems to their own cultural and emotional contexts. Moreover, integrating privacy and consent at the design stage allows non-technical actors to participate in co-design, provide feedback, or govern usage norms, transforming the understanding of AI experiences into shared capacity to shape them.',
89
+ ],
90
+ },
91
  color: 'bg-fuchsia-100 text-fuchsia-800',
92
  gradient: 'from-fuchsia-50 to-fuchsia-100 hover:from-fuchsia-100 hover:to-fuchsia-200 border-fuchsia-200 hover:border-fuchsia-300 text-fuchsia-900'
93
  },
94
+ community: {
95
+ id: 'community',
96
+ name: 'Collective Agency and Community Governance',
97
+ description: {
98
+ short: 'How AI systems shape collective practices and influence who can participate in digital spaces.',
99
+ paragraphs: [
100
+ 'We interact with and are shaped by AI systems not just as individuals but also as members of communities who have different relationships to the technology. As both technical artifacts and social infrastructures, they shape collective practices, redistribute power, and influence who can participate in digital spaces. ',
101
+ 'Transparent, collaborative, and affordable technical systems can support approaches to direct community governance, shaping how decisions about datasets, design, and deployment are made; transparency and open access to support investigation by and for communities also help them assert influence beyond formal participation. Reporting or documenting harms and biases that affect them, developing decentralized or community-moderated alternatives to centralized systems, organizing around the implementation of AI in local or online spaces, or mobilizing against uses that threaten their rights, privacy, and values all have a strong role to play.',
102
+ 'Open access to the inner working and intermediary design decisions of AI systems make this governance meaningful, enabling communities to deliberate on system goals, share oversight, and embed accountability and pluralism into AI development. Embedding consent and privacy norms into collective governance ensures that communities actively interpret, contest, and rebuild technology, shaping the field through both critique and creation.',
103
+ ],
104
+ },
105
  color: 'bg-violet-100 text-violet-800',
106
  gradient: 'from-violet-50 to-violet-100 hover:from-violet-100 hover:to-violet-200 border-violet-200 hover:border-violet-300 text-violet-900'
107
  },
108
  },
109
  imagePosition: 'right'
110
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  ecosystems: {
112
  id: 'ecosystems',
113
+ title: 'Ecosystems',
114
+ navTitle: 'Ecosystems', // Short title for navigation
115
+ description: {
116
+ short: 'AI systems are embedded in economic, regulatory, and market ecosystems that shape and are shaped by their development.',
117
+ paragraphs: [
118
+ 'Understanding AI systems requires understanding the economic, regulatory, and market ecosystems that shape and are shaped by its development. These ecosystems determine the effectiveness of different approaches to the development, governance, and commercialization of the technology – and the most effective strategies to ensure positive outcomes for stakeholders both in and outside of its development settings.',
119
+ 'More open and transparent technology enables both a better study of the interactions between these ecosystems and the development of tools and versions of the technologies that can better avoid pitfalls of labor and economic displacement, excessive concentration of resources and market power, or of regulation under strong epistemic asymmetries between policymakers and large developers. In particular, open research and development enables more direct collaboration between diverse developer profiles, legislators, adopters, advocates, and other economic actors – with less dependence on access and information provided by large model developers.',
120
+ ],
121
+ },
122
  color: 'bg-orange-100 text-orange-800',
123
  primaryColor: 'orange',
124
  colors: {
 
131
  imageAttribution: 'Lone Thomasky & Bits&BΓ€ume | BetterImagesOfAI, CC-BY-4.0',
132
  imageAltText: 'A simplified illustration of urban life near the sea showing groups of people, buildings and bridges, as well as polluting power plants, opencast mining, exploitative work, data centres and wind power stations on a hill. Several small icons indicate destructive processes.',
133
  imageSourceUrl: 'https://betterimagesofai.org/images?artist=LoneThomasky&title=DigitalSocietyBell',
134
+ topics: {
135
+ economy: {
136
+ id: 'economy',
137
+ name: 'Economic and Labor Impacts of AI',
138
+ description: {
139
+ short: 'How AI systems affect the economy and labor conditions.',
140
+ paragraphs: [
141
+ 'AI is transforming work across industries from logistics and finance to media, software development, and customer service. As models are integrated into larger commercial systems, they increasingly shape how tasks are designed, monitored, and valued. The centralization of data and the ensuing integration of automated information processing, pattern recognition, and content generation tools is changing how digital and creative work is supported, organized, and distributed, and who benefits from it. These changes redefine labor and economic sectors not just through job displacement, but through the redesign of entire production systems.',
142
+ 'Understanding where AI systems can support workers and economic outcomes, how different kinds of deployments may favor or harm different parties, and how control of work data flows can either consolidate or displace value creation for adopters of AI systems all contribute to making sure that they are developed and deployed to benefit the workforce and industry sectors that leverage the technology, not just its developers.',
143
+ 'Openness and transparency into the models and datasets that support commercial applications of AI, particularly in β€œenterprise” settings and for specific domains of activities, supports more positive outcomes and broadly distributed benefits in two major ways. First, by enabling the development of new AI systems to be driven more directly by the economic actors who want to leverage them, maintaining control of their supply chain, expertise, and value propositions. Second, by enabling more scrutiny into the systems themselves, and supporting more robust and independent analysis of the labor and economic impacts of the technology – rather than relying on the framings and promises of developers – to better guide economic policy and strategy.',
144
+ ],
145
+ },
146
  color: 'bg-yellow-100 text-yellow-800',
147
  gradient: 'from-yellow-50 to-yellow-100 hover:from-yellow-100 hover:to-yellow-200 border-yellow-200 hover:border-yellow-300 text-yellow-900'
148
  },
149
  power: {
150
  id: 'power',
151
+ name: 'De-Centralized Markets, Development, and Sovereignty',
152
+ description: {
153
+ short: 'Market concentration dynamics and technological sovereignty questions.',
154
+ paragraphs: [
155
+ 'The narratives and development of AI today are disproportionately shaped by a handful of actors who control the largest models, datasets, and compute infrastructure. This concentration of technical and financial power doesn’t just shape (and constrain) innovation – it defines which versions of the technology are given priority, who sets its norms, what values it encodes, and who benefits most from its integration into all aspects of society. As these dependencies deepen, they also raise questions of digital and technological sovereignty for nations and collectivities aiming to set their own terms for their digital infrastructures.',
156
+ 'A more balanced and resilient AI ecosystem depends on distributing the capacity to develop, study, and govern these systems. Maintaining this capacity to develop alternative versions of the technology beyond that of a few actors concentrating the majority of the computational and data resources requires a wide range of strategies, from checking abuses of market power to ensure broad participation in AI development remains incentivized and sustainable to lowering the technical and financial barrier to entry for all categories of actors; benefiting both small start-ups and public institutions and larger economic organizations resources who still may not want to reach the excesses of compute expenses of the largest developers.',
157
+ 'Fostering a broad ecosystem of open AI models, datasets, and tools and a thriving open research environment across universities and independent developers has a dual role to play in mitigating the risks of extreme concentration. First, it enables a better understanding into the tradeoffs involved in the development of the technology, including specifically in characterizing the role of different categories of resources and the risks their capture may pose to a competitive ecosystem. Second, it drastically reduces the cost of developing new AI systems, or of adapting existing AI technology to the needs of various actors; and allows them to control their data flows to ensure their longer-term welfare.',
158
+ ],
159
+ },
160
  color: 'bg-red-100 text-red-800',
161
  gradient: 'from-red-50 to-red-100 hover:from-red-100 hover:to-red-200 border-red-200 hover:border-red-300 text-red-900'
162
  },
163
+ regulation: {
164
+ id: 'regulation',
165
+ name: 'Rights and Regulation',
166
+ description: {
167
+ short: 'How AI systems are regulated and how they affect rights and regulations.',
168
+ paragraphs: [
169
+ 'Regulation of AI systems, both through the design of new technology-specific rules of through the exploration of how existing laws apply to the new technical paradigms it introduces, has drawn increasing attention commensurate with the ubiquity and visibility of the technology. Notably, the unprecedented scales of data and automation can present unique challenges, and different interests and perspectives on the technology from different categories of stakeholder have raised important questions about which risks to prioritize in legislative actions, and how to arbitrate between different tradeoffs – including when considering how to apply proposed rules to open and open-source systems, which often receive significantly less consideration in drafting processes than diversity of development contexts and developer and researcher profiles who participate in it would warrant.',
170
+ 'Effective AI regulation requires a deep understanding of the technology\'s inner workings, including its inherent trade-offs and the feasibility of technical interventions. Open access to AI systems is crucial for this, as it empowers independent legal and domain experts to conduct research and assess the technology without relying solely on the interpretations of a few powerful developers. Furthermore, open research and centralized resources for legal compliance lower barriers to participation, which is vital for the often less-resourced organizations that produce much of the most publicly beneficial work. This openness extends beyond code to include open datasets, models, and transparent decision-making, enabling a broader community to help shape AI. Overall, collaboration on the technical artifacts and legal tools that shape the design and governance of artificial intelligence is essential to ensure the sustainability of regulatory efforts that serve all of the people whose lives it shapes.',
171
+ ],
172
+ },
173
  color: 'bg-purple-100 text-purple-800',
174
  gradient: 'from-purple-50 to-purple-100 hover:from-purple-100 hover:to-purple-200 border-purple-200 hover:border-purple-300 text-purple-900'
175
  }
 
199
  id: area.id,
200
  navTitle: area.navTitle,
201
  title: area.title,
202
+ topics: Object.values(area.topics).map(topic => ({
203
+ id: topic.id,
204
+ navName: topic.navName || topic.name,
205
+ name: topic.name
206
  }))
207
  }));
208
  }
 
216
  id: area.id,
217
  navTitle: area.navTitle,
218
  title: area.title,
219
+ topics: Object.values(area.topics).map(topic => ({
220
+ id: topic.id,
221
+ navName: topic.navName || topic.name,
222
+ name: topic.name
223
  }))
224
  };
225
  }
js/data/artifacts.js DELETED
@@ -1,39 +0,0 @@
1
- // artifacts.js - Featured artifacts data
2
- export const featuredArtifacts = [
3
- {
4
- title: "🌎 What kind of environmental impacts are AI companies disclosing? (And can we compare them?) 🌎",
5
- date: "2025-09-01",
6
- type: "blog",
7
- description: "AI companies are beginning to disclose environmental metrics for their models, but inconsistent methodologies and incomplete data make meaningful comparisons impossible. Without standardized reporting of both intensity metrics and absolute totals, these disclosures risk misleading the public and obscuring the true scale of AI's environmental footprint. Transparent, comparable reporting must align with existing sustainability frameworks to prevent greenwashing and drive real accountability.",
8
- areaTags: ["efficiency"],
9
- subAreaTags: ["measuring"],
10
- sourceUrl: "https://huggingface.co/blog/sasha/environmental-impact-disclosures"
11
- },
12
- {
13
- title: "Advertisement, Privacy, and Intimacy: Lessons from Social Media for Conversational AI",
14
- date: "2025-09-01",
15
- type: "blog",
16
- description: "As conversational AI systems become increasingly intimate and trusted, we risk repeating the privacy mistakes of social mediaβ€”especially as advertising models threaten to monetize personal disclosures. Users intuitively trust AI as a private confidant, unaware that their most sensitive data may be harvested, analyzed, and exploited for commercial gain. Open-source alternatives offer a path toward transparent, user-centered AI that prioritizes privacy over profit.",
17
- areaTags: ["personal"],
18
- subAreaTags: ["interaction"],
19
- sourceUrl: "https://huggingface.co/blog/giadap/privacy-conversational-ai"
20
- },
21
- {
22
- title: "What Open-Source Developers Need to Know about the EU AI Act's Rules for GPAI Models",
23
- date: "2025-08-04",
24
- type: "blog",
25
- description: "Open-source developers can navigate the EU AI Act's obligations for general-purpose AI models with targeted exemptions when releasing models under free and open-source licenses, avoiding redundant requirements like transparency documentation and EU representative appointmentsβ€”while still needing to comply with copyright law and training data transparency.",
26
- areaTags: ["rights"],
27
- subAreaTags: ["specific", "open"],
28
- sourceUrl: "https://huggingface.co/blog/yjernite/eu-act-os-guideai"
29
- },
30
- {
31
- title: "Local Differences, Global Lessons: Insights from Organisation Policies for International Legislation",
32
- date: "2025-03-05",
33
- type: "paper",
34
- description: "Organisational AI policies in newsrooms and universities reveal practical, domain-specific approaches to managing risks like bias, privacy, and environmental impact β€” areas often underaddressed in top-down regulations like the EU AI Act. These bottom-up guidelines offer actionable insights on AI literacy, disclosure, and accountability that can inform more adaptive and effective global AI governance. The study argues for integrating real-world organisational practices into international regulatory frameworks to bridge implementation gaps.",
35
- areaTags: ["ecosystems"],
36
- subAreaTags: ["usage"],
37
- sourceUrl: "https://arxiv.org/abs/2503.05737"
38
- }
39
- ];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/data/press.js CHANGED
@@ -4,24 +4,24 @@ export const pressMentions = [
4
  date: '2025-09-10',
5
  source: 'Forbes',
6
  sourceUrl: 'https://www.forbes.com/sites/johnwerner/2025/09/10/is-ai-a-good-companion-intima-tests-this-comprehensively/',
7
- areaTags: ['personal'],
8
- subAreaTags: ['interaction'],
9
  },
10
  {
11
  title: 'The problem of AI chatbots telling people what they want to hear',
12
  date: '2025-09-03',
13
  source: 'Financial Times',
14
  sourceUrl: 'https://www.ft.com/content/72aa8c32-1fb5-49b7-842c-0a8e4766ac84',
15
- areaTags: ['personal'],
16
- subAreaTags: ['interaction'],
17
  },
18
  {
19
  title: 'Should AI flatter us, fix us, or just inform us?',
20
  date: '2025-08-19',
21
  source: 'MIT Technology Review',
22
  sourceUrl: 'https://www.technologyreview.com/2025/08/19/1122021/should-ai-flatter-us-fix-us-or-just-inform-us/',
23
- areaTags: ['personal'],
24
- subAreaTags: ['interaction'],
25
  },
26
  {
27
  title: ' Will AI really wipe out white collar jobs? Tech insiders are split ',
@@ -29,30 +29,30 @@ export const pressMentions = [
29
  source: 'CNN',
30
  sourceUrl: 'https://www.cnn.com/2025/07/21/tech/ai-replace-human-workers-tech-insiders-split',
31
  areaTags: ['ecosystems'],
32
- subAreaTags: ['labor'],
33
  },
34
  {
35
  title: 'How Much Energy Does Your AI Prompt Use? I Went to a Data Center to Find Out.',
36
  date: '2025-06-26',
37
  source: 'Wall Street Journal',
38
  sourceUrl: 'hhttps://www.wsj.com/tech/ai/ai-prompt-video-energy-electricity-use-046766d6',
39
- areaTags: ['efficiency'],
40
- subAreaTags: ['measuring', 'environment'],
41
  },
42
  {
43
  title: 'Study reveals how much energy AI uses to answer your questions',
44
  date: '2025-06-25',
45
  source: 'CNN',
46
  sourceUrl: 'https://www.cnn.com/2025/06/22/climate/ai-prompt-carbon-emissions-environment-wellness',
47
- areaTags: ['efficiency'],
48
- subAreaTags: ['measuring', 'efficient'],
49
  },
50
  {
51
- title: 'European tech’s most influential lobbyists',
52
  date: '2025-04-17',
53
  source: 'Sifted',
54
  sourceUrl: 'https://sifted.eu/articles/european-tech-startups-lobbyists',
55
- areaTags: ['rights'],
56
- subAreaTags: ['general', 'open'],
57
  },
58
  ];
 
4
  date: '2025-09-10',
5
  source: 'Forbes',
6
  sourceUrl: 'https://www.forbes.com/sites/johnwerner/2025/09/10/is-ai-a-good-companion-intima-tests-this-comprehensively/',
7
+ areaTags: ['agency'], // Updated: 'personal' β†’ 'agency'
8
+ subAreaTags: ['personal'], // Updated: 'interaction' β†’ 'personal'
9
  },
10
  {
11
  title: 'The problem of AI chatbots telling people what they want to hear',
12
  date: '2025-09-03',
13
  source: 'Financial Times',
14
  sourceUrl: 'https://www.ft.com/content/72aa8c32-1fb5-49b7-842c-0a8e4766ac84',
15
+ areaTags: ['agency'], // Updated: 'personal' β†’ 'agency'
16
+ subAreaTags: ['personal'], // Updated: 'interaction' β†’ 'personal'
17
  },
18
  {
19
  title: 'Should AI flatter us, fix us, or just inform us?',
20
  date: '2025-08-19',
21
  source: 'MIT Technology Review',
22
  sourceUrl: 'https://www.technologyreview.com/2025/08/19/1122021/should-ai-flatter-us-fix-us-or-just-inform-us/',
23
+ areaTags: ['agency'], // Updated: 'personal' β†’ 'agency'
24
+ subAreaTags: ['personal'], // Updated: 'interaction' β†’ 'personal'
25
  },
26
  {
27
  title: ' Will AI really wipe out white collar jobs? Tech insiders are split ',
 
29
  source: 'CNN',
30
  sourceUrl: 'https://www.cnn.com/2025/07/21/tech/ai-replace-human-workers-tech-insiders-split',
31
  areaTags: ['ecosystems'],
32
+ subAreaTags: ['economy'], // Updated: 'labor' β†’ 'economy'
33
  },
34
  {
35
  title: 'How Much Energy Does Your AI Prompt Use? I Went to a Data Center to Find Out.',
36
  date: '2025-06-26',
37
  source: 'Wall Street Journal',
38
  sourceUrl: 'hhttps://www.wsj.com/tech/ai/ai-prompt-video-energy-electricity-use-046766d6',
39
+ areaTags: ['sustainability'], // Updated: 'efficiency' β†’ 'sustainability'
40
+ subAreaTags: ['measuring'], // Removed 'environment' (doesn't exist in new structure)
41
  },
42
  {
43
  title: 'Study reveals how much energy AI uses to answer your questions',
44
  date: '2025-06-25',
45
  source: 'CNN',
46
  sourceUrl: 'https://www.cnn.com/2025/06/22/climate/ai-prompt-carbon-emissions-environment-wellness',
47
+ areaTags: ['sustainability'], // Updated: 'efficiency' β†’ 'sustainability'
48
+ subAreaTags: ['measuring', 'efficiency'], // Updated: 'efficient' β†’ 'efficiency'
49
  },
50
  {
51
+ title: 'European tech\'s most influential lobbyists',
52
  date: '2025-04-17',
53
  source: 'Sifted',
54
  sourceUrl: 'https://sifted.eu/articles/european-tech-startups-lobbyists',
55
+ areaTags: ['ecosystems'], // Updated: 'rights' merged into 'ecosystems'
56
+ subAreaTags: ['regulation'], // Updated: 'general', 'open' β†’ 'regulation'
57
  },
58
  ];
js/data/resources.js DELETED
@@ -1,101 +0,0 @@
1
- export const sampleResources = [
2
- {
3
- title: 'AI Legal Hackathons: Memos and Guides Hub',
4
- type: 'space',
5
- date: '2025-09-14',
6
- description: 'From 2022 to 2024, AI2, Hugging Face, and NYU organized legal hackathons with LLM students from the NYU School of Law to explore regulatory questions related to AI. The space contains some of the memos and guides from the hackathons.',
7
- url: 'https://huggingface.co/spaces/hfmlsoc/legal-hackathons-nyu-ai2',
8
- areaTags: ['rights'],
9
- subAreaTags: ['general', 'specific'],
10
- embedUrl: "https://hfmlsoc-legal-hackathons-nyu-ai2.static.hf.space"
11
- },
12
- {
13
- title: 'Archive Explorer: AI, Labor and the Economy 2022-2025',
14
- type: 'space',
15
- date: '2025-09-04',
16
- description: 'The Labor Archive Explorer is a tool for exploring a dataset of news articles and other writings about AI, labor, and the economy from the release of ChatGPT to July 2025.',
17
- url: 'https://huggingface.co/spaces/hfmlsoc/labor-archive-explorer',
18
- areaTags: ['ecosystems'],
19
- subAreaTags: ['labor'],
20
- embedUrl: "https://hfmlsoc-labor-archive-explorer.static.hf.space"
21
- },
22
- {
23
- title: 'INTIMA Companionship Benchmark Dataset',
24
- type: 'dataset',
25
- date: '2025-08-04',
26
- description: 'INTIMA (Interactions and Machine Attachment) is a benchmark designed to evaluate companionship behaviors in large language models (LLMs). It measures whether AI systems reinforce, resist, or remain neutral in response to emotionally and relationally charged user inputs.',
27
- url: 'https://huggingface.co/datasets/AI-companionship/INTIMA',
28
- areaTags: ['personal'],
29
- subAreaTags: ['interaction'],
30
- embedUrl: "https://huggingface.co/datasets/AI-companionship/INTIMA/embed/viewer/default/train"
31
- },
32
- {
33
- title: 'EU AI Act: Developer Requirements Flowchart',
34
- type: 'space',
35
- date: '2025-08-01',
36
- description: 'A guide for open and open-source developers to understand their requirements under the EU AI Act.',
37
- url: 'https://huggingface.co/spaces/hfmlsoc/os_gpai_guide_flowchart',
38
- areaTags: ['rights'],
39
- subAreaTags: ['specific', 'open'],
40
- embedUrl: "https://hfmlsoc-os-gpai-guide-flowchart.static.hf.space"
41
- },
42
- {
43
- title: 'SmolLM3-3B Public Summary of Training Content',
44
- type: 'space',
45
- date: '2025-07-25',
46
- description: 'A summary of the training content for SmolLM3-3B as required by the EU AI Act.',
47
- url: 'https://huggingface.co/spaces/hfmlsoc/smollm3-eu-data-transparency',
48
- areaTags: ['rights'],
49
- subAreaTags: ['specific'],
50
- embedUrl: "https://hfmlsoc-smollm3-eu-data-transparency.hf.space"
51
- },
52
- {
53
- title: 'Environmental Transparency Explorer Tool πŸ•΅οΈβ€β™€οΈπŸŒŽ',
54
- type: 'space',
55
- date: '2025-06-18',
56
- description: 'A tool for exploring the the data from \'Misinformation by Omission: The Need for More Environmental Transparency in AI\' showing trends in environmental transparency over time.',
57
- url: 'https://huggingface.co/spaces/sasha/environmental-transparency',
58
- areaTags: ['efficiency'],
59
- subAreaTags: ['measuring'],
60
- embedUrl: "https://sasha-environmental-transparency.hf.space"
61
- },
62
- {
63
- title: 'πŸ€— Space Privacy Analyzer πŸ•΅οΈ',
64
- type: 'space',
65
- date: '2025-04-14',
66
- description: 'A tool for analyzing data transfers and assessing potential privacy risks in Hugging Face Spaces.',
67
- url: 'https://huggingface.co/spaces/yjernite/space-privacy',
68
- areaTags: ['personal'],
69
- subAreaTags: ['privacy'],
70
- embedUrl: "https://yjernite-space-privacy.hf.space"
71
- },
72
- {
73
- title: 'AI Energy Score Leaderboard',
74
- type: 'space',
75
- date: '2024-09-30',
76
- description: 'A leaderboard for AI models across 9 common AI tasks based on the AI Energy Score methodology.',
77
- url: 'https://huggingface.co/spaces/AIEnergyScore/Leaderboard',
78
- areaTags: ['efficiency'],
79
- subAreaTags: ['measuring'],
80
- embedUrl: "https://aienergyscore-leaderboard.hf.space"
81
- },
82
- {
83
- title: 'CIVICS Civics Benchmark Dataset',
84
- type: 'dataset',
85
- date: '2024-04-29',
86
- description: 'β€œCIVICS: Culturally-Informed & Values-Inclusive Corpus for Societal Impacts” is a dataset designed to evaluate the social and cultural variation of Large Language Models (LLMs) towards socially sensitive topics across multiple languages and cultures. The hand-crafted, multilingual dataset of statements addresses value-laden topics, including LGBTQI rights, social welfare, immigration, disability rights, and surrogacy. CIVICS is designed to elicit responses from LLMs to shed light on how values encoded in their parameters shape their behaviors.',
87
- url: 'https://huggingface.co/datasets/llm-values/CIVICS',
88
- areaTags: ['personal'],
89
- subAreaTags: ['interaction']
90
- },
91
- {
92
- title: 'Stable Bias: Analyzing Societal Representations in Diffusion Models',
93
- type: 'space',
94
- date: '2023-08-11',
95
- description: 'An interactive presentation of the findings from the paper "Stable Bias: Analyzing Societal Representations in Diffusion Models".',
96
- url: 'https://huggingface.co/spaces/stable-bias/stable-bias',
97
- areaTags: ['personal'],
98
- subAreaTags: ['interaction'],
99
- embedUrl: "https://stable-bias-stable-bias.hf.space"
100
- },
101
- ];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/data/team.js CHANGED
@@ -1,30 +1,32 @@
1
  // team.js - Team member data
2
- import { areasData } from './areas.js';
 
 
3
 
4
  export const teamMembers = [
5
  {
6
  name: 'Yacine Jernite',
7
  role: 'Head of ML & Society',
8
  username: 'yjernite',
9
- tags: ['rights', 'ecosystems']
10
  },
11
  {
12
  name: 'Sasha Luccioni',
13
  role: 'AI & Climate Lead',
14
  username: 'sasha',
15
- tags: ['efficiency']
16
  },
17
  {
18
  name: 'Giada Pistilli',
19
  role: 'Principal Ethicist',
20
  username: 'giadap',
21
- tags: ['personal']
22
  },
23
  {
24
  name: 'Lucie-AimΓ©e Kaffee',
25
  role: 'Applied Policy Researcher, EU Policy',
26
  username: 'frimelle',
27
- tags: ['ecosystems', 'rights']
28
  }
29
  ];
30
 
 
1
  // team.js - Team member data
2
+
3
+ // Use global areasData (loaded in index.html <head>)
4
+ const areasData = window.areasData;
5
 
6
  export const teamMembers = [
7
  {
8
  name: 'Yacine Jernite',
9
  role: 'Head of ML & Society',
10
  username: 'yjernite',
11
+ tags: ['ecosystems'] // Updated: 'rights' merged into 'ecosystems'
12
  },
13
  {
14
  name: 'Sasha Luccioni',
15
  role: 'AI & Climate Lead',
16
  username: 'sasha',
17
+ tags: ['sustainability'] // Updated: 'efficiency' β†’ 'sustainability'
18
  },
19
  {
20
  name: 'Giada Pistilli',
21
  role: 'Principal Ethicist',
22
  username: 'giadap',
23
+ tags: ['agency'] // Updated: 'personal' β†’ 'agency'
24
  },
25
  {
26
  name: 'Lucie-AimΓ©e Kaffee',
27
  role: 'Applied Policy Researcher, EU Policy',
28
  username: 'frimelle',
29
+ tags: ['ecosystems'] // Updated: 'rights' merged into 'ecosystems'
30
  }
31
  ];
32
 
js/init.js ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // init.js - Data loading functions (pure library, no auto-execution)
2
+ // Called by bootstrap.js in the proper sequence
3
+
4
+ // Load artifacts from JSON
5
+ export async function loadArtifacts() {
6
+ try {
7
+ const response = await fetch('/data/artifacts.json');
8
+ if (!response.ok) {
9
+ throw new Error(`HTTP error! status: ${response.status}`);
10
+ }
11
+ const artifacts = await response.json();
12
+
13
+ // Make globally available
14
+ window.allArtifacts = artifacts;
15
+
16
+ return artifacts;
17
+ } catch (error) {
18
+ console.error('Failed to load artifacts:', error);
19
+ window.allArtifacts = [];
20
+ throw error;
21
+ }
22
+ }
23
+
24
+ // Helper functions for accessing loaded data
25
+ export function getArtifacts() {
26
+ return window.allArtifacts || [];
27
+ }
28
+
29
+ export function getFeaturedArtifacts() {
30
+ const artifacts = getArtifacts();
31
+ return artifacts
32
+ .filter(artifact => artifact.featured === true)
33
+ .sort((a, b) => new Date(b.date) - new Date(a.date));
34
+ }
35
+
36
+ export function getAreasData() {
37
+ return window.areasData || {};
38
+ }
39
+
40
+ // Legacy app object for backward compatibility with existing code
41
+ export const app = {
42
+ getArtifacts,
43
+ getFeaturedArtifacts,
44
+ getAreasData,
45
+ waitForInit: () => Promise.resolve() // No-op since bootstrap handles initialization
46
+ };
47
+
48
+ // Make available globally for non-module scripts
49
+ window.app = app;
50
+
js/main.js CHANGED
@@ -1,11 +1,25 @@
1
  // main.js
 
2
  import { teamMembers, teamTagData } from './data/team.js';
3
  import { initializeSearchUI } from './utils/search.js';
4
- import { overallBackgroundImage } from './data/areas.js';
5
- import { scrollToSection } from './utils/dom.js';
6
- import { updatePageBackgroundPosition } from './utils/router.js'; // Import the new function
7
 
8
- let allArtifactsData; // Declare a variable to hold the fetched artifacts
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
  // Team member component
11
  export function createTeamMember(name, role, hfUsername, tags) {
@@ -63,16 +77,6 @@ function scrollToTop() {
63
  // Make scrollToTop globally available
64
  window.scrollToTop = scrollToTop;
65
 
66
- // Initialize team members
67
- function initializeTeamMembers() {
68
- const teamContainer = document.getElementById('team-grid');
69
- if (!teamContainer) return;
70
-
71
- teamContainer.innerHTML = teamMembers.map(member =>
72
- createTeamMember(member.name, member.role, member.username, member.tags)
73
- ).join('');
74
- }
75
-
76
  // Note: Navigation handling moved to router.js for unified control
77
 
78
  // Initialize scroll to top button functionality
@@ -105,41 +109,30 @@ function initializeScrollToTop() {
105
  }
106
 
107
 
108
- // Main initialization
109
- document.addEventListener('DOMContentLoaded', async function() { // Mark as async
 
110
  const backgroundImg = document.querySelector('#overall-background img');
111
  if (backgroundImg) {
112
  backgroundImg.src = `images/${overallBackgroundImage.image}`;
113
  backgroundImg.alt = overallBackgroundImage.altText;
114
  }
115
 
116
- // Fetch artifacts once
117
- try {
118
- const response = await fetch('/data/artifacts.json');
119
- if (!response.ok) {
120
- throw new Error(`HTTP error! status: ${response.status}`);
121
- }
122
- allArtifactsData = await response.json();
123
- console.log('Artifacts loaded once in main.js:', allArtifactsData.length, 'items');
124
- } catch (error) {
125
- console.error('Failed to load artifacts in main.js:', error);
126
- allArtifactsData = [];
127
- }
128
-
129
- // Make allArtifactsData globally available for other modules
130
- window.allArtifacts = allArtifactsData;
131
-
132
  // Initialize scroll to top functionality
133
  initializeScrollToTop();
134
 
135
- // Initialize search UI, passing the loaded artifacts
136
- initializeSearchUI(allArtifactsData);
137
 
138
- // The router will handle page-specific component initialization
139
- // No need to call initializeTeamMembers, initializeHomeAreaCards, etc. here
140
- // as they will be called by the router when loading the home page
141
 
142
- // Search sidebar toggle functionality
 
 
 
 
 
143
  const searchToggle = document.getElementById('search-toggle');
144
  const searchSidebar = document.getElementById('search-sidebar');
145
  const searchClose = document.getElementById('search-close');
@@ -166,5 +159,4 @@ document.addEventListener('DOMContentLoaded', async function() { // Mark as asyn
166
  if (searchToggle) searchToggle.addEventListener('click', toggleSearch);
167
  if (searchClose) searchClose.addEventListener('click', toggleSearch);
168
  if (overlay) overlay.addEventListener('click', toggleSearch);
169
-
170
- });
 
1
  // main.js
2
+ import { app } from './init.js';
3
  import { teamMembers, teamTagData } from './data/team.js';
4
  import { initializeSearchUI } from './utils/search.js';
 
 
 
5
 
6
+ // Use global background image (loaded in index.html <head>)
7
+ const overallBackgroundImage = window.overallBackgroundImage;
8
+
9
+ // Scroll to section utility
10
+ export function scrollToSection(sectionId) {
11
+ const element = document.getElementById(sectionId);
12
+ if (element) {
13
+ const elementRect = element.getBoundingClientRect();
14
+ const absoluteElementTop = elementRect.top + window.pageYOffset;
15
+ const offset = 120; // Account for fixed header + some padding
16
+
17
+ window.scrollTo({
18
+ top: absoluteElementTop - offset,
19
+ behavior: 'smooth'
20
+ });
21
+ }
22
+ }
23
 
24
  // Team member component
25
  export function createTeamMember(name, role, hfUsername, tags) {
 
77
  // Make scrollToTop globally available
78
  window.scrollToTop = scrollToTop;
79
 
 
 
 
 
 
 
 
 
 
 
80
  // Note: Navigation handling moved to router.js for unified control
81
 
82
  // Initialize scroll to top button functionality
 
109
  }
110
 
111
 
112
+ // Main UI initialization - called by bootstrap.js
113
+ export async function initializeUI() {
114
+ // Set overall background image
115
  const backgroundImg = document.querySelector('#overall-background img');
116
  if (backgroundImg) {
117
  backgroundImg.src = `images/${overallBackgroundImage.image}`;
118
  backgroundImg.alt = overallBackgroundImage.altText;
119
  }
120
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  // Initialize scroll to top functionality
122
  initializeScrollToTop();
123
 
124
+ // Initialize search UI with loaded artifacts
125
+ initializeSearchUI(window.allArtifacts || []);
126
 
127
+ // Initialize search sidebar toggle
128
+ initializeSearchToggle();
 
129
 
130
+ // Note: The router handles page-specific component initialization
131
+ // (e.g., team members, area cards) when loading each page
132
+ }
133
+
134
+ // Search sidebar toggle functionality
135
+ function initializeSearchToggle() {
136
  const searchToggle = document.getElementById('search-toggle');
137
  const searchSidebar = document.getElementById('search-sidebar');
138
  const searchClose = document.getElementById('search-close');
 
159
  if (searchToggle) searchToggle.addEventListener('click', toggleSearch);
160
  if (searchClose) searchClose.addEventListener('click', toggleSearch);
161
  if (overlay) overlay.addEventListener('click', toggleSearch);
162
+ }
 
js/pages/AreaPage.js CHANGED
@@ -1,9 +1,11 @@
1
  // pages/AreaPage.js - Single-topic view for area pages
2
- import { areasData } from '../data/areas.js';
3
- import { featuredArtifacts } from '../data/artifacts.js';
4
  import { createArtifactCarousel } from '../cards/ArtifactSummaryCard.js';
5
- import { sampleResources } from '../data/resources.js';
6
- import { createResourceCard, initializeResourceCards } from '../cards/ResourceCard.js';
 
 
 
7
 
8
  export function renderAreaPage(areaId, topicId = null) {
9
  const area = areasData[areaId];
@@ -20,7 +22,7 @@ export function renderAreaPage(areaId, topicId = null) {
20
  }
21
 
22
  // Show specific topic
23
- const topic = area.subAreas[topicId];
24
  if (!topic) {
25
  return {
26
  content: `<div class="bg-white/90 backdrop-blur-md rounded-lg shadow-sm p-8 mx-4"><h1 class="text-2xl font-bold text-red-600">Topic not found</h1></div>`,
@@ -32,8 +34,8 @@ export function renderAreaPage(areaId, topicId = null) {
32
  }
33
 
34
  function renderAreaOverview(area, areaId) {
35
- // Get sub-areas as array
36
- const topics = Object.entries(area.subAreas).map(([key, value]) => ({
37
  id: key,
38
  name: typeof value === 'string' ? value : value.name,
39
  navName: typeof value === 'string' ? value : (value.navName || value.name),
@@ -45,78 +47,73 @@ function renderAreaOverview(area, areaId) {
45
  <!-- Top spacing -->
46
  <div class="mb-8"></div>
47
 
48
- <!-- Page Navigation Card -->
49
- <section class="mb-8 relative z-20 px-4 sm:px-6 lg:px-8">
50
- <div class="bg-white/70 backdrop-blur-sm shadow-sm rounded-lg px-6 py-4 w-full" style="max-width: min(90%, 1400px); margin: 0 auto;">
51
- <div class="flex items-center gap-3 overflow-x-auto">
52
- <span class="text-gray-600 font-semibold whitespace-nowrap">${area.navTitle}:</span>
53
- <a href="/${areaId}" class="px-3 py-1.5 text-sm font-semibold text-blue-600 underline decoration-2 underline-offset-2 hover:bg-blue-50 rounded transition-colors whitespace-nowrap">Overview</a>
54
- ${topics.map((topic, index) => `
55
- ${index === 0 ? '<span class="text-gray-300">β€’</span>' : ''}
56
- <a href="/${areaId}/${topic.id}" class="px-3 py-1.5 text-sm font-medium text-gray-700 hover:text-blue-600 hover:bg-blue-50 rounded transition-colors whitespace-nowrap">${topic.navName}</a>
57
- ${index < topics.length - 1 ? '<span class="text-gray-300">β€’</span>' : ''}
58
- `).join('')}
59
- </div>
60
- </div>
61
- </section>
62
 
63
- <!-- Area Overview Section -->
64
- <section id="overview" class="mb-16 relative z-20 px-4 sm:px-6 lg:px-8">
65
- <div class="bg-white/90 backdrop-blur-md shadow-sm rounded-lg p-6 md:p-10 w-full" style="max-width: min(90%, 1400px); margin: 0 auto;">
66
- <h1 class="text-3xl md:text-4xl font-bold text-gray-900 mb-6">${area.title}</h1>
67
-
68
- <!-- Area Description -->
69
- <div class="mb-8">
70
- <p class="text-gray-700 leading-relaxed">${area.description}</p>
71
- </div>
 
72
 
73
- <!-- Role of Openness -->
74
- ${area.openness ? `
75
- <div class="px-4 sm:px-6 py-5 bg-gradient-to-r from-orange-50/95 to-yellow-50/95 backdrop-blur-sm border-l-4 border-orange-400 rounded-r-lg mb-8">
76
- <p class="font-bold text-orange-900 mb-3 text-lg">πŸ€— The Role of Openness</p>
77
- <p class="text-orange-800 italic leading-relaxed">${area.openness}</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  </div>
79
- ` : ''}
80
-
81
- <!-- Topics within this area -->
82
- <div>
83
- <p class="text-xs font-semibold text-gray-600 uppercase tracking-wide mb-3">Topics in this area:</p>
84
- <div class="flex flex-wrap gap-2">
85
- ${topics.map(topic => {
86
- // Extract colors from topic.color
87
- let bgColor = 'bg-gray-200';
88
- let textColor = 'text-gray-700';
89
- if (topic.color) {
90
- const bgMatch = topic.color.match(/bg-(\w+)-(\d+)/);
91
- const textMatch = topic.color.match(/text-(\w+)-(\d+)/);
92
- if (bgMatch) bgColor = `bg-${bgMatch[1]}-${bgMatch[2]}`;
93
- if (textMatch) textColor = `text-${textMatch[1]}-700`;
94
- }
95
- return `
96
- <a href="/${areaId}/${topic.id}" class="inline-block px-3 py-1.5 text-sm ${bgColor} ${textColor} rounded hover:opacity-80 transition-opacity">
97
- ${topic.navName}
98
- </a>
99
- `;
100
- }).join('')}
101
- </div>
102
  </div>
103
  </div>
104
- </section>
105
  `;
106
 
107
  return {
108
  content,
109
- init: () => {}
 
 
110
  };
111
  }
112
 
113
  function renderTopicView(area, areaId, topic, topicId) {
114
  const topicName = topic.navName || topic.name;
115
- const topicDescription = topic.description || '';
116
- const topicOpenness = topic.openness || '';
 
117
 
118
  // Get all topics for navigation
119
- const allTopics = Object.entries(area.subAreas).map(([key, value]) => ({
120
  id: key,
121
  navName: typeof value === 'string' ? value : (value.navName || value.name)
122
  }));
@@ -125,54 +122,30 @@ function renderTopicView(area, areaId, topic, topicId) {
125
  <!-- Top spacing -->
126
  <div class="mb-8"></div>
127
 
128
- <!-- Page Navigation Card -->
129
- <section class="mb-8 relative z-20 px-4 sm:px-6 lg:px-8">
130
- <div class="bg-white/70 backdrop-blur-sm shadow-sm rounded-lg px-6 py-4 w-full" style="max-width: min(90%, 1400px); margin: 0 auto;">
131
- <div class="flex items-center gap-3 overflow-x-auto">
132
- <span class="text-gray-600 font-semibold whitespace-nowrap">${area.navTitle}:</span>
133
- <a href="/${areaId}" class="px-3 py-1.5 text-sm font-medium text-gray-700 hover:text-blue-600 hover:bg-blue-50 rounded transition-colors whitespace-nowrap">Overview</a>
134
- ${allTopics.map((t, index) => `
135
- ${index === 0 ? '<span class="text-gray-300">β€’</span>' : ''}
136
- <a href="/${areaId}/${t.id}" class="px-3 py-1.5 text-sm font-medium transition-colors whitespace-nowrap rounded ${t.id === topicId ? 'text-blue-600 font-semibold underline decoration-2 underline-offset-2' : 'text-gray-700 hover:text-blue-600 hover:bg-blue-50'}">${t.navName}</a>
137
- ${index < allTopics.length - 1 ? '<span class="text-gray-300">β€’</span>' : ''}
138
- `).join('')}
139
- </div>
140
- </div>
141
- </section>
142
 
143
- <!-- Topic Content Section -->
144
- <section id="${topicId}" class="mb-16 relative z-20 px-4 sm:px-6 lg:px-8">
145
- <div class="bg-white/80 backdrop-blur-md shadow-sm rounded-lg p-6 md:p-10 w-full" style="max-width: min(90%, 1400px); margin: 0 auto;">
146
- <!-- Breadcrumb -->
147
- <div class="mb-4 text-sm text-gray-600">
148
- <a href="/${areaId}" class="hover:text-blue-600 transition-colors">${area.navTitle}</a>
149
- <span class="mx-2">β€Ί</span>
150
- <span class="text-gray-900 font-medium">${topicName}</span>
151
- </div>
152
-
153
- <h1 class="text-3xl md:text-4xl font-bold text-gray-900 mb-6">${topic.name}</h1>
154
-
155
- <!-- Topic Description -->
156
- ${topicDescription ? `
157
- <div class="mb-8">
158
- <p class="text-gray-700 leading-relaxed">${topicDescription}</p>
159
- </div>
160
- ` : ''}
161
 
162
- <!-- Role of Openness for this topic -->
163
- ${topicOpenness ? `
164
- <div class="px-4 sm:px-6 py-5 bg-gradient-to-r from-orange-50/95 to-yellow-50/95 backdrop-blur-sm border-l-4 border-orange-400 rounded-r-lg mb-8">
165
- <p class="font-bold text-orange-900 mb-3 text-lg">πŸ€— The Role of Openness</p>
166
- <p class="text-orange-800 italic leading-relaxed">${topicOpenness}</p>
167
- </div>
168
- ` : ''}
 
169
 
170
- <h3 class="text-xl md:text-2xl font-bold text-gray-900 mb-6">Related Research & Resources</h3>
171
- <div id="${topicId}-artifacts-carousel" class="overflow-x-auto -mx-2">
172
- <!-- Carousel will be inserted here -->
173
- </div>
174
  </div>
175
- </section>
176
  `;
177
 
178
  return {
@@ -197,13 +170,43 @@ function renderTopicView(area, areaId, topic, topicId) {
197
  }));
198
 
199
  const carouselId = `${topicId}-artifacts-carousel`;
200
- createArtifactCarousel(transformedArtifacts.length > 0 ? transformedArtifacts : featuredArtifacts, carouselId);
201
  } catch (error) {
202
  console.error(`Error creating carousel for ${topicId}:`, error);
203
  const carouselId = `${topicId}-artifacts-carousel`;
204
- createArtifactCarousel(featuredArtifacts, carouselId);
205
  }
206
  }, 50);
207
  }
208
  };
209
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  // pages/AreaPage.js - Single-topic view for area pages
2
+ import { getFeaturedArtifacts } from '../init.js';
 
3
  import { createArtifactCarousel } from '../cards/ArtifactSummaryCard.js';
4
+ import { renderAreaNavigation } from '../components/PageNavigation.js';
5
+ import { renderContentSection, renderOpennessCallout } from '../components/ContentSection.js';
6
+
7
+ // Use global areasData (loaded in index.html <head>)
8
+ const areasData = window.areasData;
9
 
10
  export function renderAreaPage(areaId, topicId = null) {
11
  const area = areasData[areaId];
 
22
  }
23
 
24
  // Show specific topic
25
+ const topic = area.topics[topicId];
26
  if (!topic) {
27
  return {
28
  content: `<div class="bg-white/90 backdrop-blur-md rounded-lg shadow-sm p-8 mx-4"><h1 class="text-2xl font-bold text-red-600">Topic not found</h1></div>`,
 
34
  }
35
 
36
  function renderAreaOverview(area, areaId) {
37
+ // Get topics as array
38
+ const topics = Object.entries(area.topics).map(([key, value]) => ({
39
  id: key,
40
  name: typeof value === 'string' ? value : value.name,
41
  navName: typeof value === 'string' ? value : (value.navName || value.name),
 
47
  <!-- Top spacing -->
48
  <div class="mb-8"></div>
49
 
50
+ ${renderAreaNavigation(areaId, area.navTitle, topics, null)}
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
+ ${renderContentSection('overview', `
53
+ <h1 class="text-3xl md:text-4xl font-bold text-gray-900 mb-6">${area.title}</h1>
54
+
55
+ <!-- Area Description -->
56
+ <div class="mb-8">
57
+ ${area.description.paragraphs ?
58
+ area.description.paragraphs.map(p => `<p class="text-gray-700 leading-relaxed mb-4">${p}</p>`).join('')
59
+ : `<p class="text-gray-700 leading-relaxed">${area.description.short || area.description}</p>`
60
+ }
61
+ </div>
62
 
63
+ <!-- Topics within this area -->
64
+ <div class="mb-8">
65
+ <p class="text-xs font-semibold text-gray-600 uppercase tracking-wide mb-3">Topics in this area:</p>
66
+ <div class="flex flex-wrap gap-2">
67
+ ${topics.map(topic => {
68
+ // Extract colors from topic.color
69
+ let bgColor = 'bg-gray-200';
70
+ let textColor = 'text-gray-700';
71
+ if (topic.color) {
72
+ const bgMatch = topic.color.match(/bg-(\w+)-(\d+)/);
73
+ const textMatch = topic.color.match(/text-(\w+)-(\d+)/);
74
+ if (bgMatch) bgColor = `bg-${bgMatch[1]}-${bgMatch[2]}`;
75
+ if (textMatch) textColor = `text-${textMatch[1]}-700`;
76
+ }
77
+
78
+ // Get short description for tooltip
79
+ const shortDesc = topic.description?.short || (typeof topic.description === 'string' ? topic.description.split('.')[0] + '.' : '');
80
+ const titleAttr = shortDesc ? ` title="${shortDesc}"` : '';
81
+
82
+ return `
83
+ <a href="/${areaId}/${topic.id}" class="inline-block px-3 py-1.5 text-sm ${bgColor} ${textColor} rounded hover:opacity-80 transition-opacity"${titleAttr}>
84
+ ${topic.navName}
85
+ </a>
86
+ `;
87
+ }).join('')}
88
  </div>
89
+ </div>
90
+
91
+ <!-- Research and Resources -->
92
+ <div>
93
+ <p class="text-xs font-semibold text-gray-600 uppercase tracking-wide mb-3">Research and Resources:</p>
94
+ <div id="area-artifacts-carousel-${areaId}" class="overflow-x-auto -mx-2">
95
+ <!-- Carousel will be inserted here -->
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  </div>
97
  </div>
98
+ `)}
99
  `;
100
 
101
  return {
102
  content,
103
+ init: () => {
104
+ initializeAreaArtifactsCarousel(areaId);
105
+ }
106
  };
107
  }
108
 
109
  function renderTopicView(area, areaId, topic, topicId) {
110
  const topicName = topic.navName || topic.name;
111
+ const topicDescription = topic.description?.paragraphs
112
+ ? topic.description.paragraphs.map(p => `<p class="text-gray-700 leading-relaxed mb-4">${p}</p>`).join('')
113
+ : (topic.description?.short || topic.description || '');
114
 
115
  // Get all topics for navigation
116
+ const allTopics = Object.entries(area.topics).map(([key, value]) => ({
117
  id: key,
118
  navName: typeof value === 'string' ? value : (value.navName || value.name)
119
  }));
 
122
  <!-- Top spacing -->
123
  <div class="mb-8"></div>
124
 
125
+ ${renderAreaNavigation(areaId, area.navTitle, allTopics, topicId)}
 
 
 
 
 
 
 
 
 
 
 
 
 
126
 
127
+ ${renderContentSection(topicId, `
128
+ <!-- Breadcrumb -->
129
+ <div class="mb-4 text-sm text-gray-600">
130
+ <a href="/${areaId}" class="hover:text-blue-600 transition-colors">${area.navTitle}</a>
131
+ <span class="mx-2">β€Ί</span>
132
+ <span class="text-gray-900 font-medium">${topicName}</span>
133
+ </div>
 
 
 
 
 
 
 
 
 
 
 
134
 
135
+ <h1 class="text-3xl md:text-4xl font-bold text-gray-900 mb-6">${topic.name}</h1>
136
+
137
+ <!-- Topic Description -->
138
+ ${topicDescription ? `
139
+ <div class="mb-8">
140
+ ${topicDescription}
141
+ </div>
142
+ ` : ''}
143
 
144
+ <h3 class="text-xl md:text-2xl font-bold text-gray-900 mb-6">Related Research & Resources</h3>
145
+ <div id="${topicId}-artifacts-carousel" class="overflow-x-auto -mx-2">
146
+ <!-- Carousel will be inserted here -->
 
147
  </div>
148
+ `)}
149
  `;
150
 
151
  return {
 
170
  }));
171
 
172
  const carouselId = `${topicId}-artifacts-carousel`;
173
+ createArtifactCarousel(transformedArtifacts.length > 0 ? transformedArtifacts : getFeaturedArtifacts(), carouselId);
174
  } catch (error) {
175
  console.error(`Error creating carousel for ${topicId}:`, error);
176
  const carouselId = `${topicId}-artifacts-carousel`;
177
+ createArtifactCarousel(getFeaturedArtifacts(), carouselId);
178
  }
179
  }, 50);
180
  }
181
  };
182
  }
183
+
184
+ // Helper function to initialize area artifacts carousel
185
+ function initializeAreaArtifactsCarousel(areaId) {
186
+ // Wait for DOM to be ready
187
+ setTimeout(() => {
188
+ try {
189
+ const allArtifacts = window.allArtifacts || [];
190
+
191
+ // Filter artifacts by area
192
+ const filteredArtifacts = allArtifacts.filter(artifact =>
193
+ artifact.areas && artifact.areas.includes(areaId)
194
+ );
195
+
196
+ // Transform field names to match what the carousel expects
197
+ const transformedArtifacts = filteredArtifacts.map(artifact => ({
198
+ ...artifact,
199
+ areaTags: artifact.areas,
200
+ subAreaTags: artifact.topics,
201
+ sourceUrl: artifact.url
202
+ }));
203
+
204
+ const carouselId = `area-artifacts-carousel-${areaId}`;
205
+ createArtifactCarousel(transformedArtifacts.length > 0 ? transformedArtifacts : getFeaturedArtifacts(), carouselId);
206
+ } catch (error) {
207
+ console.error(`Error creating carousel for area ${areaId}:`, error);
208
+ const carouselId = `area-artifacts-carousel-${areaId}`;
209
+ createArtifactCarousel(getFeaturedArtifacts(), carouselId);
210
+ }
211
+ }, 50);
212
+ }
js/pages/HomePage.js CHANGED
@@ -1,94 +1,76 @@
1
  // pages/HomePage.js - Home page functionality for SPA
2
  import { createTeamMember } from '../main.js';
3
- import { createHomeAreaCard } from '../cards/HomeAreaCard.js';
4
  import { createArtifactCarousel } from '../cards/ArtifactSummaryCard.js';
5
- import { areasData, homeBackgroundImage } from '../data/areas.js';
6
- import { featuredArtifacts } from '../data/artifacts.js';
7
  import { teamMembers } from '../data/team.js';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
  export function renderHomePage() {
10
  const content = `
11
  <!-- Top spacing -->
12
  <div class="mb-8"></div>
13
 
14
- <!-- Page Navigation Card -->
15
- <section class="mb-8 relative z-20 px-4 sm:px-6 lg:px-8">
16
- <div class="bg-white/70 backdrop-blur-sm shadow-sm rounded-lg px-6 py-4 w-full" style="max-width: min(90%, 1400px); margin: 0 auto;">
17
- <div class="flex items-center gap-3 overflow-x-auto">
18
- <span class="text-gray-600 font-semibold whitespace-nowrap">On this page:</span>
19
- <a href="/#about" class="px-3 py-1.5 text-sm font-medium text-gray-700 hover:text-blue-600 hover:bg-blue-50 rounded transition-colors whitespace-nowrap">About</a>
20
- <span class="text-gray-300">β€’</span>
21
- <a href="/#recent-works" class="px-3 py-1.5 text-sm font-medium text-gray-700 hover:text-blue-600 hover:bg-blue-50 rounded transition-colors whitespace-nowrap">Recent Works</a>
22
- <span class="text-gray-300">β€’</span>
23
- <a href="/#research-areas" class="px-3 py-1.5 text-sm font-medium text-gray-700 hover:text-blue-600 hover:bg-blue-50 rounded transition-colors whitespace-nowrap">Research Areas</a>
24
- <span class="text-gray-300">β€’</span>
25
- <a href="/#team" class="px-3 py-1.5 text-sm font-medium text-gray-700 hover:text-blue-600 hover:bg-blue-50 rounded transition-colors whitespace-nowrap">Team Members</a>
26
- </div>
27
- </div>
28
- </section>
29
 
30
- <!-- About Section - Responsive Width with Frosted Glass -->
31
- <section id="about" class="mb-16 relative z-20 px-4 sm:px-6 lg:px-8">
32
- <div class="bg-white/40 backdrop-blur-sm shadow-sm rounded-lg p-6 md:p-10 w-full" style="max-width: min(90%, 1400px); margin: 0 auto;">
33
- <h2 class="text-3xl md:text-4xl font-bold text-gray-900 mb-6">About</h2>
 
 
 
34
 
35
- <!-- Introduction Text - Single column -->
36
- <div class="mb-8">
37
- <div>
38
- <p class="text-gray-700 leading-relaxed">
39
- We're a multidisciplinary team working on research and regulatory questions related to AI systems &mdash; their (open) development, governance, and impact on society at large.
40
- Our work spans four key inter-connected areas where AI technology intersects with society:
41
- </p>
42
- </div>
43
- </div>
44
-
45
- <!-- Perspective and Positionality -->
46
- <div class="px-4 sm:px-6 py-5 bg-gradient-to-r from-orange-50/95 to-yellow-50/95 backdrop-blur-sm border-l-4 border-orange-400 rounded-r-lg">
47
- <p class="font-bold text-orange-900 mb-3 text-lg">πŸ€— Perspective and Positionality</p>
48
- <p class="text-orange-800 italic leading-relaxed">
49
- Our work on these topics is shaped by the context of our work at Hugging Face, which is the main platform for open and collaborative development and sharing of Artificial Intelligence artifacts. As a result, much of our work discusses the specific roles of openness and transparency in shaping AI technology into a more equitable and better-governed category of technology.
50
- </p>
51
- </div>
52
  </div>
53
- </section>
54
-
55
- <!-- Featured Works Section - Transparent Card -->
56
- <section id="recent-works" class="mb-16 relative z-20 px-4 sm:px-6 lg:px-8">
57
- <div class="bg-white/20 backdrop-blur-sm shadow-sm rounded-lg p-6 md:p-10 w-full" style="max-width: min(90%, 1400px); margin: 0 auto;">
58
- <h2 class="text-3xl md:text-4xl font-bold text-gray-900 mb-6">Recent & Featured Works</h2>
59
- <div id="featured-artifacts-carousel" class="overflow-x-auto -mx-2">
60
- <!-- Carousel will be inserted here -->
61
- </div>
62
  </div>
63
- </section>
64
 
65
- <!-- Research Areas Section - Transparent Card with 2x2 Grid -->
66
- <section id="research-areas" class="mb-16 relative z-20 px-4 sm:px-6 lg:px-8">
67
- <div class="bg-white/20 backdrop-blur-sm shadow-sm rounded-lg p-6 md:p-10 w-full" style="max-width: min(90%, 1400px); margin: 0 auto;">
68
- <h2 class="text-3xl md:text-4xl font-bold text-gray-900 mb-8 text-center">Research Areas</h2>
69
- <div id="research-areas-grid" class="grid grid-cols-1 md:grid-cols-2 gap-4 sm:gap-6">
70
- <!-- Area cards will be inserted here by JavaScript -->
71
- </div>
72
  </div>
73
- </section>
74
-
75
- <!-- Team Members Section - Frosted Background -->
76
- <section id="team" class="mb-16 relative z-20 px-4 sm:px-6 lg:px-8">
77
- <div class="bg-white/40 backdrop-blur-sm shadow-sm rounded-lg p-6 md:p-10 w-full" style="max-width: min(90%, 1400px); margin: 0 auto;">
78
- <h2 class="text-3xl md:text-4xl font-bold text-gray-900 mb-6">Team Members</h2>
79
- <div id="team-grid" class="grid grid-cols-1 md:grid-cols-2 gap-4 sm:gap-6 mb-6">
80
- <!-- Team members will be inserted here by JavaScript -->
81
- </div>
82
- <div class="prose max-w-none text-gray-700 pt-4 border-t border-gray-200">
83
- <p>We also work closely with
84
- <a href="https://huggingface.co/irenesolaiman" class="text-blue-600 hover:text-blue-800 transition-colors" target="_blank">Irene Solaiman</a> (Chief Policy Officer),
85
- <a href="https://huggingface.co/evijit" class="text-blue-600 hover:text-blue-800 transition-colors" target="_blank">Avijit Ghosh</a> (Applied Policy Researcher) in the policy team,
86
- and with <a href="https://huggingface.co/meg" class="text-blue-600 hover:text-blue-800 transition-colors" target="_blank">Meg Mitchell</a> (Chief Ethics Scientist),
87
- and with <a href="https://huggingface.co/brunatrevelin" class="text-blue-600 hover:text-blue-800 transition-colors" target="_blank">Bruna Trevelin</a> (Legal Counsel)!
88
- </p>
89
- </div>
90
  </div>
91
- </section>
 
 
 
 
 
 
 
 
92
  `;
93
 
94
  return {
@@ -113,16 +95,6 @@ function initializeTeamMembers() {
113
  ).join('');
114
  }
115
 
116
- function getAreaShortDescription(areaId) {
117
- const descriptions = {
118
- efficiency: 'Costs, energy, sustainability',
119
- personal: 'Personal interactions, agency',
120
- rights: 'Legal frameworks, compliance',
121
- ecosystems: 'Markets, labor, and adoption dynamics'
122
- };
123
- return descriptions[areaId] || '';
124
- }
125
-
126
  function initializeHomeAreaCards() {
127
  const areasContainer = document.getElementById('research-areas-grid');
128
  if (!areasContainer) return;
@@ -132,87 +104,16 @@ function initializeHomeAreaCards() {
132
  }
133
 
134
  function createResearchAreaCard(area) {
135
- // Get first sentence of description
136
- const shortDesc = area.description.split('.')[0] + '.';
137
-
138
- // Get topic names and colors from the subAreas - same logic as ArtifactSummaryCard
139
- const topics = Object.values(area.subAreas).map(subArea => {
140
- const topicName = subArea.navName || subArea.name;
141
- let bgColor = 'bg-gray-200';
142
- let textColor = 'text-gray-700';
143
-
144
- // Extract background and text color from the subArea color class
145
- if (subArea.color) {
146
- // Match pattern like "bg-emerald-100 text-emerald-800"
147
- const bgMatch = subArea.color.match(/bg-(\w+)-(\d+)/);
148
- const textMatch = subArea.color.match(/text-(\w+)-(\d+)/);
149
-
150
- if (bgMatch) {
151
- bgColor = `bg-${bgMatch[1]}-${bgMatch[2]}`;
152
- }
153
- if (textMatch) {
154
- textColor = `text-${textMatch[1]}-700`; // Use consistent 700 shade like artifact cards
155
- }
156
- }
157
-
158
- return {
159
- name: topicName,
160
- bgColor,
161
- textColor
162
- };
163
- });
164
-
165
- return `
166
- <a href="/${area.id}"
167
- class="group relative block border border-gray-200 rounded-lg overflow-hidden bg-white hover:shadow-lg transition-all duration-200 h-64">
168
-
169
- <!-- Background image with low opacity -->
170
- ${area.image ? `
171
- <div class="absolute inset-0 opacity-15 group-hover:opacity-30 transition-opacity">
172
- <img src="/images/${area.image}" alt="" class="w-full h-full object-cover">
173
- </div>
174
- ` : ''}
175
-
176
- <!-- Content -->
177
- <div class="relative p-5 h-full flex flex-col">
178
- <!-- Header -->
179
- <div class="flex justify-between items-start mb-3 flex-shrink-0">
180
- <h3 class="text-lg font-bold text-gray-900 leading-tight">${area.navTitle}</h3>
181
- <svg class="w-5 h-5 text-gray-400 group-hover:text-blue-600 transition-colors flex-shrink-0 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
182
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
183
- </svg>
184
- </div>
185
-
186
- <!-- Description - scrollable -->
187
- <div class="text-md text-gray-700 mb-4 flex-grow overflow-y-auto pr-2">
188
- <p class="leading-relaxed">${area.description}</p>
189
- </div>
190
-
191
- <!-- Topics with colors from subAreas - same style as artifact cards -->
192
- <div class="flex-shrink-0">
193
- <p class="text-xs font-semibold text-gray-600 uppercase tracking-wide mb-2">Topics:</p>
194
- <div class="flex flex-wrap gap-2">
195
- ${topics.map(topic => `
196
- <span class="inline-block px-2 py-0.5 text-sm ${topic.bgColor} ${topic.textColor} rounded">
197
- ${topic.name}
198
- </span>
199
- `).join('')}
200
- </div>
201
- </div>
202
-
203
- <!-- Image Attribution -->
204
- ${area.imageAttribution ? `
205
- <p class="text-xs text-gray-500 mt-3 pt-2 border-t border-gray-100 flex-shrink-0">${area.imageAttribution}</p>
206
- ` : ''}
207
- </div>
208
- </a>
209
- `;
210
  }
211
 
212
  function initializeArtifactCarousels() {
213
  const carouselContainer = document.getElementById('featured-artifacts-carousel');
214
  if (!carouselContainer) return;
215
 
 
 
216
  createArtifactCarousel(featuredArtifacts, 'featured-artifacts-carousel');
217
  }
218
 
 
1
  // pages/HomePage.js - Home page functionality for SPA
2
  import { createTeamMember } from '../main.js';
 
3
  import { createArtifactCarousel } from '../cards/ArtifactSummaryCard.js';
4
+ import { getFeaturedArtifacts } from '../init.js';
 
5
  import { teamMembers } from '../data/team.js';
6
+ import { renderAreaCard } from '../components/Card.js';
7
+ import { renderHomeNavigation } from '../components/PageNavigation.js';
8
+ import { renderContentSection, renderOpennessCallout } from '../components/ContentSection.js';
9
+
10
+ // Use global areasData and backgrounds (loaded in index.html <head>)
11
+ const areasData = window.areasData;
12
+ const homeBackgroundImage = window.homeBackgroundImage;
13
+
14
+ // Helper function to create inline styled links
15
+ function createInlineLink(text, href, colorClass = '', tooltip = '') {
16
+ const baseClass = 'inline-block px-2 py-0.5 mx-0.5 text-sm font-medium rounded hover:opacity-80 transition-opacity no-underline';
17
+ const titleAttr = tooltip ? ` title="${tooltip}"` : '';
18
+ return `<a href="${href}" class="${baseClass} ${colorClass}"${titleAttr}>${text}</a>`;
19
+ }
20
 
21
  export function renderHomePage() {
22
  const content = `
23
  <!-- Top spacing -->
24
  <div class="mb-8"></div>
25
 
26
+ ${renderHomeNavigation()}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
28
+ ${renderContentSection('about-and-works', `
29
+ <h3 id="about" class="text-xl md:text-2xl font-bold text-gray-900 mb-8 text-center">About</h3>
30
+
31
+ <div class="space-y-2 text-gray-700 leading-relaxed mb-8">
32
+ <p>
33
+ With the rapid evolution of Artificial Intelligence over the last five years – and particularly its shift from Machine Learning as a behind-the-scenes organizing principle of our digital infrastructure to the more visible "generative AI" systems sold as consumer products – the interaction modes between the technology and its social contexts have expanded drastically.
34
+ </p>
35
 
36
+ <p>
37
+ Technology developers have a role to play in fostering more positive outcomes for these interactions; but they cannot be the sole deciders. However, for co-development to occur in meaningful ways between different kinds of stakeholders – with potentially diverging interests – it needs to be grounded in a common understanding of the technology and ability to investigate and modify technical systems. This is greatly facilitated by artificial intelligence models, datasets, and systems that are openly and collaboratively developed.
38
+ </p>
39
+
40
+ <p>
41
+ In addition to the work of the entire ${createInlineLink('Hugging Face', 'https://huggingface.co', 'bg-yellow-100 text-yellow-800')} team to support the development and sharing of such systems, the ${createInlineLink('Machine Learning and Society Team', '/', 'bg-blue-100 text-blue-800')} works on projects targeting the boundaries between technology and society more specifically. This includes work on the ${createInlineLink('Sustainability', '/sustainability', areasData.sustainability.color, areasData.sustainability.description.short)} of the technology, addressing its financial and environmental costs and investigating methods to manage its footprint, work on how ${createInlineLink('Agency', '/agency', areasData.agency.color, areasData.agency.description.short)} over artificial intelligence systems (or lack thereof) plays out for individual and communities, and work on how the economic and regulatory ${createInlineLink('Ecosystems of AI', '/ecosystems', areasData.ecosystems.color, areasData.ecosystems.description.short)} shape who benefits most or least from the technology.
42
+ </p>
43
+
44
+ <p>
45
+ This work is shaped by different aspects of openness, from transparency to collaboration to ease of access. Beyond producing research and tools that we hope will support more distributed development of the technology, we strongly invite collaborations on shared resources with all categories of expertise.
46
+ </p>
 
 
 
 
 
 
47
  </div>
48
+
49
+ <h3 id="recent-works" class="text-xl md:text-2xl font-bold text-gray-900 mb-8 text-center mt-8 pt-8 border-t border-gray-200">Recent & Featured Works</h3>
50
+ <div id="featured-artifacts-carousel" class="overflow-x-auto -mx-2">
51
+ <!-- Carousel will be inserted here -->
 
 
 
 
 
52
  </div>
53
+ `)}
54
 
55
+ ${renderContentSection('areas-and-team', `
56
+ <h3 id="research-areas" class="text-xl md:text-2xl font-bold text-gray-900 mb-8 text-center">Research Areas</h3>
57
+ <div id="research-areas-grid" class="grid grid-cols-1 md:grid-cols-3 gap-4 sm:gap-6 mb-8">
58
+ <!-- Area cards will be inserted here by JavaScript -->
 
 
 
59
  </div>
60
+
61
+ <h3 id="team" class="text-xl md:text-2xl font-bold text-gray-900 mb-8 text-center mt-8 pt-8 border-t border-gray-200">Team Members</h3>
62
+ <div id="team-grid" class="grid grid-cols-1 md:grid-cols-2 gap-4 sm:gap-6 mb-6">
63
+ <!-- Team members will be inserted here by JavaScript -->
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  </div>
65
+ <div class="prose max-w-none text-gray-700 pt-4 border-t border-gray-200">
66
+ <p>We also work closely with
67
+ <a href="https://huggingface.co/irenesolaiman" class="text-blue-600 hover:text-blue-800 transition-colors" target="_blank">Irene Solaiman</a> (Chief Policy Officer),
68
+ <a href="https://huggingface.co/evijit" class="text-blue-600 hover:text-blue-800 transition-colors" target="_blank">Avijit Ghosh</a> (Applied Policy Researcher) in the policy team,
69
+ and with <a href="https://huggingface.co/meg" class="text-blue-600 hover:text-blue-800 transition-colors" target="_blank">Meg Mitchell</a> (Chief Ethics Scientist),
70
+ and with <a href="https://huggingface.co/brunatrevelin" class="text-blue-600 hover:text-blue-800 transition-colors" target="_blank">Bruna Trevelin</a> (Legal Counsel)!
71
+ </p>
72
+ </div>
73
+ `)}
74
  `;
75
 
76
  return {
 
95
  ).join('');
96
  }
97
 
 
 
 
 
 
 
 
 
 
 
98
  function initializeHomeAreaCards() {
99
  const areasContainer = document.getElementById('research-areas-grid');
100
  if (!areasContainer) return;
 
104
  }
105
 
106
  function createResearchAreaCard(area) {
107
+ // Use the unified Card component
108
+ return renderAreaCard(area);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  }
110
 
111
  function initializeArtifactCarousels() {
112
  const carouselContainer = document.getElementById('featured-artifacts-carousel');
113
  if (!carouselContainer) return;
114
 
115
+ // Get featured artifacts dynamically from the loaded JSON data
116
+ const featuredArtifacts = getFeaturedArtifacts();
117
  createArtifactCarousel(featuredArtifacts, 'featured-artifacts-carousel');
118
  }
119
 
js/pages/ResourcesPage.js CHANGED
@@ -1,52 +1,15 @@
1
  // pages/ResourcesPage.js - Resources page functionality for SPA
2
- import { homeBackgroundImage, areasData } from '../data/areas.js';
3
  import { pressMentions } from '../data/press.js';
4
- import { sampleResources } from '../data/resources.js';
5
- import { createResourceCard, initializeResourceCards } from '../cards/ResourceCard.js';
 
 
 
 
6
 
7
  export function renderResourcesPage() {
8
  const content = `
9
- <!-- Technical Resources Section -->
10
- <section id="technical-resources" class="mb-12 relative z-20">
11
- <div class="bg-white bg-opacity-90 backdrop-blur-sm rounded-lg shadow-sm p-8">
12
- <h2 class="text-3xl font-bold text-gray-900 mb-6">Technical Resources</h2>
13
-
14
- <div class="mb-8">
15
- <p class="text-gray-700 leading-relaxed mb-6">
16
- Our team develops technical artifacts in the course of their research and policy work.
17
- These resources include datasets, tools, benchmarks, and interactive applications that
18
- support transparency, reproducibility, and accessibility in AI research and governance.
19
- </p>
20
- </div>
21
-
22
- <!-- Resource Cards Carousel -->
23
- <div class="relative">
24
- <div class="resource-carousel-container overflow-hidden" style="width: calc(100% - 2rem); margin: 0 auto;">
25
- <div class="resource-carousel flex gap-6 transition-transform duration-300 ease-in-out" style="width: ${sampleResources.length * 624}px;">
26
- ${sampleResources.map(resource => createResourceCard(resource)).join('')}
27
- </div>
28
- </div>
29
-
30
- <!-- Carousel Navigation -->
31
- <div class="flex justify-center mt-4 space-x-2">
32
- <button class="resource-carousel-prev bg-gray-200 hover:bg-gray-300 text-gray-700 px-3 py-2 rounded-md transition-colors">
33
- <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
34
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
35
- </svg>
36
- </button>
37
- <button class="resource-carousel-next bg-gray-200 hover:bg-gray-300 text-gray-700 px-3 py-2 rounded-md transition-colors">
38
- <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
39
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
40
- </svg>
41
- </button>
42
- </div>
43
- </div>
44
- </div>
45
- </section>
46
-
47
- <!-- Press Mentions Section -->
48
- <section id="press-mentions" class="mb-12 relative z-20">
49
- <div class="bg-white bg-opacity-90 backdrop-blur-sm rounded-lg shadow-sm p-8">
50
  <h2 class="text-3xl font-bold text-gray-900 mb-6">Press Mentions</h2>
51
 
52
  <div class="space-y-3">
@@ -68,36 +31,8 @@ export function renderResourcesPage() {
68
  day: 'numeric'
69
  });
70
 
71
- // Generate area tags
72
- const areaTagsHtml = article.areaTags.map(areaId => {
73
- const area = areasData[areaId];
74
- if (!area) return '';
75
- return `<span class="px-2 py-1 rounded-full text-xs font-medium ${area.colors.medium}">${area.name}</span>`;
76
- }).join('');
77
-
78
- // Generate sub-area tags
79
- const subAreaTagsHtml = article.subAreaTags.map(subAreaKey => {
80
- // Find the sub-area name and color by looking through all areas
81
- let subAreaName = subAreaKey; // fallback to key if not found
82
- let textColor = 'text-gray-700'; // fallback color
83
-
84
- for (const areaKey in areasData) {
85
- const area = areasData[areaKey];
86
- if (area.subAreas && area.subAreas[subAreaKey]) {
87
- const subArea = area.subAreas[subAreaKey];
88
- subAreaName = typeof subArea === 'string' ? subArea : subArea.name;
89
- // Extract just the text color from the sub-area color
90
- if (typeof subArea === 'object' && subArea.color) {
91
- const colorMatch = subArea.color.match(/text-(\w+)-(\d+)/);
92
- if (colorMatch) {
93
- textColor = `text-${colorMatch[1]}-700`; // Use consistent 700 shade
94
- }
95
- }
96
- break;
97
- }
98
- }
99
- return `<span class="inline-block px-2 py-0.5 text-xs bg-gray-200 ${textColor} rounded">${subAreaName}</span>`;
100
- }).join('');
101
 
102
  return `
103
  <!-- Press Article ${index + 1} - ${isLeftAligned ? 'Left' : 'Right'} aligned -->
@@ -138,8 +73,7 @@ export function renderResourcesPage() {
138
  `;
139
  }).join('')}
140
  </div>
141
- </div>
142
- </section>
143
  `;
144
 
145
  return {
@@ -147,10 +81,6 @@ export function renderResourcesPage() {
147
  init: () => {
148
  // Initialize background attribution
149
  initializeResourcesBackgroundAttribution();
150
- // Initialize resource cards
151
- initializeResourceCards();
152
- // Initialize resource carousel
153
- initializeResourceCarousel();
154
  }
155
  };
156
  }
@@ -172,40 +102,3 @@ function initializeResourcesBackgroundAttribution() {
172
  attribution.style.opacity = '0';
173
  });
174
  }
175
-
176
- function initializeResourceCarousel() {
177
- const carousel = document.querySelector('.resource-carousel');
178
- const prevButton = document.querySelector('.resource-carousel-prev');
179
- const nextButton = document.querySelector('.resource-carousel-next');
180
-
181
- if (!carousel || !prevButton || !nextButton) {
182
- return;
183
- }
184
-
185
- let currentIndex = 0;
186
- const cardWidth = 624; // 600px card + 24px gap
187
- const visibleCards = 1.5; // Show 1.5 cards at a time (larger cards)
188
- const maxIndex = sampleResources.length - 1; // Allow going to the last item
189
-
190
- function updateCarousel() {
191
- const translateX = -currentIndex * cardWidth;
192
- carousel.style.transform = `translateX(${translateX}px)`;
193
-
194
- // Update button states - no disabled states for looping
195
- prevButton.classList.remove('opacity-50', 'cursor-not-allowed');
196
- nextButton.classList.remove('opacity-50', 'cursor-not-allowed');
197
- }
198
-
199
- prevButton.addEventListener('click', () => {
200
- currentIndex = currentIndex > 0 ? currentIndex - 1 : maxIndex;
201
- updateCarousel();
202
- });
203
-
204
- nextButton.addEventListener('click', () => {
205
- currentIndex = currentIndex < maxIndex ? currentIndex + 1 : 0;
206
- updateCarousel();
207
- });
208
-
209
- // Initialize carousel state
210
- updateCarousel();
211
- }
 
1
  // pages/ResourcesPage.js - Resources page functionality for SPA
 
2
  import { pressMentions } from '../data/press.js';
3
+ import { renderTagSet } from '../utils/tags.js';
4
+ import { renderContentSection } from '../components/ContentSection.js';
5
+
6
+ // Use global data (loaded in index.html <head>)
7
+ const areasData = window.areasData;
8
+ const homeBackgroundImage = window.homeBackgroundImage;
9
 
10
  export function renderResourcesPage() {
11
  const content = `
12
+ ${renderContentSection('press-mentions', `
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  <h2 class="text-3xl font-bold text-gray-900 mb-6">Press Mentions</h2>
14
 
15
  <div class="space-y-3">
 
31
  day: 'numeric'
32
  });
33
 
34
+ // Generate tags using the utility
35
+ const { areaTagsHtml, topicTagsHtml: subAreaTagsHtml } = renderTagSet(article.areaTags, article.subAreaTags);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
  return `
38
  <!-- Press Article ${index + 1} - ${isLeftAligned ? 'Left' : 'Right'} aligned -->
 
73
  `;
74
  }).join('')}
75
  </div>
76
+ `, { className: 'mb-12' })}
 
77
  `;
78
 
79
  return {
 
81
  init: () => {
82
  // Initialize background attribution
83
  initializeResourcesBackgroundAttribution();
 
 
 
 
84
  }
85
  };
86
  }
 
102
  attribution.style.opacity = '0';
103
  });
104
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/utils/dom.js DELETED
@@ -1,13 +0,0 @@
1
- export function scrollToSection(sectionId) {
2
- const element = document.getElementById(sectionId);
3
- if (element) {
4
- const elementRect = element.getBoundingClientRect();
5
- const absoluteElementTop = elementRect.top + window.pageYOffset;
6
- const offset = 120; // Account for fixed header + some padding
7
-
8
- window.scrollTo({
9
- top: absoluteElementTop - offset,
10
- behavior: 'smooth'
11
- });
12
- }
13
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/utils/router.js CHANGED
@@ -2,21 +2,26 @@
2
  import { renderHomePage } from '../pages/HomePage.js';
3
  import { renderAreaPage } from '../pages/AreaPage.js';
4
  import { renderResourcesPage } from '../pages/ResourcesPage.js';
5
- import { scrollToSection } from './dom.js';
6
 
7
  class Router {
8
  constructor() {
 
9
  this.routes = {
10
  '/': 'home',
11
  '/home': 'home',
12
- '/efficiency': 'efficiency',
13
- '/personal': 'personal',
14
- '/rights': 'rights',
15
- '/ecosystems': 'ecosystems',
16
  '/about': 'resources'
17
  };
18
 
19
- this.areas = ['efficiency', 'personal', 'rights', 'ecosystems'];
 
 
 
 
 
 
 
 
20
  this.currentPage = null;
21
  this.currentArea = null;
22
  this.currentTopic = null;
@@ -109,21 +114,17 @@ class Router {
109
  await this.setPageBackground(route);
110
 
111
  try {
112
- switch (route) {
113
- case 'home':
114
- await this.loadHomePage();
115
- break;
116
- case 'efficiency':
117
- case 'personal':
118
- case 'rights':
119
- case 'ecosystems':
120
- await this.loadAreaPage(route, topic);
121
- break;
122
- case 'resources':
123
- await this.loadResourcesPage();
124
- break;
125
- default:
126
- await this.loadHomePage();
127
  }
128
 
129
  } catch (error) {
@@ -141,14 +142,15 @@ class Router {
141
 
142
  let backgroundImage, attribution, sourceUrl;
143
 
 
144
  if (route === 'home' || route === 'resources') {
145
- const { homeBackgroundImage } = await import('../data/areas.js');
146
  backgroundImage = homeBackgroundImage.image;
147
  attribution = homeBackgroundImage.attribution;
148
  sourceUrl = homeBackgroundImage.sourceUrl;
149
  } else {
150
  // Area pages
151
- const { areasData } = await import('../data/areas.js');
152
  const area = areasData[route];
153
  backgroundImage = area.image;
154
  attribution = area.imageAttribution;
@@ -166,7 +168,7 @@ class Router {
166
 
167
  backgroundDiv.innerHTML = `
168
  <!-- Background Image Main Content -->
169
- <img src="/images/${backgroundImage}" alt="" class="w-full h-full object-cover pointer-events-none">
170
  <div id="bg-attribution" class="absolute bottom-4 right-4 bg-black bg-opacity-75 text-white text-xs px-2 py-1 rounded opacity-0 transition-opacity duration-200 max-w-xs z-50">
171
  <a href="${sourceUrl}" target="_blank" class="text-blue-300 hover:text-blue-100">
172
  ${attribution}
@@ -222,11 +224,16 @@ class Router {
222
  // Update navigation state
223
  this.updateNavigation('home');
224
  } catch (error) {
 
 
 
 
225
  // Fallback to error content
226
  mainContent.innerHTML = `
227
  <div class="bg-white rounded-lg shadow-sm p-8">
228
  <h1 class="text-3xl font-bold text-red-600 mb-6">Error Loading Page</h1>
229
- <p class="text-gray-700">Sorry, there was an error loading the home page.</p>
 
230
  </div>
231
  `;
232
  }
 
2
  import { renderHomePage } from '../pages/HomePage.js';
3
  import { renderAreaPage } from '../pages/AreaPage.js';
4
  import { renderResourcesPage } from '../pages/ResourcesPage.js';
5
+ import { scrollToSection } from '../main.js';
6
 
7
  class Router {
8
  constructor() {
9
+ // Base routes (non-area pages)
10
  this.routes = {
11
  '/': 'home',
12
  '/home': 'home',
 
 
 
 
13
  '/about': 'resources'
14
  };
15
 
16
+ // Generate area routes dynamically from window.areasData
17
+ const areasData = window.areasData || {};
18
+ Object.keys(areasData).forEach(areaId => {
19
+ this.routes[`/${areaId}`] = areaId;
20
+ });
21
+
22
+ // Generate areas list dynamically
23
+ this.areas = Object.keys(areasData);
24
+
25
  this.currentPage = null;
26
  this.currentArea = null;
27
  this.currentTopic = null;
 
114
  await this.setPageBackground(route);
115
 
116
  try {
117
+ // Route to appropriate page
118
+ if (route === 'home') {
119
+ await this.loadHomePage();
120
+ } else if (route === 'resources') {
121
+ await this.loadResourcesPage();
122
+ } else if (this.areas.includes(route)) {
123
+ // Dynamically handle any area page
124
+ await this.loadAreaPage(route, topic);
125
+ } else {
126
+ // Unknown route, default to home
127
+ await this.loadHomePage();
 
 
 
 
128
  }
129
 
130
  } catch (error) {
 
142
 
143
  let backgroundImage, attribution, sourceUrl;
144
 
145
+ // Use global data loaded in index.html <head>
146
  if (route === 'home' || route === 'resources') {
147
+ const homeBackgroundImage = window.homeBackgroundImage;
148
  backgroundImage = homeBackgroundImage.image;
149
  attribution = homeBackgroundImage.attribution;
150
  sourceUrl = homeBackgroundImage.sourceUrl;
151
  } else {
152
  // Area pages
153
+ const areasData = window.areasData;
154
  const area = areasData[route];
155
  backgroundImage = area.image;
156
  attribution = area.imageAttribution;
 
168
 
169
  backgroundDiv.innerHTML = `
170
  <!-- Background Image Main Content -->
171
+ <img src="/images/${backgroundImage}" alt="" class="w-full h-full pointer-events-none">
172
  <div id="bg-attribution" class="absolute bottom-4 right-4 bg-black bg-opacity-75 text-white text-xs px-2 py-1 rounded opacity-0 transition-opacity duration-200 max-w-xs z-50">
173
  <a href="${sourceUrl}" target="_blank" class="text-blue-300 hover:text-blue-100">
174
  ${attribution}
 
224
  // Update navigation state
225
  this.updateNavigation('home');
226
  } catch (error) {
227
+ console.error('Error loading home page:', error);
228
+ console.error('Error stack:', error.stack);
229
+ console.error('Error message:', error.message);
230
+
231
  // Fallback to error content
232
  mainContent.innerHTML = `
233
  <div class="bg-white rounded-lg shadow-sm p-8">
234
  <h1 class="text-3xl font-bold text-red-600 mb-6">Error Loading Page</h1>
235
+ <p class="text-gray-700 mb-4">Sorry, there was an error loading the home page.</p>
236
+ <pre class="text-sm bg-gray-100 p-4 rounded overflow-auto">${error.message}\n\n${error.stack}</pre>
237
  </div>
238
  `;
239
  }
js/utils/search.js CHANGED
@@ -1,9 +1,11 @@
1
- // search.js - Complete MiniSearch implementation with resources and scores
2
- import { sampleResources } from '../data/resources.js';
3
- import { areasData } from '../data/areas.js';
4
 
5
- let miniSearch, miniSearchResources;
6
- let allArtifacts; // no longer needs to be explicitly defined
 
 
 
7
 
8
  // Helper to create and populate a MiniSearch instance
9
  function createMiniSearchIndex(data, storeFields) {
@@ -34,28 +36,13 @@ export async function initializeSearch(artifactsData) {
34
  date: artifact.date
35
  }));
36
 
37
- // Prepare resources data
38
- const resourcesData = sampleResources.map((resource, index) => ({
39
- id: index,
40
- title: resource.title,
41
- description: resource.description,
42
- type: resource.type,
43
- areas: (resource.areaTags || []).join(' '),
44
- topics: (resource.subAreaTags || []).join(' '),
45
- url: resource.url,
46
- date: resource.date
47
- }));
48
-
49
  // Initialize MiniSearch for artifacts
50
  miniSearch = createMiniSearchIndex(searchData, ['title', 'description', 'type', 'areas', 'topics', 'url', 'date']);
51
-
52
- // Initialize MiniSearch for resources
53
- miniSearchResources = createMiniSearchIndex(resourcesData, ['title', 'description', 'type', 'areas', 'topics', 'url', 'date']);
54
  }
55
 
56
  export function searchContent(query) {
57
  if (!query || query.trim().length < 2) {
58
- return { artifacts: [], resources: [] };
59
  }
60
 
61
  const artifactResults = miniSearch.search(query, {
@@ -64,15 +51,8 @@ export function searchContent(query) {
64
  boost: { title: 2, description: 1 }
65
  });
66
 
67
- const resourceResults = miniSearchResources.search(query, {
68
- prefix: true,
69
- fuzzy: 0.2,
70
- boost: { title: 2, description: 1 }
71
- });
72
-
73
  return {
74
- artifacts: artifactResults, // Show all results, not limited to 5
75
- resources: resourceResults
76
  };
77
  }
78
 
@@ -142,8 +122,8 @@ export function initializeSearchUI(artifactsData) {
142
 
143
  // Update the displaySearchResults function in search.js
144
  export function displaySearchResults(results, query) {
145
- const { artifacts, resources } = results;
146
- const totalResults = artifacts.length + resources.length;
147
 
148
  if (totalResults === 0) {
149
  document.getElementById('search-results').innerHTML = `
@@ -153,48 +133,20 @@ export function displaySearchResults(results, query) {
153
  }
154
 
155
  let html = `<div class="text-sm text-gray-600 mb-4">
156
- Found ${totalResults} results (${artifacts.length} writings, ${resources.length} resources)
157
  </div>`;
158
 
159
- // Display artifacts with collapsible header
160
  if (artifacts.length > 0) {
161
- html += `
162
- <div class="mb-4">
163
- <button onclick="toggleCategory('artifacts')" class="flex items-center justify-between w-full p-2 bg-blue-50 hover:bg-blue-100 rounded-lg transition-colors">
164
- <h4 class="font-semibold text-gray-900">Writings (${artifacts.length})</h4>
165
- <svg id="artifacts-arrow" class="w-4 h-4 text-gray-600 transform transition-transform" style="transform: rotate(0deg);">
166
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
167
- </svg>
168
- </button>
169
- <div id="artifacts-content" class="space-y-2 mt-2">
170
- `;
171
 
172
  artifacts.forEach(result => {
173
  const score = Math.round(result.score * 100);
174
 
175
- // Create area links
176
- const areaLinks = result.areas ? result.areas.split(' ').map(area => {
177
- const areaData = areasData[area];
178
- if (!areaData) return '';
179
- const colorClass = areaData?.colors?.bg || 'bg-blue-100';
180
- const textColorClass = areaData?.colors?.text || 'text-blue-800';
181
- return `<a href="/${area}#overview" class="text-xs px-2 py-1 ${colorClass} ${textColorClass} rounded hover:opacity-80 transition-opacity">${areaData?.title || area}</a>`;
182
- }).filter(link => link).join('') : '';
183
-
184
- // Create sub-area links
185
- const subAreaLinks = result.topics ? result.topics.split(' ').map(topic => {
186
- const primaryArea = result.areas?.split(' ')[0] || 'efficiency';
187
- const areaData = areasData[primaryArea];
188
- if (!areaData || !areaData.subAreas) return '';
189
-
190
- const subAreaData = areaData.subAreas[topic];
191
- if (!subAreaData) return '';
192
-
193
- const subAreaName = typeof subAreaData === 'string' ? subAreaData : subAreaData?.name || topic;
194
- const colorClass = subAreaData?.color || 'bg-gray-100 text-gray-800';
195
-
196
- return `<a href="/${primaryArea}#${topic}" class="text-xs px-2 py-1 ${colorClass} rounded hover:opacity-80 transition-opacity">${subAreaName}</a>`;
197
- }).filter(link => link).join('') : '';
198
 
199
  html += `
200
  <div class="p-3 bg-gray-50 rounded-lg border">
@@ -221,90 +173,8 @@ export function displaySearchResults(results, query) {
221
  `;
222
  });
223
 
224
- html += `</div></div>`;
225
- }
226
-
227
- // Display resources with collapsible header
228
- if (resources.length > 0) {
229
- html += `
230
- <div class="mb-4">
231
- <button onclick="toggleCategory('resources')" class="flex items-center justify-between w-full p-2 bg-green-50 hover:bg-green-100 rounded-lg transition-colors">
232
- <h4 class="font-semibold text-gray-900">Resources (${resources.length})</h4>
233
- <svg id="resources-arrow" class="w-4 h-4 text-gray-600 transform transition-transform" style="transform: rotate(0deg);">
234
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
235
- </svg>
236
- </button>
237
- <div id="resources-content" class="space-y-2 mt-2">
238
- `;
239
-
240
- resources.forEach(result => {
241
- const score = Math.round(result.score * 100);
242
-
243
- // Create area links for resources
244
- const areaLinks = result.areas ? result.areas.split(' ').map(area => {
245
- const areaData = areasData[area];
246
- if (!areaData) return '';
247
- const colorClass = areaData?.colors?.bg || 'bg-green-100';
248
- const textColorClass = areaData?.colors?.text || 'text-green-800';
249
- return `<a href="/${area}#overview" class="text-xs px-2 py-1 ${colorClass} ${textColorClass} rounded hover:opacity-80 transition-opacity">${areaData?.title || area}</a>`;
250
- }).filter(link => link).join('') : '';
251
-
252
- // Create sub-area links for resources
253
- const subAreaLinks = result.topics ? result.topics.split(' ').map(topic => {
254
- const primaryArea = result.areas?.split(' ')[0] || 'efficiency';
255
- const areaData = areasData[primaryArea];
256
- if (!areaData || !areaData.subAreas) return '';
257
-
258
- const subAreaData = areaData.subAreas[topic];
259
- if (!subAreaData) return '';
260
-
261
- const subAreaName = typeof subAreaData === 'string' ? subAreaData : subAreaData?.name || topic;
262
- const colorClass = subAreaData?.color || 'bg-gray-100 text-gray-800';
263
-
264
- return `<a href="/${primaryArea}#${topic}" class="text-xs px-2 py-1 ${colorClass} rounded hover:opacity-80 transition-opacity">${subAreaName}</a>`;
265
- }).filter(link => link).join('') : '';
266
-
267
- html += `
268
- <div class="p-3 bg-gray-50 rounded-lg border">
269
- <div class="flex items-center justify-between mb-2">
270
- <h5 class="font-medium text-sm text-gray-900">${result.title}</h5>
271
- <div class="flex items-center gap-2">
272
- <span class="text-xs text-gray-500">${score}%</span>
273
- <a href="${result.url}" target="_blank" class="text-gray-400 hover:text-gray-600 transition-colors">
274
- <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
275
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"></path>
276
- </svg>
277
- </a>
278
- </div>
279
- </div>
280
- <div class="flex items-center gap-2 mb-2 text-xs text-gray-600">
281
- <span class="px-2 py-1 bg-gray-200 text-gray-700 rounded">${result.type}</span>
282
- <span>${result.date}</span>
283
- </div>
284
- <div class="flex flex-wrap gap-1">
285
- ${areaLinks}
286
- ${subAreaLinks}
287
- </div>
288
- </div>
289
- `;
290
- });
291
-
292
- html += `</div></div>`;
293
  }
294
 
295
  document.getElementById('search-results').innerHTML = html;
296
- }
297
-
298
- // Add this function to handle category toggling
299
- window.toggleCategory = function(category) {
300
- const content = document.getElementById(`${category}-content`);
301
- const arrow = document.getElementById(`${category}-arrow`);
302
-
303
- if (content.style.display === 'none') {
304
- content.style.display = 'block';
305
- arrow.style.transform = 'rotate(0deg)';
306
- } else {
307
- content.style.display = 'none';
308
- arrow.style.transform = 'rotate(-90deg)';
309
- }
310
- };
 
1
+ // search.js - Complete MiniSearch implementation with artifacts
2
+ import { renderSearchTags } from './tags.js';
 
3
 
4
+ // Use global areasData (loaded in index.html <head>)
5
+ const areasData = window.areasData;
6
+
7
+ let miniSearch;
8
+ let allArtifacts;
9
 
10
  // Helper to create and populate a MiniSearch instance
11
  function createMiniSearchIndex(data, storeFields) {
 
36
  date: artifact.date
37
  }));
38
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  // Initialize MiniSearch for artifacts
40
  miniSearch = createMiniSearchIndex(searchData, ['title', 'description', 'type', 'areas', 'topics', 'url', 'date']);
 
 
 
41
  }
42
 
43
  export function searchContent(query) {
44
  if (!query || query.trim().length < 2) {
45
+ return { artifacts: [] };
46
  }
47
 
48
  const artifactResults = miniSearch.search(query, {
 
51
  boost: { title: 2, description: 1 }
52
  });
53
 
 
 
 
 
 
 
54
  return {
55
+ artifacts: artifactResults
 
56
  };
57
  }
58
 
 
122
 
123
  // Update the displaySearchResults function in search.js
124
  export function displaySearchResults(results, query) {
125
+ const { artifacts } = results;
126
+ const totalResults = artifacts.length;
127
 
128
  if (totalResults === 0) {
129
  document.getElementById('search-results').innerHTML = `
 
133
  }
134
 
135
  let html = `<div class="text-sm text-gray-600 mb-4">
136
+ Found ${totalResults} result${totalResults === 1 ? '' : 's'}
137
  </div>`;
138
 
139
+ // Display artifacts
140
  if (artifacts.length > 0) {
141
+ html += `<div class="space-y-2">`;
 
 
 
 
 
 
 
 
 
142
 
143
  artifacts.forEach(result => {
144
  const score = Math.round(result.score * 100);
145
 
146
+ // Use renderSearchTags utility
147
+ const areas = result.areas ? result.areas.split(' ') : [];
148
+ const topics = result.topics ? result.topics.split(' ') : [];
149
+ const { areaLinksHtml: areaLinks, topicLinksHtml: subAreaLinks } = renderSearchTags(areas, topics);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150
 
151
  html += `
152
  <div class="p-3 bg-gray-50 rounded-lg border">
 
173
  `;
174
  });
175
 
176
+ html += `</div>`;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
  }
178
 
179
  document.getElementById('search-results').innerHTML = html;
180
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/utils/sidebar.js DELETED
@@ -1,57 +0,0 @@
1
- import { overallBackgroundImage } from '../data/areas.js';
2
-
3
- export function renderSidebar(title, items) {
4
- return `
5
- <div class="relative h-full">
6
- <nav class="p-4 overflow-y-auto h-full pb-16">
7
- <h3 class="text-sm font-semibold text-gray-400 uppercase tracking-wider mb-3">${title}</h3>
8
- <ul class="space-y-1">
9
- ${items.map(item => {
10
- const activeClass = item.isActive ? 'text-blue-600 bg-blue-50' : 'text-gray-700 hover:text-gray-900 hover:bg-gray-50';
11
- const indentClass = item.isNested ? 'ml-4' : '';
12
-
13
- if (item.isHeader) {
14
- return `
15
- <li class="${indentClass}">
16
- <span class="block px-3 py-2 text-lg font-semibold ${activeClass} rounded-md">${item.label}</span>
17
- ${item.subItems && item.subItems.length > 0 ? `
18
- <ul class="space-y-1 mt-1">
19
- ${item.subItems.map(subItem => {
20
- const subActiveClass = subItem.isActive ? 'text-blue-600 bg-blue-50' : 'text-gray-600 hover:text-gray-800 hover:bg-gray-50';
21
- return `
22
- <li class="ml-4"><a href="${subItem.href}" class="page-nav-link block px-3 py-2 text-md ${subActiveClass} rounded-md transition-colors">${subItem.label}</a></li>
23
- `;
24
- }).join('')}
25
- </ul>
26
- ` : ''}
27
- </li>
28
- `;
29
- } else {
30
- return `
31
- <li class="${indentClass}">
32
- <a href="${item.href}" class="page-nav-link block px-3 py-2 text-lg ${activeClass} rounded-md transition-colors">${item.label}</a>
33
- ${item.subItems && item.subItems.length > 0 ? `
34
- <ul class="space-y-1 mt-1">
35
- ${item.subItems.map(subItem => {
36
- const subActiveClass = subItem.isActive ? 'text-blue-600 bg-blue-50' : 'text-gray-600 hover:text-gray-800 hover:bg-gray-50';
37
- return `
38
- <li class="ml-4"><a href="${subItem.href}" class="page-nav-link block px-3 py-2 text-md ${subActiveClass} rounded-md transition-colors">${subItem.label}</a></li>
39
- `;
40
- }).join('')}
41
- </ul>
42
- ` : ''}
43
- </li>
44
- `;
45
- }
46
- }).join('')}
47
- </ul>
48
- </nav>
49
- <div id="left-sidebar-attribution" class="absolute bottom-16 left-4 bg-black bg-opacity-75 text-white text-xs px-2 py-1 rounded transition-opacity duration-200 max-w-xs z-50">
50
- <a href="${overallBackgroundImage.sourceUrl}" target="_blank" class="text-blue-300 hover:text-blue-100">
51
- ${overallBackgroundImage.attribution}
52
- </a>
53
- </div>
54
- </div>
55
- </div>
56
- `;
57
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/utils/tags.js ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // tags.js - Centralized tag rendering utilities
2
+
3
+ /**
4
+ * Renders a single area tag with proper styling
5
+ * @param {string} areaId - The area identifier (e.g., 'efficiency', 'personal')
6
+ * @returns {string} HTML string for the area tag
7
+ */
8
+ export function renderAreaTag(areaId) {
9
+ const areasData = window.areasData; // Access dynamically
10
+ const area = areasData[areaId];
11
+ if (!area) return '';
12
+
13
+ return `<span class="inline-block px-2 py-1 text-xs rounded-full ${area.color}">${area.title}</span>`;
14
+ }
15
+
16
+ /**
17
+ * Renders a single topic tag with proper styling
18
+ * @param {string} areaId - The parent area identifier
19
+ * @param {string} topicId - The topic identifier (e.g., 'environment', 'privacy')
20
+ * @returns {string} HTML string for the topic tag
21
+ */
22
+ export function renderTopicTag(areaId, topicId) {
23
+ const areasData = window.areasData; // Access dynamically
24
+ const area = areasData[areaId];
25
+ if (!area || !area.topics) {
26
+ console.warn(`renderTopicTag: area "${areaId}" not found or has no topics`);
27
+ return '';
28
+ }
29
+
30
+ const topic = area.topics[topicId];
31
+ if (!topic) {
32
+ console.warn(`renderTopicTag: topic "${topicId}" not found in area "${areaId}". Available topics:`, Object.keys(area.topics));
33
+ return '';
34
+ }
35
+
36
+ const topicName = typeof topic === 'string' ? topic : (topic.name || topic.navName || topicId);
37
+ console.log(`renderTopicTag: areaId="${areaId}", topicId="${topicId}", topicName="${topicName}"`, topic);
38
+ let bgColor = 'bg-gray-200';
39
+ let textColor = 'text-gray-700';
40
+
41
+ // Extract background and text color from the topic color class
42
+ if (typeof topic === 'object' && topic.color) {
43
+ const bgMatch = topic.color.match(/bg-(\w+)-(\d+)/);
44
+ const textMatch = topic.color.match(/text-(\w+)-(\d+)/);
45
+
46
+ if (bgMatch) {
47
+ bgColor = `bg-${bgMatch[1]}-${bgMatch[2]}`;
48
+ }
49
+ if (textMatch) {
50
+ textColor = `text-${textMatch[1]}-700`; // Use consistent 700 shade
51
+ }
52
+ }
53
+
54
+ return `<span class="inline-block px-2 py-0.5 text-xs ${bgColor} ${textColor} rounded">${topicName}</span>`;
55
+ }
56
+
57
+ /**
58
+ * Renders a complete set of area and topic tags
59
+ * @param {string[]} areas - Array of area identifiers
60
+ * @param {string[]} topics - Array of topic identifiers
61
+ * @returns {object} Object with areaTagsHtml and topicTagsHtml properties
62
+ */
63
+ export function renderTagSet(areas = [], topics = []) {
64
+ const areaTagsHtml = areas.map(areaId => renderAreaTag(areaId)).filter(tag => tag).join('');
65
+
66
+ // For topics, we need to find which area they belong to
67
+ const topicTagsHtml = topics.map(topicId => {
68
+ // Try to find the topic in the first area, or search all areas
69
+ const primaryArea = areas[0];
70
+ if (primaryArea) {
71
+ const tag = renderTopicTag(primaryArea, topicId);
72
+ if (tag) return tag;
73
+ }
74
+
75
+ // If not found in primary area, search all areas
76
+ const areasData = window.areasData; // Access dynamically
77
+ for (const areaId in areasData) {
78
+ const tag = renderTopicTag(areaId, topicId);
79
+ if (tag) return tag;
80
+ }
81
+
82
+ return '';
83
+ }).filter(tag => tag).join('');
84
+
85
+ return {
86
+ areaTagsHtml,
87
+ topicTagsHtml
88
+ };
89
+ }
90
+
91
+ /**
92
+ * Renders tags for search results with links
93
+ * @param {string[]} areas - Array of area identifiers
94
+ * @param {string[]} topics - Array of topic identifiers
95
+ * @returns {object} Object with areaLinksHtml and topicLinksHtml properties
96
+ */
97
+ export function renderSearchTags(areas = [], topics = []) {
98
+ const areasData = window.areasData; // Access dynamically
99
+ const areaLinksHtml = areas.map(areaId => {
100
+ const area = areasData[areaId];
101
+ if (!area) return '';
102
+
103
+ const colorClass = area.color || 'bg-blue-100 text-blue-800';
104
+ return `<a href="/${areaId}#overview" class="text-xs px-2 py-1 ${colorClass} rounded hover:opacity-80 transition-opacity">${area.title}</a>`;
105
+ }).filter(link => link).join('');
106
+
107
+ const topicLinksHtml = topics.map(topicId => {
108
+ // Find which area this topic belongs to
109
+ const primaryArea = areas[0];
110
+ if (!primaryArea) return '';
111
+
112
+ const area = areasData[primaryArea];
113
+ if (!area || !area.topics) return '';
114
+
115
+ const topic = area.topics[topicId];
116
+ if (!topic) return '';
117
+
118
+ const topicName = typeof topic === 'string' ? topic : topic.name;
119
+ const colorClass = typeof topic === 'object' && topic.color ? topic.color : 'bg-gray-100 text-gray-800';
120
+
121
+ return `<a href="/${primaryArea}#${topicId}" class="text-xs px-2 py-1 ${colorClass} rounded hover:opacity-80 transition-opacity">${topicName}</a>`;
122
+ }).filter(link => link).join('');
123
+
124
+ return {
125
+ areaLinksHtml,
126
+ topicLinksHtml
127
+ };
128
+ }
129
+