yolo
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"recommendations": ["Vue.volar"]
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
# Vue 3 + TypeScript + Vite
|
||||
|
||||
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
||||
|
||||
Learn more about the recommended Project Setup and IDE Support in the [Vue Docs TypeScript Guide](https://vuejs.org/guide/typescript/overview.html#project-setup).
|
||||
@@ -0,0 +1,13 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>governance-site</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
Generated
+2107
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "governance-site",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vue-tsc -b && vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"lucide-vue-next": "^0.556.0",
|
||||
"pinia": "^3.0.4",
|
||||
"vue": "^3.5.24",
|
||||
"vue-router": "^4.6.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.10.1",
|
||||
"@vitejs/plugin-vue": "^6.0.1",
|
||||
"@vue/tsconfig": "^0.8.1",
|
||||
"sass": "^1.94.2",
|
||||
"typescript": "~5.9.3",
|
||||
"vite": "^7.2.4",
|
||||
"vue-tsc": "^3.1.6"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<AppLayout>
|
||||
<router-view />
|
||||
</AppLayout>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import AppLayout from '@/components/layout/AppLayout.vue'
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import '@/styles/main.scss';
|
||||
|
||||
#app {
|
||||
min-height: 100vh;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 496 B |
@@ -0,0 +1,41 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
|
||||
defineProps<{ msg: string }>()
|
||||
|
||||
const count = ref(0)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>{{ msg }}</h1>
|
||||
|
||||
<div class="card">
|
||||
<button type="button" @click="count++">count is {{ count }}</button>
|
||||
<p>
|
||||
Edit
|
||||
<code>components/HelloWorld.vue</code> to test HMR
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Check out
|
||||
<a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"
|
||||
>create-vue</a
|
||||
>, the official Vue + Vite starter
|
||||
</p>
|
||||
<p>
|
||||
Learn more about IDE Support for Vue in the
|
||||
<a
|
||||
href="https://vuejs.org/guide/scaling-up/tooling.html#ide-support"
|
||||
target="_blank"
|
||||
>Vue Docs Scaling up Guide</a
|
||||
>.
|
||||
</p>
|
||||
<p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.read-the-docs {
|
||||
color: #888;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<header class="document-header">
|
||||
<h1 class="document-title">{{ title }}</h1>
|
||||
<p v-if="description" class="document-description lead">
|
||||
{{ description }}
|
||||
</p>
|
||||
<div v-if="showMeta" class="document-meta">
|
||||
<span v-if="lastUpdated" class="meta-item">
|
||||
<Calendar :size="16" />
|
||||
Last updated: {{ formatDate(lastUpdated) }}
|
||||
</span>
|
||||
<span v-if="readingTime" class="meta-item">
|
||||
<Clock :size="16" />
|
||||
{{ readingTime }} min read
|
||||
</span>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Calendar, Clock } from 'lucide-vue-next'
|
||||
|
||||
interface Props {
|
||||
title: string
|
||||
description?: string
|
||||
lastUpdated?: Date
|
||||
readingTime?: number
|
||||
showMeta?: boolean
|
||||
}
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
showMeta: true
|
||||
})
|
||||
|
||||
const formatDate = (date: Date): string => {
|
||||
return new Intl.DateTimeFormat('en-US', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric'
|
||||
}).format(date)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.document-header {
|
||||
margin-bottom: $space-7;
|
||||
padding-bottom: $space-5;
|
||||
border-bottom: 2px solid $color-border;
|
||||
}
|
||||
|
||||
.document-title {
|
||||
margin-bottom: $space-4;
|
||||
}
|
||||
|
||||
.document-description {
|
||||
margin-bottom: $space-4;
|
||||
color: $color-text-muted;
|
||||
}
|
||||
|
||||
.document-meta {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: $space-4;
|
||||
font-size: $font-size-sm;
|
||||
color: $color-text-muted;
|
||||
}
|
||||
|
||||
.meta-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: $space-2;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,103 @@
|
||||
<template>
|
||||
<section class="document-section" :id="section.id">
|
||||
<component :is="headingTag" class="section-title">
|
||||
{{ section.title }}
|
||||
</component>
|
||||
<div class="section-content" v-html="renderedContent"></div>
|
||||
|
||||
<div v-if="section.subsections && section.subsections.length > 0" class="subsections">
|
||||
<DocumentSection
|
||||
v-for="subsection in section.subsections"
|
||||
:key="subsection.id"
|
||||
:section="subsection"
|
||||
:level="level + 1"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import type { DocumentSection as IDocumentSection } from '@/types'
|
||||
|
||||
interface Props {
|
||||
section: IDocumentSection
|
||||
level?: number
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
level: 2
|
||||
})
|
||||
|
||||
const headingTag = computed(() => {
|
||||
const tag = `h${Math.min(props.level, 6)}`
|
||||
return tag
|
||||
})
|
||||
|
||||
const renderedContent = computed(() => {
|
||||
// Basic markdown-like rendering
|
||||
let html = props.section.content
|
||||
|
||||
// Convert bold text
|
||||
html = html.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
|
||||
|
||||
// Convert italic text
|
||||
html = html.replace(/\*(.*?)\*/g, '<em>$1</em>')
|
||||
|
||||
// Convert line breaks to paragraphs
|
||||
html = html.split('\n\n').map(p => `<p>${p}</p>`).join('')
|
||||
|
||||
return html
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.document-section {
|
||||
margin-bottom: $space-6;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.section-title {
|
||||
margin-top: $space-6;
|
||||
margin-bottom: $space-4;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.section-content {
|
||||
:deep(p) {
|
||||
margin-bottom: $space-4;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(ul), :deep(ol) {
|
||||
margin-bottom: $space-4;
|
||||
padding-left: $space-5;
|
||||
}
|
||||
|
||||
:deep(li) {
|
||||
margin-bottom: $space-2;
|
||||
}
|
||||
|
||||
:deep(blockquote) {
|
||||
margin: $space-4 0;
|
||||
padding-left: $space-4;
|
||||
border-left: 4px solid $color-border;
|
||||
color: $color-text-muted;
|
||||
}
|
||||
}
|
||||
|
||||
.subsections {
|
||||
margin-top: $space-5;
|
||||
padding-left: $space-4;
|
||||
border-left: 2px solid $color-border;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,181 @@
|
||||
<template>
|
||||
<header class="app-header">
|
||||
<div class="container">
|
||||
<div class="header-content">
|
||||
<button
|
||||
class="menu-toggle lg:d-none"
|
||||
@click="navigationStore.toggleMenu()"
|
||||
:aria-label="navigationStore.isMenuOpen ? 'Close menu' : 'Open menu'"
|
||||
aria-controls="navigation-menu"
|
||||
>
|
||||
<Menu v-if="!navigationStore.isMenuOpen" :size="24" />
|
||||
<X v-else :size="24" />
|
||||
</button>
|
||||
|
||||
<router-link to="/" class="logo-link">
|
||||
<h1 class="logo">{{ hackerspaceStore.hackerspace.name }}</h1>
|
||||
</router-link>
|
||||
|
||||
<nav class="header-nav d-none lg:d-flex">
|
||||
<router-link
|
||||
v-for="item in mainNavItems"
|
||||
:key="item.id"
|
||||
:to="item.path"
|
||||
class="nav-link"
|
||||
:class="{ active: $route.path === item.path }"
|
||||
>
|
||||
{{ item.title }}
|
||||
</router-link>
|
||||
</nav>
|
||||
|
||||
<div class="header-actions">
|
||||
<button
|
||||
class="icon-button"
|
||||
@click="toggleTheme"
|
||||
aria-label="Toggle theme"
|
||||
>
|
||||
<Sun v-if="isDark" :size="20" />
|
||||
<Moon v-else :size="20" />
|
||||
</button>
|
||||
<button
|
||||
class="icon-button"
|
||||
@click="printPage"
|
||||
aria-label="Print page"
|
||||
>
|
||||
<Printer :size="20" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useNavigationStore } from '@/stores/navigation'
|
||||
import { useHackerspaceStore } from '@/stores/hackerspace'
|
||||
import { Menu, X, Sun, Moon, Printer } from 'lucide-vue-next'
|
||||
|
||||
const route = useRoute()
|
||||
const navigationStore = useNavigationStore()
|
||||
const hackerspaceStore = useHackerspaceStore()
|
||||
|
||||
const isDark = ref(false)
|
||||
|
||||
const mainNavItems = computed(() =>
|
||||
navigationStore.navItems.slice(0, 5)
|
||||
)
|
||||
|
||||
const toggleTheme = () => {
|
||||
isDark.value = !isDark.value
|
||||
document.documentElement.classList.toggle('dark-theme')
|
||||
}
|
||||
|
||||
const printPage = () => {
|
||||
window.print()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.app-header {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
background-color: $color-paper;
|
||||
border-bottom: 1px solid $color-border;
|
||||
height: $header-height;
|
||||
}
|
||||
|
||||
.header-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: $header-height;
|
||||
gap: $space-4;
|
||||
}
|
||||
|
||||
.menu-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: $radius-md;
|
||||
transition: background-color $transition-fast;
|
||||
|
||||
&:hover {
|
||||
background-color: $color-paper-light;
|
||||
}
|
||||
}
|
||||
|
||||
.logo-link {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-size: $font-size-lg;
|
||||
font-weight: 700;
|
||||
margin: 0;
|
||||
color: $color-text;
|
||||
}
|
||||
|
||||
.header-nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: $space-2;
|
||||
flex-grow: 1;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
padding: $space-2 $space-3;
|
||||
border-radius: $radius-md;
|
||||
font-size: $font-size-sm;
|
||||
font-weight: 500;
|
||||
transition: all $transition-fast;
|
||||
|
||||
&:hover {
|
||||
background-color: $color-paper-light;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: $color-paper-light;
|
||||
color: $color-accent;
|
||||
}
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: $space-2;
|
||||
}
|
||||
|
||||
.icon-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: $radius-md;
|
||||
transition: background-color $transition-fast;
|
||||
color: $color-text-muted;
|
||||
|
||||
&:hover {
|
||||
background-color: $color-paper-light;
|
||||
color: $color-text;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: $breakpoint-lg) {
|
||||
.header-nav {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<div class="app-layout">
|
||||
<AppHeader />
|
||||
<AppSidebar />
|
||||
<main class="app-main">
|
||||
<div class="main-content">
|
||||
<slot />
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import AppHeader from './AppHeader.vue'
|
||||
import AppSidebar from './AppSidebar.vue'
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.app-layout {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.app-main {
|
||||
flex: 1;
|
||||
padding-top: $header-height;
|
||||
margin-left: 0;
|
||||
transition: margin-left $transition-base;
|
||||
|
||||
@media (min-width: $breakpoint-lg) {
|
||||
margin-left: $sidebar-width;
|
||||
}
|
||||
}
|
||||
|
||||
.main-content {
|
||||
padding: $space-6 $space-4;
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
|
||||
@media (min-width: $breakpoint-md) {
|
||||
padding: $space-7 $space-5;
|
||||
}
|
||||
|
||||
@media (min-width: $breakpoint-lg) {
|
||||
padding: $space-8 $space-6;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,114 @@
|
||||
<template>
|
||||
<aside
|
||||
class="app-sidebar"
|
||||
:class="{ open: navigationStore.isMenuOpen }"
|
||||
id="navigation-menu"
|
||||
>
|
||||
<nav class="sidebar-nav" role="navigation">
|
||||
<router-link
|
||||
v-for="item in navigationStore.navItems"
|
||||
:key="item.id"
|
||||
:to="item.path"
|
||||
class="sidebar-link"
|
||||
:class="{ active: $route.path === item.path }"
|
||||
@click="navigationStore.closeMenu()"
|
||||
>
|
||||
<span class="sidebar-link-text">{{ item.title }}</span>
|
||||
</router-link>
|
||||
</nav>
|
||||
|
||||
<div class="sidebar-footer">
|
||||
<p class="text-small text-muted">
|
||||
Governance in a Box
|
||||
</p>
|
||||
<p class="text-xs text-muted">
|
||||
Adapt for your hackerspace
|
||||
</p>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<div
|
||||
v-if="navigationStore.isMenuOpen"
|
||||
class="sidebar-backdrop lg:d-none"
|
||||
@click="navigationStore.closeMenu()"
|
||||
></div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useNavigationStore } from '@/stores/navigation'
|
||||
|
||||
const route = useRoute()
|
||||
const navigationStore = useNavigationStore()
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.app-sidebar {
|
||||
position: fixed;
|
||||
top: $header-height;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: $sidebar-width;
|
||||
background-color: $color-paper-light;
|
||||
border-right: 1px solid $color-border;
|
||||
transform: translateX(-100%);
|
||||
transition: transform $transition-base;
|
||||
z-index: 90;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
&.open {
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
@media (min-width: $breakpoint-lg) {
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-nav {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: $space-4;
|
||||
}
|
||||
|
||||
.sidebar-link {
|
||||
display: block;
|
||||
padding: $space-3 $space-4;
|
||||
margin-bottom: $space-2;
|
||||
border-radius: $radius-md;
|
||||
font-size: $font-size-sm;
|
||||
color: $color-text;
|
||||
transition: all $transition-fast;
|
||||
|
||||
&:hover {
|
||||
background-color: $color-paper;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: $color-paper;
|
||||
color: $color-accent;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-link-text {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.sidebar-footer {
|
||||
padding: $space-4;
|
||||
border-top: 1px solid $color-border;
|
||||
}
|
||||
|
||||
.sidebar-backdrop {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
z-index: 80;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,103 @@
|
||||
<template>
|
||||
<div class="callout-box" :class="[`callout-${type}`]">
|
||||
<div class="callout-icon">
|
||||
<component :is="iconComponent" :size="20" />
|
||||
</div>
|
||||
<div class="callout-content">
|
||||
<h4 v-if="title" class="callout-title">{{ title }}</h4>
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { Info, AlertTriangle, CheckCircle, XCircle, Lightbulb } from 'lucide-vue-next'
|
||||
|
||||
interface Props {
|
||||
type?: 'info' | 'warning' | 'success' | 'error' | 'tip'
|
||||
title?: string
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
type: 'info'
|
||||
})
|
||||
|
||||
const iconComponent = computed(() => {
|
||||
const icons = {
|
||||
info: Info,
|
||||
warning: AlertTriangle,
|
||||
success: CheckCircle,
|
||||
error: XCircle,
|
||||
tip: Lightbulb
|
||||
}
|
||||
return icons[props.type]
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.callout-box {
|
||||
display: flex;
|
||||
gap: $space-3;
|
||||
padding: $space-4;
|
||||
margin: $space-5 0;
|
||||
border-radius: $radius-md;
|
||||
border-left: 4px solid;
|
||||
|
||||
&.callout-info {
|
||||
background-color: rgba($color-accent, 0.05);
|
||||
border-color: $color-accent;
|
||||
color: darken($color-accent, 10%);
|
||||
}
|
||||
|
||||
&.callout-warning {
|
||||
background-color: rgba($color-warning, 0.05);
|
||||
border-color: $color-warning;
|
||||
color: darken($color-warning, 10%);
|
||||
}
|
||||
|
||||
&.callout-success {
|
||||
background-color: rgba($color-success, 0.05);
|
||||
border-color: $color-success;
|
||||
color: darken($color-success, 10%);
|
||||
}
|
||||
|
||||
&.callout-error {
|
||||
background-color: rgba($color-error, 0.05);
|
||||
border-color: $color-error;
|
||||
color: darken($color-error, 10%);
|
||||
}
|
||||
|
||||
&.callout-tip {
|
||||
background-color: $color-paper-light;
|
||||
border-color: $color-text-muted;
|
||||
color: $color-text;
|
||||
}
|
||||
}
|
||||
|
||||
.callout-icon {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
.callout-content {
|
||||
flex: 1;
|
||||
color: $color-text;
|
||||
|
||||
:deep(p) {
|
||||
margin-bottom: $space-2;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.callout-title {
|
||||
margin-bottom: $space-2;
|
||||
font-size: $font-size-md;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,12 @@
|
||||
import { createApp } from 'vue'
|
||||
import { createPinia } from 'pinia'
|
||||
import router from './router'
|
||||
import App from './App.vue'
|
||||
|
||||
const app = createApp(App)
|
||||
const pinia = createPinia()
|
||||
|
||||
app.use(pinia)
|
||||
app.use(router)
|
||||
|
||||
app.mount('#app')
|
||||
@@ -0,0 +1,453 @@
|
||||
<template>
|
||||
<div class="adapt-this-page">
|
||||
<DocumentHeader
|
||||
title="Adapt This for Your Hackerspace"
|
||||
description="How to customize this governance framework for your own community."
|
||||
:last-updated="new Date('2024-12-05')"
|
||||
/>
|
||||
|
||||
<CalloutBox type="tip" title="License">
|
||||
<p>
|
||||
This entire framework is released under Creative Commons BY-SA 4.0.
|
||||
You're free to use, modify, and share it. We only ask that you share
|
||||
your improvements back to the community.
|
||||
</p>
|
||||
</CalloutBox>
|
||||
|
||||
<section id="quick-start">
|
||||
<h2>Quick Start Guide</h2>
|
||||
|
||||
<div class="step-list">
|
||||
<div class="step-card">
|
||||
<h3>Step 1: Download Everything</h3>
|
||||
<p>Get all the documents and source code:</p>
|
||||
<ul>
|
||||
<li>Download the complete package from Resources</li>
|
||||
<li>Clone the GitHub repository</li>
|
||||
<li>Fork for your own modifications</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="step-card">
|
||||
<h3>Step 2: Find & Replace Basics</h3>
|
||||
<p>Global replacements to make:</p>
|
||||
<ul>
|
||||
<li>"HeatSync Labs" → Your hackerspace name</li>
|
||||
<li>"Mesa, Arizona" → Your location</li>
|
||||
<li>"heatsynclabs.org" → Your domain</li>
|
||||
<li>Contact emails → Your addresses</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="step-card">
|
||||
<h3>Step 3: Customize Key Numbers</h3>
|
||||
<p>Adjust these to match your needs:</p>
|
||||
<ul>
|
||||
<li>Membership dues amounts</li>
|
||||
<li>Spending authority limits</li>
|
||||
<li>Meeting schedules</li>
|
||||
<li>Proposal timelines (we use 9-14 days)</li>
|
||||
<li>Board size and structure</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="step-card">
|
||||
<h3>Step 4: Legal Alignment</h3>
|
||||
<p>Match your local requirements:</p>
|
||||
<ul>
|
||||
<li>State/country nonprofit laws</li>
|
||||
<li>Required officer positions</li>
|
||||
<li>Tax-exempt requirements</li>
|
||||
<li>Insurance minimums</li>
|
||||
<li>Liability considerations</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="what-to-keep">
|
||||
<h2>What to Keep vs What to Change</h2>
|
||||
|
||||
<div class="comparison-grid">
|
||||
<div class="keep-card">
|
||||
<h3>Keep These Core Elements</h3>
|
||||
<ul>
|
||||
<li><strong>Do-ocracy principles</strong> - They work universally</li>
|
||||
<li><strong>Conflict resolution process</strong> - Time-tested approach</li>
|
||||
<li><strong>Decision framework</strong> - Clear paths for action</li>
|
||||
<li><strong>Board limitations</strong> - Prevents power accumulation</li>
|
||||
<li><strong>Documentation culture</strong> - Essential for continuity</li>
|
||||
<li><strong>"Be excellent"</strong> - Simple, effective principle</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="change-card">
|
||||
<h3>Customize These Elements</h3>
|
||||
<ul>
|
||||
<li><strong>Membership tiers</strong> - Match your economics</li>
|
||||
<li><strong>Officer roles</strong> - Per legal requirements</li>
|
||||
<li><strong>Meeting frequency</strong> - Based on activity level</li>
|
||||
<li><strong>Tool policies</strong> - Depends on equipment</li>
|
||||
<li><strong>Space-specific rules</strong> - Your layout matters</li>
|
||||
<li><strong>Cultural references</strong> - Make it yours</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="cultural-adaptation">
|
||||
<h2>Cultural Adaptation</h2>
|
||||
|
||||
<p>
|
||||
Every hackerspace has its own culture. Here's how to preserve yours
|
||||
while adopting this framework:
|
||||
</p>
|
||||
|
||||
<h3>Language and Tone</h3>
|
||||
<ul>
|
||||
<li>Adjust formality level to match your community</li>
|
||||
<li>Translate to your primary language(s)</li>
|
||||
<li>Use local idioms and references</li>
|
||||
<li>Match your existing communication style</li>
|
||||
</ul>
|
||||
|
||||
<h3>Values Emphasis</h3>
|
||||
<ul>
|
||||
<li>Highlight what matters most to your community</li>
|
||||
<li>Add sections for unique priorities</li>
|
||||
<li>Adjust the balance between structure and flexibility</li>
|
||||
<li>Include your origin story and mission</li>
|
||||
</ul>
|
||||
|
||||
<h3>Community Norms</h3>
|
||||
<ul>
|
||||
<li>Incorporate existing unwritten rules</li>
|
||||
<li>Respect established traditions</li>
|
||||
<li>Acknowledge founding members' contributions</li>
|
||||
<li>Build on what already works</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="technical-setup">
|
||||
<h2>Technical Setup</h2>
|
||||
|
||||
<h3>Website Deployment</h3>
|
||||
<p>To deploy your own version of this site:</p>
|
||||
|
||||
<pre><code>1. Clone the repository:
|
||||
git clone https://github.com/yourusername/governance-site
|
||||
cd governance-site
|
||||
|
||||
2. Install dependencies:
|
||||
npm install
|
||||
|
||||
3. Customize content:
|
||||
- Edit pages in src/pages/
|
||||
- Update store in src/stores/hackerspace.ts
|
||||
- Modify styles in src/styles/
|
||||
|
||||
4. Build for production:
|
||||
npm run build
|
||||
|
||||
5. Deploy to your host:
|
||||
- Static hosting (Netlify, Vercel, GitHub Pages)
|
||||
- Your own server (nginx, Apache)
|
||||
- CDN (CloudFlare Pages)</code></pre>
|
||||
|
||||
<h3>Alternative Formats</h3>
|
||||
<ul>
|
||||
<li><strong>Wiki:</strong> Convert markdown to MediaWiki format</li>
|
||||
<li><strong>Google Docs:</strong> Import and share with comments enabled</li>
|
||||
<li><strong>PDF:</strong> Print from browser or use pandoc</li>
|
||||
<li><strong>Physical:</strong> Print and bind for the space</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="common-modifications">
|
||||
<h2>Common Modifications</h2>
|
||||
|
||||
<h3>For Smaller Spaces (under 20 members)</h3>
|
||||
<ul>
|
||||
<li>Simplify board to 3 positions</li>
|
||||
<li>Combine roles (Champion/Secretary)</li>
|
||||
<li>Reduce meeting frequency to quarterly</li>
|
||||
<li>Lower quorum requirements</li>
|
||||
<li>Informal documentation acceptable</li>
|
||||
</ul>
|
||||
|
||||
<h3>For Larger Spaces (100+ members)</h3>
|
||||
<ul>
|
||||
<li>Add committee structure</li>
|
||||
<li>Implement area captains</li>
|
||||
<li>Create member tiers</li>
|
||||
<li>Formalize training programs</li>
|
||||
<li>Add staff positions</li>
|
||||
</ul>
|
||||
|
||||
<h3>For Non-US Spaces</h3>
|
||||
<ul>
|
||||
<li>Replace 501(c)(3) with local equivalent</li>
|
||||
<li>Adjust to local nonprofit law</li>
|
||||
<li>Convert measurements and currency</li>
|
||||
<li>Update legal references</li>
|
||||
<li>Consider language translations</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="implementation">
|
||||
<h2>Implementation Strategy</h2>
|
||||
|
||||
<h3>For New Hackerspaces</h3>
|
||||
<ol>
|
||||
<li>Use this as your starting framework</li>
|
||||
<li>Customize before opening</li>
|
||||
<li>Get founding member buy-in</li>
|
||||
<li>File legal paperwork with adapted bylaws</li>
|
||||
<li>Iterate based on early experience</li>
|
||||
</ol>
|
||||
|
||||
<h3>For Existing Hackerspaces</h3>
|
||||
<ol>
|
||||
<li>Compare with current governance</li>
|
||||
<li>Identify gaps and improvements</li>
|
||||
<li>Propose changes gradually</li>
|
||||
<li>Get member feedback</li>
|
||||
<li>Vote on adoption at meeting</li>
|
||||
<li>Phase in over time</li>
|
||||
</ol>
|
||||
|
||||
<CalloutBox type="warning">
|
||||
<p>
|
||||
<strong>Don't break what works!</strong> If your current system is
|
||||
functioning, cherry-pick improvements rather than wholesale replacement.
|
||||
</p>
|
||||
</CalloutBox>
|
||||
</section>
|
||||
|
||||
<section id="share-back">
|
||||
<h2>Share Your Improvements</h2>
|
||||
|
||||
<p>
|
||||
The hackerspace community thrives on sharing. When you adapt this framework:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>Document your changes</strong> - Others can learn from them</li>
|
||||
<li><strong>Share your templates</strong> - Upload to the community repo</li>
|
||||
<li><strong>Report what worked</strong> - Success stories help others</li>
|
||||
<li><strong>Share what didn't</strong> - Failures are valuable too</li>
|
||||
<li><strong>Contribute translations</strong> - Help non-English spaces</li>
|
||||
</ul>
|
||||
|
||||
<h3>How to Contribute</h3>
|
||||
<ul>
|
||||
<li>Submit pull requests to the main repository</li>
|
||||
<li>Share in hackerspace forums</li>
|
||||
<li>Present at hackerspace conferences</li>
|
||||
<li>Write blog posts about your experience</li>
|
||||
<li>Add to hackerspace.org wiki</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="help">
|
||||
<h2>Getting Help</h2>
|
||||
|
||||
<p>
|
||||
Adapting governance can be challenging. Here's where to get help:
|
||||
</p>
|
||||
|
||||
<h3>Community Resources</h3>
|
||||
<ul>
|
||||
<li><strong>Hackerspace Forums:</strong> discuss.hackerspaces.org</li>
|
||||
<li><strong>Slack/Discord:</strong> Join hackerspace channels</li>
|
||||
<li><strong>Regional Networks:</strong> Connect with nearby spaces</li>
|
||||
<li><strong>Conferences:</strong> Meet others who've done this</li>
|
||||
</ul>
|
||||
|
||||
<h3>Direct Support</h3>
|
||||
<ul>
|
||||
<li><strong>Email us:</strong> governance@heatsynclabs.org</li>
|
||||
<li><strong>Video call:</strong> Schedule a consultation</li>
|
||||
<li><strong>Visit:</strong> Come see how we do things</li>
|
||||
<li><strong>Mentorship:</strong> We'll pair you with an experienced space</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="checklist">
|
||||
<h2>Final Checklist</h2>
|
||||
|
||||
<p>Before launching with your adapted framework:</p>
|
||||
|
||||
<div class="checklist">
|
||||
<label><input type="checkbox"> All names and locations updated</label>
|
||||
<label><input type="checkbox"> Legal requirements verified</label>
|
||||
<label><input type="checkbox"> Financial amounts appropriate</label>
|
||||
<label><input type="checkbox"> Contact information current</label>
|
||||
<label><input type="checkbox"> Processes match your culture</label>
|
||||
<label><input type="checkbox"> Members have reviewed drafts</label>
|
||||
<label><input type="checkbox"> Legal counsel consulted if needed</label>
|
||||
<label><input type="checkbox"> Documentation accessible to all</label>
|
||||
<label><input type="checkbox"> Training plan for rollout</label>
|
||||
<label><input type="checkbox"> Feedback mechanism in place</label>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<CalloutBox type="tip">
|
||||
<p>
|
||||
<strong>Remember:</strong> Perfect is the enemy of done. Start with
|
||||
something workable and improve it over time. Your governance will
|
||||
evolve with your community.
|
||||
</p>
|
||||
</CalloutBox>
|
||||
|
||||
<section id="acknowledgments">
|
||||
<h2>Acknowledgments</h2>
|
||||
|
||||
<p>
|
||||
This framework builds on the work of hundreds of hackerspaces worldwide.
|
||||
Special thanks to:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>Mitch Altman and the hackerspace founders</li>
|
||||
<li>Hackerspace Gent for the Blueprint</li>
|
||||
<li>Noisebridge for radical inclusion</li>
|
||||
<li>Pumping Station: One for governance innovation</li>
|
||||
<li>All spaces that shared their documents openly</li>
|
||||
<li>The entire hackerspace community</li>
|
||||
</ul>
|
||||
|
||||
<p class="text-center mt-7">
|
||||
<strong>Now go forth and make things!</strong>
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import DocumentHeader from '@/components/document/DocumentHeader.vue'
|
||||
import CalloutBox from '@/components/ui/CalloutBox.vue'
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.adapt-this-page {
|
||||
max-width: $max-content-width;
|
||||
|
||||
section {
|
||||
margin-bottom: $space-7;
|
||||
}
|
||||
|
||||
.step-list {
|
||||
display: grid;
|
||||
gap: $space-4;
|
||||
margin: $space-5 0;
|
||||
|
||||
.step-card {
|
||||
padding: $space-4;
|
||||
background-color: $color-paper-light;
|
||||
border-left: 4px solid $color-accent;
|
||||
border-radius: $radius-md;
|
||||
|
||||
h3 {
|
||||
color: $color-accent;
|
||||
margin-bottom: $space-3;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: $space-3;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
ul {
|
||||
font-size: $font-size-sm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.comparison-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: $space-4;
|
||||
margin: $space-5 0;
|
||||
|
||||
@media (max-width: $breakpoint-md) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.keep-card, .change-card {
|
||||
padding: $space-4;
|
||||
border-radius: $radius-md;
|
||||
|
||||
h3 {
|
||||
margin-bottom: $space-3;
|
||||
}
|
||||
|
||||
ul {
|
||||
font-size: $font-size-sm;
|
||||
}
|
||||
}
|
||||
|
||||
.keep-card {
|
||||
background-color: rgba($color-success, 0.05);
|
||||
border: 2px solid $color-success;
|
||||
|
||||
h3 {
|
||||
color: $color-success;
|
||||
}
|
||||
}
|
||||
|
||||
.change-card {
|
||||
background-color: rgba($color-warning, 0.05);
|
||||
border: 2px solid $color-warning;
|
||||
|
||||
h3 {
|
||||
color: $color-warning;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: $color-paper-light;
|
||||
padding: $space-4;
|
||||
border-radius: $radius-md;
|
||||
overflow-x: auto;
|
||||
font-size: $font-size-sm;
|
||||
|
||||
code {
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.checklist {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $space-3;
|
||||
margin: $space-4 0;
|
||||
padding: $space-4;
|
||||
background-color: $color-paper-light;
|
||||
border-radius: $radius-md;
|
||||
|
||||
label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: $space-2;
|
||||
cursor: pointer;
|
||||
font-size: $font-size-sm;
|
||||
|
||||
input[type="checkbox"] {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.mt-7 {
|
||||
margin-top: $space-7;
|
||||
}
|
||||
}</style>
|
||||
@@ -0,0 +1,286 @@
|
||||
<template>
|
||||
<div class="board-page">
|
||||
<DocumentHeader
|
||||
title="The Board of Directors"
|
||||
description="Infrastructure maintainers and conflict resolvers - not leaders. The board exists to handle what members can't do individually."
|
||||
:last-updated="new Date('2024-12-05')"
|
||||
/>
|
||||
|
||||
<CalloutBox type="info" title="Key Principle">
|
||||
<p>
|
||||
<strong>Board members are wardens, not rulers.</strong> They maintain the infrastructure,
|
||||
handle legal requirements, and resolve conflicts the community can't handle directly.
|
||||
They should be indistinguishable from normal members in day-to-day operations.
|
||||
</p>
|
||||
</CalloutBox>
|
||||
|
||||
<section id="legal-reality">
|
||||
<h2>Legal Requirements vs Actual Roles</h2>
|
||||
|
||||
<p>
|
||||
Arizona law requires certain corporate officer positions for our 501(c)(3) status.
|
||||
Here's how we map legal requirements to our actual flat hierarchy:
|
||||
</p>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Legal Title (On Paper)</th>
|
||||
<th>Actual Role at HeatSync</th>
|
||||
<th>Real Responsibilities</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>President</td>
|
||||
<td>Champion</td>
|
||||
<td>Coordination between offices, membership support, bylaw enforcement</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Vice President</td>
|
||||
<td>Co-Champion</td>
|
||||
<td>Shares Champion duties, provides backup and balance</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Treasurer</td>
|
||||
<td>Treasurer</td>
|
||||
<td>Financial management, dues collection, budget oversight</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Secretary</td>
|
||||
<td>Secretary</td>
|
||||
<td>Meeting records, documentation, official correspondence</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p class="text-muted mt-4">
|
||||
<em>Note: We use functional titles internally but file legal paperwork with
|
||||
traditional titles to meet state requirements.</em>
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section id="board-offices">
|
||||
<h2>Board Offices</h2>
|
||||
|
||||
<h3>Champion (1-2 officers)</h3>
|
||||
<p>The Champion coordinates between board offices and assists members. Responsibilities:</p>
|
||||
<ul>
|
||||
<li>Coordinate tasks between board offices</li>
|
||||
<li>Assist members with membership-related tasks</li>
|
||||
<li>Ensure bylaws are followed (not enforce with an iron fist)</li>
|
||||
<li>Be the "face" of the board when needed for external relations</li>
|
||||
<li>Call and facilitate board meetings</li>
|
||||
</ul>
|
||||
<p class="text-small text-muted">
|
||||
Maximum 2 officers. Each gets a full vote. If two Champions, they should
|
||||
coordinate to avoid duplication.
|
||||
</p>
|
||||
|
||||
<h3>Treasurer (1-2 officers)</h3>
|
||||
<p>The Treasurer manages finances and ensures bills get paid. Responsibilities:</p>
|
||||
<ul>
|
||||
<li>Manage bank accounts and financial assets</li>
|
||||
<li>Collect membership dues and donations</li>
|
||||
<li>Pay bills and manage expenses</li>
|
||||
<li>Provide monthly financial reports</li>
|
||||
<li>File required tax documents</li>
|
||||
<li>Manage reimbursements for do-ocracy projects</li>
|
||||
</ul>
|
||||
<p class="text-small text-muted">
|
||||
Maximum 2 officers. Dual signatures required for expenses over $50.
|
||||
</p>
|
||||
|
||||
<h3>Secretary (1 officer)</h3>
|
||||
<p>The Secretary documents what happens. Responsibilities:</p>
|
||||
<ul>
|
||||
<li>Record meeting minutes (board and membership meetings)</li>
|
||||
<li>Maintain official records and documents</li>
|
||||
<li>Handle official correspondence</li>
|
||||
<li>Manage membership roster</li>
|
||||
<li>Post public notices as required</li>
|
||||
<li>Maintain corporate records for legal compliance</li>
|
||||
</ul>
|
||||
|
||||
<h3>Operations (1+ officers)</h3>
|
||||
<p>Operations keeps the space running. Responsibilities:</p>
|
||||
<ul>
|
||||
<li>Coordinate space maintenance and improvements</li>
|
||||
<li>Delegate operational tasks to volunteers</li>
|
||||
<li>Ensure safety procedures are followed</li>
|
||||
<li>Manage relationships with landlord</li>
|
||||
<li>Coordinate tool maintenance and certification</li>
|
||||
</ul>
|
||||
<p class="text-small text-muted">
|
||||
No maximum. Can create committees for specific operational areas.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section id="limitations">
|
||||
<h2>What the Board CANNOT Do</h2>
|
||||
|
||||
<CalloutBox type="warning">
|
||||
<p>The board's power is intentionally limited to prevent power accumulation:</p>
|
||||
</CalloutBox>
|
||||
|
||||
<ul>
|
||||
<li><strong>Cannot control space direction:</strong> Members decide what HeatSync becomes</li>
|
||||
<li><strong>Cannot override do-ocracy:</strong> If someone's doing the work, they make decisions</li>
|
||||
<li><strong>Cannot act unilaterally:</strong> Major decisions need member input</li>
|
||||
<li><strong>Cannot self-perpetuate:</strong> All positions are elected annually</li>
|
||||
<li><strong>Cannot hide proceedings:</strong> All meetings are open except sensitive legal/personnel matters</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="elections">
|
||||
<h2>Elections and Terms</h2>
|
||||
|
||||
<h3>Regular Elections</h3>
|
||||
<ul>
|
||||
<li>Held at first membership meeting in October</li>
|
||||
<li>One-year terms for all positions</li>
|
||||
<li>No term limits - officers can serve multiple terms</li>
|
||||
<li>Candidates must be dues-paying members in good standing</li>
|
||||
<li>Majority vote of present members wins</li>
|
||||
</ul>
|
||||
|
||||
<h3>Interim Officers</h3>
|
||||
<p>If an officer leaves mid-term:</p>
|
||||
<ol>
|
||||
<li>Board appoints interim replacement at next board meeting</li>
|
||||
<li>Interim serves remainder of original term</li>
|
||||
<li>If board can't agree, special election within 60 days</li>
|
||||
</ol>
|
||||
|
||||
<h3>Removal from Office</h3>
|
||||
<p>An officer can be removed by:</p>
|
||||
<ul>
|
||||
<li>Unanimous vote of other board members, OR</li>
|
||||
<li>Majority vote of all dues-paying members</li>
|
||||
<li>Missing 2 board meetings without 24-hour notice</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="operations">
|
||||
<h2>How the Board Operates</h2>
|
||||
|
||||
<h3>Meetings</h3>
|
||||
<ul>
|
||||
<li><strong>Frequency:</strong> At least quarterly</li>
|
||||
<li><strong>Annual Meeting:</strong> First member meeting in April</li>
|
||||
<li><strong>Quorum:</strong> 2/3 of elected officers</li>
|
||||
<li><strong>Openness:</strong> All members can observe (except executive session)</li>
|
||||
<li><strong>Minutes:</strong> Posted publicly within 7 days</li>
|
||||
</ul>
|
||||
|
||||
<h3>Decision Making</h3>
|
||||
<ul>
|
||||
<li>Consensus preferred, majority vote when needed</li>
|
||||
<li>Each officer gets one vote (even if sharing an office)</li>
|
||||
<li>Purchases over $50 need board approval</li>
|
||||
<li>All expenditures need 2 board signatures</li>
|
||||
</ul>
|
||||
|
||||
<h3>Committees</h3>
|
||||
<p>
|
||||
Any board office can create committees for their area. For example:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Operations might create a Safety Committee</li>
|
||||
<li>Treasurer might create a Fundraising Committee</li>
|
||||
<li>Champion might create a Membership Committee</li>
|
||||
</ul>
|
||||
<p>
|
||||
Committees are advisory and report to their creating office.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section id="conflict-resolution">
|
||||
<h2>Board as Conflict Resolvers</h2>
|
||||
|
||||
<p>
|
||||
When the do-ocracy can't resolve something, the board steps in as mediators:
|
||||
</p>
|
||||
|
||||
<h3>The Process</h3>
|
||||
<ol>
|
||||
<li><strong>Private Talk:</strong> Board member talks privately with each party</li>
|
||||
<li><strong>Mediation:</strong> Bring parties together to find resolution</li>
|
||||
<li><strong>Decision if Needed:</strong> Board decides if mediation fails</li>
|
||||
<li><strong>Temporary Measures:</strong> Can restrict access if safety is at risk</li>
|
||||
<li><strong>Community Communication:</strong> Inform members appropriately</li>
|
||||
</ol>
|
||||
|
||||
<h3>Principles</h3>
|
||||
<ul>
|
||||
<li>Protect the space's ability to function</li>
|
||||
<li>Be transparent about interventions</li>
|
||||
<li>Focus on resolution, not punishment</li>
|
||||
<li>Document decisions for consistency</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="accountability">
|
||||
<h2>Board Accountability</h2>
|
||||
|
||||
<p>
|
||||
The board is accountable to members through:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>Open Meetings:</strong> Members can observe and speak</li>
|
||||
<li><strong>Posted Minutes:</strong> All decisions are documented</li>
|
||||
<li><strong>Financial Reports:</strong> Monthly treasurer reports</li>
|
||||
<li><strong>Annual Elections:</strong> Members choose who serves</li>
|
||||
<li><strong>Removal Process:</strong> Members can remove officers</li>
|
||||
<li><strong>Limited Authority:</strong> Can't override member initiatives</li>
|
||||
</ul>
|
||||
|
||||
<CalloutBox type="tip">
|
||||
<p>
|
||||
<strong>Remember:</strong> Board members should be contributing members first,
|
||||
officers second. The best board members are barely distinguishable from
|
||||
active members except when their specific duties are needed.
|
||||
</p>
|
||||
</CalloutBox>
|
||||
</section>
|
||||
|
||||
<section id="current-board">
|
||||
<h2>Current Board</h2>
|
||||
<p>
|
||||
See the wiki or bulletin board for current board members and contact information.
|
||||
Board emails:
|
||||
</p>
|
||||
<ul>
|
||||
<li><strong>All board members:</strong> board@heatsynclabs.org</li>
|
||||
<li><strong>Champions:</strong> champion@heatsynclabs.org</li>
|
||||
<li><strong>Treasurer:</strong> treasurer@heatsynclabs.org</li>
|
||||
<li><strong>Secretary:</strong> secretary@heatsynclabs.org</li>
|
||||
<li><strong>Operations:</strong> operations@heatsynclabs.org</li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import DocumentHeader from '@/components/document/DocumentHeader.vue'
|
||||
import CalloutBox from '@/components/ui/CalloutBox.vue'
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.board-page {
|
||||
max-width: $max-content-width;
|
||||
|
||||
section {
|
||||
margin-bottom: $space-7;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-top: $space-5;
|
||||
color: $color-accent;
|
||||
}
|
||||
|
||||
table {
|
||||
margin: $space-5 0;
|
||||
}
|
||||
}</style>
|
||||
@@ -0,0 +1,309 @@
|
||||
<template>
|
||||
<div class="bylaws-page">
|
||||
<DocumentHeader
|
||||
title="Bylaws of HeatSync Labs"
|
||||
description="The legal foundation for our 501(c)(3) nonprofit hackerspace, designed to meet legal requirements while maximizing member autonomy through do-ocracy principles."
|
||||
:last-updated="new Date('2024-12-05')"
|
||||
/>
|
||||
|
||||
<section id="article-1">
|
||||
<h2>Article I: Name, Purpose, and Status</h2>
|
||||
|
||||
<h3>Section 1.1: Name</h3>
|
||||
<p>
|
||||
The name of the organization shall be HeatSync Labs, Inc., doing business as
|
||||
HeatSync Labs (hereinafter, the "Corporation").
|
||||
</p>
|
||||
|
||||
<h3>Section 1.2: Purpose</h3>
|
||||
<p>
|
||||
The Corporation is organized exclusively for charitable, educational, and
|
||||
scientific purposes within the meaning of Section 501(c)(3) of the Internal
|
||||
Revenue Code. Its mission is to:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Provide a collaborative physical workspace, tools, and resources for making,
|
||||
learning, exploring, and sharing technology and creative projects.</li>
|
||||
<li>Promote education in technology, science, art, and craftsmanship through
|
||||
workshops, classes, and public outreach.</li>
|
||||
<li>Foster a community of innovation and shared knowledge, operating on the
|
||||
principles of open access, inclusivity, and <strong>do-ocracy</strong>.</li>
|
||||
</ul>
|
||||
|
||||
<h3>Section 1.3: 501(c)(3) Status</h3>
|
||||
<p>
|
||||
The Corporation shall operate exclusively for its stated charitable purposes.
|
||||
No part of its net earnings shall benefit any private shareholder or individual.
|
||||
The Corporation shall not engage in substantial lobbying or any political
|
||||
campaign activities.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section id="article-2">
|
||||
<h2>Article II: Membership</h2>
|
||||
|
||||
<h3>Section 2.1: Eligibility</h3>
|
||||
<p>
|
||||
Membership is open to any individual who supports the Corporation's mission,
|
||||
agrees to abide by its Code of Conduct and Safety Policies, and pays the
|
||||
established dues (if any). The Corporation shall not discriminate on any
|
||||
unlawful basis.
|
||||
</p>
|
||||
|
||||
<h3>Section 2.2: Classes of Membership</h3>
|
||||
<p>The Corporation shall have <strong>Voting Members</strong>.</p>
|
||||
<ul>
|
||||
<li><strong>Voting Member:</strong> An individual who has completed an orientation,
|
||||
is in good standing (current on dues, if applicable, and adherence to policies),
|
||||
and has actively contributed to the space's maintenance or projects within the
|
||||
last 6 months. Contribution is self-documented and recognized (see Do-ocracy,
|
||||
Article VI).</li>
|
||||
</ul>
|
||||
|
||||
<h3>Section 2.3: Rights of Voting Members</h3>
|
||||
<p>
|
||||
Each Voting Member shall have one vote on matters put before the membership,
|
||||
including the election of the Board of Directors and amendments to these Bylaws.
|
||||
</p>
|
||||
|
||||
<h3>Section 2.4: Termination</h3>
|
||||
<p>
|
||||
Membership may be terminated for cause, including non-payment of dues or
|
||||
violation of the Code of Conduct, upon fair review as defined in the
|
||||
Corporation's policies.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section id="article-3">
|
||||
<h2>Article III: Board of Directors</h2>
|
||||
|
||||
<h3>Section 3.1: Role and Powers</h3>
|
||||
<p>
|
||||
The Board of Directors ("Board") is responsible for the legal, financial, and
|
||||
fiduciary oversight of the Corporation. It shall ensure compliance with all laws
|
||||
and the 501(c)(3) mission. The Board shall adopt policies but shall <strong>empower
|
||||
the membership and do-ocracy model</strong> for daily operations and project execution.
|
||||
</p>
|
||||
|
||||
<h3>Section 3.2: Composition</h3>
|
||||
<ul>
|
||||
<li>The Board shall consist of no fewer than three (3) and no more than seven (7) Directors.</li>
|
||||
<li>At least one-third of the Board must be elected from and by the Voting Membership.</li>
|
||||
<li>The remainder may be elected from the membership or appointed for specific expertise
|
||||
(legal, financial, etc.).</li>
|
||||
</ul>
|
||||
|
||||
<h3>Section 3.3: Election & Terms</h3>
|
||||
<p>
|
||||
Elected Directors shall serve staggered terms of two (2) years. Elections shall
|
||||
be held annually at the Membership Meeting. A Director may serve no more than
|
||||
four consecutive terms.
|
||||
</p>
|
||||
|
||||
<h3>Section 3.4: Officers</h3>
|
||||
<p>
|
||||
The Board shall elect from its members a Chair, Secretary, and Treasurer.
|
||||
Officers shall have duties as prescribed by the Board and consistent with state law.
|
||||
</p>
|
||||
|
||||
<h3>Section 3.5: Meetings</h3>
|
||||
<p>
|
||||
The Board shall meet at least quarterly. Meetings shall be open for observation
|
||||
by any Voting Member, except during executive sessions for sensitive matters
|
||||
(personnel, legal).
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section id="article-4">
|
||||
<h2>Article IV: Membership Meetings</h2>
|
||||
|
||||
<h3>Section 4.1: Annual Meeting</h3>
|
||||
<p>
|
||||
An Annual Membership Meeting shall be held for electing Directors, presenting
|
||||
annual reports, and addressing major strategic issues.
|
||||
</p>
|
||||
|
||||
<h3>Section 4.2: Special Meetings</h3>
|
||||
<p>
|
||||
Special Meetings may be called by the Board or by a petition of at least 20%
|
||||
of Voting Members.
|
||||
</p>
|
||||
|
||||
<h3>Section 4.3: Quorum & Decision Making</h3>
|
||||
<p>
|
||||
For annual meetings, a quorum shall be 20% of Voting Members. For special meetings,
|
||||
30%. Whenever possible, the Corporation shall operate by <strong>consensus</strong>.
|
||||
When a vote is required, a simple majority of members present shall decide, except
|
||||
for Bylaws amendments (see Article VIII).
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section id="article-5">
|
||||
<h2>Article V: Committees</h2>
|
||||
|
||||
<h3>Section 5.1: Standing Committees</h3>
|
||||
<p>
|
||||
The Board may establish Standing Committees for ongoing functions (Finance, Safety).
|
||||
Committee chairs shall report to the Board.
|
||||
</p>
|
||||
|
||||
<h3>Section 5.2: Do-ocracy Working Groups</h3>
|
||||
<p>
|
||||
These are <strong>self-forming, project-oriented groups</strong> established by
|
||||
members under the principles of Article VI. They are not committees of the Board
|
||||
and operate autonomously within the scope of approved budgets and space policies.
|
||||
They must report their activities and use of resources to the membership via a
|
||||
public log/wiki.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section id="article-6">
|
||||
<h2>Article VI: Principle of Do-ocracy</h2>
|
||||
|
||||
<CalloutBox type="tip" title="Core Principle">
|
||||
<p>
|
||||
A "do-ocracy" is an organizational structure in which individuals have the
|
||||
authority and responsibility to self-initiate and execute projects, tasks,
|
||||
and improvements for the Corporation. <strong>The authority to make a decision
|
||||
and take action lies with those who do the work.</strong>
|
||||
</p>
|
||||
</CalloutBox>
|
||||
|
||||
<h3>Section 6.1: Definition</h3>
|
||||
<p>
|
||||
A "do-ocracy" is an organizational structure in which individuals have the
|
||||
authority and responsibility to self-initiate and execute projects, tasks, and
|
||||
improvements for the Corporation. <strong>The authority to make a decision and
|
||||
take action lies with those who do the work.</strong>
|
||||
</p>
|
||||
|
||||
<h3>Section 6.2: Scope</h3>
|
||||
|
||||
<h4>Empowered Actions:</h4>
|
||||
<p>Members are empowered to:</p>
|
||||
<ul>
|
||||
<li>Fix broken equipment</li>
|
||||
<li>Organize workshops</li>
|
||||
<li>Improve infrastructure</li>
|
||||
<li>Create art for the space</li>
|
||||
<li>Develop software tools</li>
|
||||
<li>Manage day-to-day operations within established safety and financial guidelines</li>
|
||||
</ul>
|
||||
|
||||
<h4>Limitations:</h4>
|
||||
<p>Do-ocracy does not authorize actions that:</p>
|
||||
<ul>
|
||||
<li>Violate law or the Code of Conduct</li>
|
||||
<li>Create significant legal/financial risk</li>
|
||||
<li>Commit the Corporation to major contracts</li>
|
||||
<li>Spend beyond a pre-set budget cap for autonomous projects ($200)</li>
|
||||
<li>Alter core governance</li>
|
||||
</ul>
|
||||
|
||||
<h3>Section 6.3: Process & Accountability</h3>
|
||||
<ol>
|
||||
<li><strong>Proposal & Notification:</strong> A member wishing to undertake a
|
||||
significant action shall document their intent (via wiki, mailing list, or
|
||||
physical board) to allow for feedback.</li>
|
||||
<li><strong>Seeking Feedback:</strong> The proposing member shall actively seek
|
||||
feedback, especially from those affected. <strong>Constructive objection must
|
||||
be addressed.</strong></li>
|
||||
<li><strong>Execution:</strong> If no unresolvable objection is raised within
|
||||
<strong>9-14 days</strong>, the member may proceed, using resources responsibly.</li>
|
||||
<li><strong>Documentation:</strong> All actions must be documented (what was done,
|
||||
cost, who did it).</li>
|
||||
</ol>
|
||||
|
||||
<h3>Section 6.4: Conflict Resolution</h3>
|
||||
<p>
|
||||
Disputes arising from do-ocratic actions shall first be addressed through direct,
|
||||
respectful dialogue. Unresolved disputes shall be mediated per the Corporation's
|
||||
Conflict Resolution Policy, ultimately appealable to the Board.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section id="article-7">
|
||||
<h2>Article VII: Finances</h2>
|
||||
|
||||
<h3>Section 7.1: Fiscal Year</h3>
|
||||
<p>The fiscal year shall be January 1 to December 31.</p>
|
||||
|
||||
<h3>Section 7.2: Budget</h3>
|
||||
<p>
|
||||
The Board, with input from the membership, shall approve an annual budget.
|
||||
The budget shall include a <strong>Do-ocracy Project Fund</strong> to be
|
||||
allocated by members for small, autonomous projects.
|
||||
</p>
|
||||
|
||||
<h3>Section 7.3: Disbursements</h3>
|
||||
<p>
|
||||
Disbursements under the Do-ocracy Project Fund cap may be reimbursed upon
|
||||
presentation of receipts and documentation. Larger expenditures require prior
|
||||
approval per the Financial Policy.
|
||||
</p>
|
||||
|
||||
<h3>Section 7.4: Financial Review</h3>
|
||||
<p>
|
||||
The Board shall ensure an annual financial review or audit as required by law
|
||||
or best practices.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section id="article-8">
|
||||
<h2>Article VIII: Amendments</h2>
|
||||
<p>
|
||||
These Bylaws may be amended by a <strong>two-thirds (2/3) supermajority vote</strong>
|
||||
of the Voting Members present at a duly called Membership Meeting, provided written
|
||||
notice of the proposed amendment has been provided to all members at least
|
||||
<strong>14 days</strong> in advance.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section id="article-9">
|
||||
<h2>Article IX: Dissolution</h2>
|
||||
<p>
|
||||
Upon dissolution of the Corporation, after paying all debts and obligations, its
|
||||
remaining assets shall be distributed to one or more 501(c)(3) organizations with
|
||||
a similar mission, as determined by the Board. No assets shall be distributed to
|
||||
any member, director, or officer.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<div class="signature-block mt-8">
|
||||
<p><strong>Adopted on:</strong> _______________</p>
|
||||
<p><strong>Secretary:</strong> _________________________</p>
|
||||
<p class="text-small text-muted">(Printed Name & Signature)</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import DocumentHeader from '@/components/document/DocumentHeader.vue'
|
||||
import CalloutBox from '@/components/ui/CalloutBox.vue'
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.bylaws-page {
|
||||
max-width: $max-content-width;
|
||||
|
||||
section {
|
||||
margin-bottom: $space-7;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-top: $space-5;
|
||||
margin-bottom: $space-3;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin-top: $space-4;
|
||||
margin-bottom: $space-2;
|
||||
}
|
||||
|
||||
.signature-block {
|
||||
padding: $space-5;
|
||||
background-color: $color-paper-light;
|
||||
border-radius: $radius-md;
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
}</style>
|
||||
@@ -0,0 +1,319 @@
|
||||
<template>
|
||||
<div class="community-standards-page">
|
||||
<DocumentHeader
|
||||
title="Community Standards & Accountability Process"
|
||||
description="HeatSync Labs exists so people can make things. These standards protect that mission by ensuring everyone can participate safely."
|
||||
:last-updated="new Date('2024-12-05')"
|
||||
/>
|
||||
|
||||
<CalloutBox type="info">
|
||||
<p>
|
||||
<strong>We're a do-ocracy:</strong> if you see a problem, you can address it.
|
||||
But some problems need backup. This document tells you when to act, when to
|
||||
escalate, and what happens next.
|
||||
</p>
|
||||
</CalloutBox>
|
||||
|
||||
<section id="core-principle">
|
||||
<h2>1. The Core Principle</h2>
|
||||
<p class="lead"><strong>Be excellent to each other.</strong></p>
|
||||
|
||||
<p>This means:</p>
|
||||
<ol>
|
||||
<li><strong>Respect people's right to exist and make things here,</strong> regardless of who they are.</li>
|
||||
<li><strong>Take care of the space</strong> so others can use it too.</li>
|
||||
<li><strong>Handle conflicts directly when you can,</strong> and ask for help when you can't.</li>
|
||||
<li><strong>Support the community's ability to enforce its norms,</strong> even when it's uncomfortable.</li>
|
||||
</ol>
|
||||
</section>
|
||||
|
||||
<section id="who-applies">
|
||||
<h2>2. Who This Applies To</h2>
|
||||
<p>
|
||||
Everyone in HeatSync spaces—physical or digital—including members, guests,
|
||||
visitors, board members, and anyone at HSL-sponsored events. No one is exempt.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section id="protected-groups">
|
||||
<h2>3. Who We Protect</h2>
|
||||
<p>HeatSync Labs does not tolerate discrimination or harassment based on:</p>
|
||||
|
||||
<ul>
|
||||
<li>Race or ethnicity</li>
|
||||
<li>Gender identity or expression</li>
|
||||
<li>Sexual orientation</li>
|
||||
<li>Disability (visible or invisible)</li>
|
||||
<li>Age</li>
|
||||
<li>Religion (or lack thereof)</li>
|
||||
<li>National origin</li>
|
||||
<li>Socioeconomic status</li>
|
||||
<li>Body size or appearance</li>
|
||||
<li>Neurodivergence</li>
|
||||
</ul>
|
||||
|
||||
<p class="text-muted">
|
||||
<em>This list is not exhaustive.</em> If you're being targeted for who you are, that's covered.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section id="behaviors">
|
||||
<h2>4. Behavior That Isn't Tolerated</h2>
|
||||
|
||||
<h3>4.1 Immediate Removal Behaviors</h3>
|
||||
<p>These result in immediate removal from the space. No warnings.</p>
|
||||
|
||||
<ol>
|
||||
<li><strong>Violence or credible threats of violence</strong></li>
|
||||
<li><strong>Sexual harassment or assault</strong></li>
|
||||
<li><strong>Stalking or deliberate intimidation</strong></li>
|
||||
<li><strong>Doxxing</strong> (publishing someone's private information)</li>
|
||||
<li><strong>Theft or intentional destruction of property</strong></li>
|
||||
<li><strong>Grossly unsafe tool use</strong> that endangers others</li>
|
||||
</ol>
|
||||
|
||||
<h3>4.2 Escalating Behaviors</h3>
|
||||
<p>These may result in warnings, then escalating consequences if they continue.</p>
|
||||
|
||||
<ul>
|
||||
<li>Slurs, discriminatory jokes, or derogatory language targeting protected characteristics</li>
|
||||
<li>Unwelcome physical contact (you need consent before touching someone)</li>
|
||||
<li>Sustained disruption of events, meetings, or others' work</li>
|
||||
<li>Refusing to stop behavior when asked</li>
|
||||
<li>Repeated boundary violations after being informed</li>
|
||||
<li>Creating a hostile environment through patterns of microaggressions</li>
|
||||
<li>Retaliation against someone who made a report</li>
|
||||
</ul>
|
||||
|
||||
<h3>4.3 Space & Tool Violations</h3>
|
||||
|
||||
<ul>
|
||||
<li>Using tools you're not certified for</li>
|
||||
<li>Leaving messes for others to clean up</li>
|
||||
<li>Ignoring posted safety procedures</li>
|
||||
<li>Using more space than you need during busy times</li>
|
||||
<li>Taking or using others' property without permission</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="do-ocracy-response">
|
||||
<h2>5. The Do-ocracy Response</h2>
|
||||
|
||||
<CalloutBox type="tip">
|
||||
<p>
|
||||
<strong>We're a do-ocracy.</strong> That means you have standing to address
|
||||
problems directly. You don't need permission to say "hey, that's not cool"
|
||||
or "please clean up after yourself." Most issues should be handled this way.
|
||||
</p>
|
||||
</CalloutBox>
|
||||
|
||||
<h3>5.1 When to Handle It Yourself</h3>
|
||||
|
||||
<ul>
|
||||
<li>Someone forgot safety glasses → remind them</li>
|
||||
<li>Someone left a mess → ask them to clean it up</li>
|
||||
<li>Someone's being loud during your work → politely ask them to keep it down</li>
|
||||
<li>Someone said something mildly off → call it in ("hey, that came across weird")</li>
|
||||
<li>A tool needs maintenance → fix it if you can, report it if you can't</li>
|
||||
</ul>
|
||||
|
||||
<h3>5.2 When to Escalate</h3>
|
||||
|
||||
<ul>
|
||||
<li>The behavior is in the "Immediate Removal" category</li>
|
||||
<li>You've addressed it directly and it continues</li>
|
||||
<li>You don't feel safe addressing it directly</li>
|
||||
<li>The person becomes hostile when confronted</li>
|
||||
<li>It's a pattern, not a one-time thing</li>
|
||||
<li>You witness something happening to someone else who seems distressed</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="reporting">
|
||||
<h2>6. Reporting & Response Process</h2>
|
||||
|
||||
<h3>6.1 How to Report</h3>
|
||||
<p>Choose the method that works for you:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>Email:</strong> conduct@heatsynclabs.org (goes to all board members)</li>
|
||||
<li><strong>In person:</strong> Any board member or host present at the space</li>
|
||||
<li><strong>Anonymous:</strong> Drop box at [LOCATION] or anonymous form at [URL]</li>
|
||||
<li><strong>Direct to specific board member:</strong> If you're not comfortable with full board seeing the report</li>
|
||||
</ul>
|
||||
|
||||
<h3>6.2 What Happens Next</h3>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Timeline</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><strong>48 hours</strong></td>
|
||||
<td>Acknowledgment sent to reporter (unless anonymous)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>7 days</strong></td>
|
||||
<td>Initial investigation complete; interim measures if needed</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>21 days</strong></td>
|
||||
<td>Final decision communicated to all parties</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p class="text-muted">
|
||||
<em>Exceptions:</em> Complex situations may take longer. If so, you'll be told why and given an updated timeline.
|
||||
</p>
|
||||
|
||||
<h3>6.3 Investigation Process</h3>
|
||||
|
||||
<ol>
|
||||
<li><strong>Intake:</strong> At least two board members review the report</li>
|
||||
<li><strong>Gathering information:</strong> We talk to the reporter, the respondent, and any witnesses</li>
|
||||
<li><strong>Interim measures:</strong> If someone's safety is at risk, we may restrict access during investigation</li>
|
||||
<li><strong>Decision:</strong> Board determines what happened and what response is appropriate</li>
|
||||
<li><strong>Communication:</strong> Both parties are informed of the outcome</li>
|
||||
</ol>
|
||||
|
||||
<CalloutBox type="info">
|
||||
<p>
|
||||
<strong>Conflict of Interest:</strong> If a board member is involved in the
|
||||
incident (as reporter, respondent, or close relation), they recuse themselves
|
||||
from the process.
|
||||
</p>
|
||||
</CalloutBox>
|
||||
</section>
|
||||
|
||||
<section id="consequences">
|
||||
<h2>7. Consequences</h2>
|
||||
<p>Responses are proportional to the severity and pattern of behavior.</p>
|
||||
|
||||
<h3>Tier A: Verbal or Written Warning</h3>
|
||||
<p>For first-time minor violations where the person seems unaware or immediately corrects.</p>
|
||||
<ul>
|
||||
<li>Documented internally but not announced publicly</li>
|
||||
</ul>
|
||||
|
||||
<h3>Tier B: Required Action</h3>
|
||||
<p>For repeated minor violations or moderate violations. May include:</p>
|
||||
<ul>
|
||||
<li>Apology to affected parties</li>
|
||||
<li>Cleaning duty or other community service</li>
|
||||
<li>Temporary restriction from specific areas or tools</li>
|
||||
<li>Required re-certification for safety training</li>
|
||||
</ul>
|
||||
|
||||
<h3>Tier C: Temporary Suspension</h3>
|
||||
<p>For serious violations or continued problems after warnings. 30-180 days.</p>
|
||||
<ul>
|
||||
<li>No access to space during suspension</li>
|
||||
<li>Card access revoked</li>
|
||||
<li>Reinstatement may require conditions (e.g., meeting with board)</li>
|
||||
</ul>
|
||||
|
||||
<h3>Tier D: Permanent Ban</h3>
|
||||
<p>For severe violations or repeated serious problems. Reserved for:</p>
|
||||
<ul>
|
||||
<li>Violence, sexual assault, stalking, or credible threats</li>
|
||||
<li>Pattern of harassment despite previous consequences</li>
|
||||
<li>Actions that seriously endanger others</li>
|
||||
</ul>
|
||||
|
||||
<CalloutBox type="warning">
|
||||
<p>
|
||||
<strong>No waiting for multiple complaints:</strong> The board is not required
|
||||
to wait for a specific number of reports before taking action. A single credible
|
||||
report of serious behavior is sufficient to investigate and act.
|
||||
</p>
|
||||
</CalloutBox>
|
||||
</section>
|
||||
|
||||
<section id="appeals">
|
||||
<h2>8. Appeals</h2>
|
||||
<p>If you believe a decision was unfair, you may appeal.</p>
|
||||
|
||||
<h3>8.1 Grounds for Appeal</h3>
|
||||
<ul>
|
||||
<li>New evidence that wasn't available during the investigation</li>
|
||||
<li>Procedural errors that affected the outcome</li>
|
||||
<li>Consequence is disproportionate to the violation</li>
|
||||
</ul>
|
||||
|
||||
<h3>8.2 Appeal Process</h3>
|
||||
<ul>
|
||||
<li>Submit written appeal to conduct@heatsynclabs.org within 14 days of decision</li>
|
||||
<li>Appeal is reviewed by board members not involved in original decision</li>
|
||||
<li>If all board members were involved, appeal goes to membership vote at HYH</li>
|
||||
<li>Decision on appeal is final</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="confidentiality">
|
||||
<h2>9. Confidentiality & Documentation</h2>
|
||||
<ul>
|
||||
<li>Reports are kept confidential to those involved in the investigation</li>
|
||||
<li>The board maintains records of all reports and outcomes</li>
|
||||
<li>Consequences may be shared with the community without naming individuals</li>
|
||||
<li>Deliberately making consequences public when the board chose privacy is itself a violation</li>
|
||||
<li>If the community needs to know for safety reasons, the board will communicate appropriately</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="amendments">
|
||||
<h2>10. Amendments</h2>
|
||||
<p>
|
||||
This document may be amended through the standard HSL proposal process.
|
||||
Amendments require a majority vote at HYH followed by board ratification.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<CalloutBox type="tip">
|
||||
<p>
|
||||
<strong>The goal isn't punishment—it's a space where people can make things
|
||||
without worrying about being harassed, endangered, or excluded.</strong>
|
||||
When we hold each other accountable, we're protecting what makes HeatSync worth having.
|
||||
</p>
|
||||
</CalloutBox>
|
||||
|
||||
<section id="contact" class="mt-7">
|
||||
<h2>Contact</h2>
|
||||
<ul>
|
||||
<li><strong>Report a concern:</strong> conduct@heatsynclabs.org</li>
|
||||
<li><strong>General board inquiries:</strong> board@heatsynclabs.org</li>
|
||||
<li><strong>Physical drop box:</strong> [LOCATION TBD]</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<p class="text-small text-muted mt-7">
|
||||
<em>This document is adapted from the Geek Feminism Anti-Harassment Policy and distributed under CC BY-SA 3.0.</em>
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import DocumentHeader from '@/components/document/DocumentHeader.vue'
|
||||
import CalloutBox from '@/components/ui/CalloutBox.vue'
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.community-standards-page {
|
||||
max-width: $max-content-width;
|
||||
|
||||
section {
|
||||
margin-bottom: $space-6;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-top: $space-5;
|
||||
}
|
||||
|
||||
table {
|
||||
margin: $space-5 0;
|
||||
}
|
||||
}</style>
|
||||
@@ -0,0 +1,461 @@
|
||||
<template>
|
||||
<div class="decision-making-page">
|
||||
<DocumentHeader
|
||||
title="Decision Making Process"
|
||||
description="When to act independently, when to seek consensus, and how to make group decisions efficiently."
|
||||
:last-updated="new Date('2024-12-05')"
|
||||
/>
|
||||
|
||||
<CalloutBox type="tip" title="Core Principle">
|
||||
<p>
|
||||
<strong>Default to action.</strong> Most decisions should be made by whoever
|
||||
is doing the work. Group decisions are only for irreversible changes or
|
||||
things that affect everyone.
|
||||
</p>
|
||||
</CalloutBox>
|
||||
|
||||
<section id="decision-framework">
|
||||
<h2>The Decision Framework</h2>
|
||||
|
||||
<div class="decision-tree">
|
||||
<div class="decision-level individual">
|
||||
<h3>Individual Action (Just Do It)</h3>
|
||||
<p><strong>Timeline:</strong> Immediate</p>
|
||||
<p><strong>Who decides:</strong> You</p>
|
||||
<ul>
|
||||
<li>Reversible changes</li>
|
||||
<li>Under $50 cost</li>
|
||||
<li>Doesn't affect others' work</li>
|
||||
<li>Safety improvements</li>
|
||||
<li>Cleaning and organizing</li>
|
||||
<li>Documentation</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="decision-level feedback">
|
||||
<h3>Seek Feedback (Post & Wait)</h3>
|
||||
<p><strong>Timeline:</strong> 3-7 days</p>
|
||||
<p><strong>Who decides:</strong> You, with input</p>
|
||||
<ul>
|
||||
<li>$50-$200 expenses</li>
|
||||
<li>Changes to shared spaces</li>
|
||||
<li>New procedures or guidelines</li>
|
||||
<li>Events using significant space</li>
|
||||
<li>Tool modifications</li>
|
||||
<li>Affects specific groups</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="decision-level consensus">
|
||||
<h3>Group Consensus (Meeting)</h3>
|
||||
<p><strong>Timeline:</strong> 9-14 days</p>
|
||||
<p><strong>Who decides:</strong> Present members</p>
|
||||
<ul>
|
||||
<li>Over $200 expenses</li>
|
||||
<li>Permanent infrastructure</li>
|
||||
<li>Policy changes</li>
|
||||
<li>Access and membership</li>
|
||||
<li>Irreversible changes</li>
|
||||
<li>Affects everyone</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="feedback-process">
|
||||
<h2>The Feedback Process</h2>
|
||||
|
||||
<p>
|
||||
When your action needs feedback (middle tier), here's how to gather it effectively:
|
||||
</p>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
<h4>1. Document Your Proposal</h4>
|
||||
<p>Write a clear description including:</p>
|
||||
<ul>
|
||||
<li>What you want to do</li>
|
||||
<li>Why it's needed</li>
|
||||
<li>How it affects others</li>
|
||||
<li>Estimated cost and timeline</li>
|
||||
<li>How to provide feedback</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<h4>2. Post in Multiple Places</h4>
|
||||
<ul>
|
||||
<li>Wiki or documentation site</li>
|
||||
<li>Slack/Discord announcement</li>
|
||||
<li>Physical board in the space</li>
|
||||
<li>Mailing list if significant</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<h4>3. Set a Deadline</h4>
|
||||
<ul>
|
||||
<li>Small changes: 72 hours</li>
|
||||
<li>Medium changes: 7 days</li>
|
||||
<li>Large but not permanent: 9-14 days</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<h4>4. Address Feedback</h4>
|
||||
<ul>
|
||||
<li>Acknowledge all input</li>
|
||||
<li>Adjust plan if needed</li>
|
||||
<li>Explain if you can't accommodate</li>
|
||||
<li>Find compromise when possible</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<h4>5. Proceed or Escalate</h4>
|
||||
<ul>
|
||||
<li>No objections? Do it!</li>
|
||||
<li>Minor concerns? Address and proceed</li>
|
||||
<li>Major objections? Bring to meeting</li>
|
||||
<li>Deadlock? Board mediates</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ol>
|
||||
</section>
|
||||
|
||||
<section id="meetings">
|
||||
<h2>Membership Meetings</h2>
|
||||
|
||||
<p>
|
||||
Some decisions need face-to-face discussion. Here's how our meetings work:
|
||||
</p>
|
||||
|
||||
<h3>Regular Meetings</h3>
|
||||
<ul>
|
||||
<li><strong>Frequency:</strong> Monthly, first Tuesday</li>
|
||||
<li><strong>Time:</strong> 7:00 PM</li>
|
||||
<li><strong>Location:</strong> Main area of the space</li>
|
||||
<li><strong>Who can attend:</strong> Anyone (guests welcome)</li>
|
||||
<li><strong>Who can vote:</strong> Dues-paying members</li>
|
||||
</ul>
|
||||
|
||||
<h3>Meeting Agenda</h3>
|
||||
<ol>
|
||||
<li>Welcome and introductions (5 min)</li>
|
||||
<li>Review previous meeting actions (5 min)</li>
|
||||
<li>Officer reports (10 min)</li>
|
||||
<li>Old business (15 min)</li>
|
||||
<li>New proposals (30 min)</li>
|
||||
<li>Open discussion (15 min)</li>
|
||||
<li>Action items and close (5 min)</li>
|
||||
</ol>
|
||||
|
||||
<h3>Proposal Process</h3>
|
||||
<ul>
|
||||
<li>Post proposal 14 days before meeting</li>
|
||||
<li>Present proposal at meeting (5 min max)</li>
|
||||
<li>Q&A and discussion (10 min max)</li>
|
||||
<li>Modify based on feedback if needed</li>
|
||||
<li>Call for consensus or vote</li>
|
||||
</ul>
|
||||
|
||||
<CalloutBox type="info">
|
||||
<p>
|
||||
<strong>Keep it short:</strong> Meetings should be under 90 minutes.
|
||||
Long discussions can continue after the formal meeting.
|
||||
</p>
|
||||
</CalloutBox>
|
||||
</section>
|
||||
|
||||
<section id="consensus">
|
||||
<h2>Consensus vs Voting</h2>
|
||||
|
||||
<h3>We Prefer Consensus</h3>
|
||||
<p>
|
||||
Consensus doesn't mean everyone loves the decision, but everyone can live with it.
|
||||
Signs of consensus:
|
||||
</p>
|
||||
<ul>
|
||||
<li>No strong objections raised</li>
|
||||
<li>People saying "I can live with that"</li>
|
||||
<li>Thumbs up or sideways (not down)</li>
|
||||
<li>General nodding and agreement</li>
|
||||
</ul>
|
||||
|
||||
<h3>When to Vote</h3>
|
||||
<p>If consensus fails after reasonable discussion:</p>
|
||||
<ul>
|
||||
<li>Board elections (always vote)</li>
|
||||
<li>Bylaw changes (2/3 majority required)</li>
|
||||
<li>Budget over $500 (majority)</li>
|
||||
<li>Membership issues (majority)</li>
|
||||
<li>Deadlocked after 15 minutes discussion</li>
|
||||
</ul>
|
||||
|
||||
<h3>Blocking Consensus</h3>
|
||||
<p>
|
||||
Anyone can block consensus, but it's a serious action. If you block:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Explain your fundamental concern</li>
|
||||
<li>Propose an alternative if possible</li>
|
||||
<li>Be willing to work toward resolution</li>
|
||||
<li>Consider if it's really block-worthy</li>
|
||||
</ul>
|
||||
<p class="text-muted">
|
||||
Blocking should be rare. Most concerns can be addressed through modification.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section id="special-decisions">
|
||||
<h2>Special Decision Types</h2>
|
||||
|
||||
<h3>Emergency Decisions</h3>
|
||||
<p>When immediate action is needed (safety, legal, infrastructure failure):</p>
|
||||
<ul>
|
||||
<li>Any member can act to protect safety</li>
|
||||
<li>Any board member can make emergency decisions</li>
|
||||
<li>Document actions taken</li>
|
||||
<li>Report at next meeting</li>
|
||||
<li>Retroactive approval if needed</li>
|
||||
</ul>
|
||||
|
||||
<h3>Financial Decisions</h3>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Amount</th>
|
||||
<th>Who Decides</th>
|
||||
<th>Process</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Under $50</td>
|
||||
<td>Individual member</td>
|
||||
<td>Just do it, save receipt</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>$50 - $200</td>
|
||||
<td>Individual with feedback</td>
|
||||
<td>Post proposal, wait 72 hours</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>$200 - $500</td>
|
||||
<td>Membership meeting</td>
|
||||
<td>Proposal + discussion</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Over $500</td>
|
||||
<td>Membership vote</td>
|
||||
<td>14-day notice + formal vote</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h3>Access Decisions</h3>
|
||||
<ul>
|
||||
<li><strong>New member approval:</strong> Board reviews application</li>
|
||||
<li><strong>Key/card access:</strong> After orientation completion</li>
|
||||
<li><strong>Tool certification:</strong> Certified member signs off</li>
|
||||
<li><strong>Access revocation:</strong> Board decision with member appeal rights</li>
|
||||
<li><strong>Banning:</strong> See Community Standards process</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="documentation">
|
||||
<h2>Documenting Decisions</h2>
|
||||
|
||||
<p>All decisions need documentation proportional to their impact:</p>
|
||||
|
||||
<h3>Individual Actions</h3>
|
||||
<ul>
|
||||
<li>Note in appropriate log or wiki</li>
|
||||
<li>Receipt in expense folder</li>
|
||||
<li>Before/after photos if visual change</li>
|
||||
</ul>
|
||||
|
||||
<h3>Feedback Decisions</h3>
|
||||
<ul>
|
||||
<li>Original proposal preserved</li>
|
||||
<li>Feedback received noted</li>
|
||||
<li>Final implementation documented</li>
|
||||
<li>Outcomes tracked</li>
|
||||
</ul>
|
||||
|
||||
<h3>Meeting Decisions</h3>
|
||||
<ul>
|
||||
<li>Recorded in meeting minutes</li>
|
||||
<li>Posted within 7 days</li>
|
||||
<li>Action items tracked</li>
|
||||
<li>Follow-up at next meeting</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="conflicts">
|
||||
<h2>When Decisions Conflict</h2>
|
||||
|
||||
<p>Sometimes decisions or actions conflict. Here's the precedence:</p>
|
||||
|
||||
<ol>
|
||||
<li><strong>Safety always wins</strong> - Safety concerns override everything</li>
|
||||
<li><strong>Legal requirements</strong> - We must follow the law</li>
|
||||
<li><strong>Bylaws</strong> - Our governing document</li>
|
||||
<li><strong>Meeting decisions</strong> - Group consensus/votes</li>
|
||||
<li><strong>Board decisions</strong> - Within their scope</li>
|
||||
<li><strong>Do-ocracy actions</strong> - Individual initiative</li>
|
||||
</ol>
|
||||
|
||||
<p>When same-level decisions conflict:</p>
|
||||
<ul>
|
||||
<li>More recent generally wins</li>
|
||||
<li>More specific overrides general</li>
|
||||
<li>Irreversible overrides reversible</li>
|
||||
<li>Talk it out when unclear</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="tips">
|
||||
<h2>Tips for Good Decision Making</h2>
|
||||
|
||||
<div class="tips-grid">
|
||||
<div class="tip">
|
||||
<h4>Bias Toward Action</h4>
|
||||
<p>When in doubt, try it. Most things are reversible.</p>
|
||||
</div>
|
||||
|
||||
<div class="tip">
|
||||
<h4>Communicate Early</h4>
|
||||
<p>Surprises create conflict. Share plans before implementing.</p>
|
||||
</div>
|
||||
|
||||
<div class="tip">
|
||||
<h4>Accept Good Enough</h4>
|
||||
<p>Perfect consensus is rare. Workable solutions are valuable.</p>
|
||||
</div>
|
||||
|
||||
<div class="tip">
|
||||
<h4>Time Box Discussions</h4>
|
||||
<p>Set limits. Not every decision needs an hour of debate.</p>
|
||||
</div>
|
||||
|
||||
<div class="tip">
|
||||
<h4>Document Rationale</h4>
|
||||
<p>Future members need to understand why, not just what.</p>
|
||||
</div>
|
||||
|
||||
<div class="tip">
|
||||
<h4>Review and Adjust</h4>
|
||||
<p>Decisions aren't permanent. Review and improve over time.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<CalloutBox type="tip">
|
||||
<p>
|
||||
<strong>Remember:</strong> The goal is to enable action, not prevent it.
|
||||
When the decision-making process becomes a barrier to doing things,
|
||||
it's time to simplify the process.
|
||||
</p>
|
||||
</CalloutBox>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import DocumentHeader from '@/components/document/DocumentHeader.vue'
|
||||
import CalloutBox from '@/components/ui/CalloutBox.vue'
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.decision-making-page {
|
||||
max-width: $max-content-width;
|
||||
|
||||
section {
|
||||
margin-bottom: $space-7;
|
||||
}
|
||||
|
||||
.decision-tree {
|
||||
display: grid;
|
||||
gap: $space-4;
|
||||
margin: $space-5 0;
|
||||
|
||||
.decision-level {
|
||||
padding: $space-4;
|
||||
border-radius: $radius-md;
|
||||
border: 2px solid;
|
||||
|
||||
h3 {
|
||||
margin-bottom: $space-2;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: $space-3;
|
||||
font-size: $font-size-sm;
|
||||
}
|
||||
|
||||
&.individual {
|
||||
background-color: rgba($color-success, 0.05);
|
||||
border-color: $color-success;
|
||||
|
||||
h3 {
|
||||
color: $color-success;
|
||||
}
|
||||
}
|
||||
|
||||
&.feedback {
|
||||
background-color: rgba($color-warning, 0.05);
|
||||
border-color: $color-warning;
|
||||
|
||||
h3 {
|
||||
color: $color-warning;
|
||||
}
|
||||
}
|
||||
|
||||
&.consensus {
|
||||
background-color: rgba($color-accent, 0.05);
|
||||
border-color: $color-accent;
|
||||
|
||||
h3 {
|
||||
color: $color-accent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ol li {
|
||||
margin-bottom: $space-4;
|
||||
|
||||
h4 {
|
||||
color: $color-accent;
|
||||
margin-bottom: $space-2;
|
||||
}
|
||||
}
|
||||
|
||||
.tips-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: $space-4;
|
||||
margin: $space-5 0;
|
||||
|
||||
.tip {
|
||||
padding: $space-3;
|
||||
background-color: $color-paper-light;
|
||||
border-radius: $radius-md;
|
||||
|
||||
h4 {
|
||||
color: $color-accent;
|
||||
margin-bottom: $space-2;
|
||||
font-size: $font-size-md;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
font-size: $font-size-sm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
table {
|
||||
margin: $space-5 0;
|
||||
}
|
||||
}</style>
|
||||
@@ -0,0 +1,393 @@
|
||||
<template>
|
||||
<div class="do-ocracy-page">
|
||||
<DocumentHeader
|
||||
title="The Do-ocracy Guide"
|
||||
description="How to actually get things done at HeatSync Labs. If you want something done: Just do it!"
|
||||
:last-updated="new Date('2024-12-05')"
|
||||
/>
|
||||
|
||||
<CalloutBox type="tip" title="The Golden Rule">
|
||||
<p>
|
||||
<strong>If you want something done: Just do it!</strong>
|
||||
</p>
|
||||
<p>
|
||||
Doing a task is in itself justification for you being the person who does that job.
|
||||
Authority is earned through action, not election.
|
||||
</p>
|
||||
</CalloutBox>
|
||||
|
||||
<section id="what-is-doocracy">
|
||||
<h2>What is Do-ocracy?</h2>
|
||||
|
||||
<p class="lead">
|
||||
In a do-ocracy, individuals choose to take on tasks and roles independently.
|
||||
The authority to make decisions and take action lies with those who do the work.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This is different from democracy (where everyone votes) and different from
|
||||
meritocracy (where the "best" person does it). In a do-ocracy, <strong>whoever
|
||||
shows up and does the work has the authority to make decisions about that work.</strong>
|
||||
</p>
|
||||
|
||||
<h3>Core Principles</h3>
|
||||
<ul>
|
||||
<li><strong>Initiative:</strong> Don't wait for permission or assignment</li>
|
||||
<li><strong>Action:</strong> Doing beats planning</li>
|
||||
<li><strong>Communication:</strong> Tell others what you're doing</li>
|
||||
<li><strong>Openness:</strong> Be receptive to feedback and help</li>
|
||||
<li><strong>Responsibility:</strong> Own your actions and their outcomes</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="how-it-works">
|
||||
<h2>How It Works in Practice</h2>
|
||||
|
||||
<div class="process-steps">
|
||||
<div class="step">
|
||||
<h3>1. See a Need</h3>
|
||||
<p>Notice something that needs doing: broken equipment, messy area, missing documentation, cool project idea.</p>
|
||||
</div>
|
||||
|
||||
<div class="step">
|
||||
<h3>2. Communicate Intent</h3>
|
||||
<p>For significant actions, post your plan on the wiki, Slack, or physical board. This allows for feedback.</p>
|
||||
</div>
|
||||
|
||||
<div class="step">
|
||||
<h3>3. Seek Input</h3>
|
||||
<p>Actively ask for feedback, especially from those who might be affected. Address constructive objections.</p>
|
||||
</div>
|
||||
|
||||
<div class="step">
|
||||
<h3>4. Take Action</h3>
|
||||
<p>If no unresolvable objections arise within 9-14 days (or immediately for small tasks), proceed responsibly.</p>
|
||||
</div>
|
||||
|
||||
<div class="step">
|
||||
<h3>5. Document Results</h3>
|
||||
<p>Record what you did, how much it cost, and any relevant details for future reference.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="when-to-act">
|
||||
<h2>When to Just Act vs When to Discuss</h2>
|
||||
|
||||
<div class="decision-grid">
|
||||
<div class="decision-card act">
|
||||
<h3>Just Do It</h3>
|
||||
<ul>
|
||||
<li>Cleaning and organizing</li>
|
||||
<li>Fixing broken things</li>
|
||||
<li>Routine maintenance</li>
|
||||
<li>Documentation improvements</li>
|
||||
<li>Small improvements (under $50)</li>
|
||||
<li>Reversible changes</li>
|
||||
<li>Safety fixes</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="decision-card discuss">
|
||||
<h3>Seek Feedback First</h3>
|
||||
<ul>
|
||||
<li>Changes affecting others' work</li>
|
||||
<li>Spending $50-$200</li>
|
||||
<li>Moving/reorganizing shared spaces</li>
|
||||
<li>New policies or procedures</li>
|
||||
<li>Tool modifications</li>
|
||||
<li>Events using significant space</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="decision-card vote">
|
||||
<h3>Needs Formal Approval</h3>
|
||||
<ul>
|
||||
<li>Spending over $200</li>
|
||||
<li>Permanent infrastructure changes</li>
|
||||
<li>Legal commitments</li>
|
||||
<li>Bylaw changes</li>
|
||||
<li>Safety policy changes</li>
|
||||
<li>Membership decisions</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="practical-examples">
|
||||
<h2>Practical Examples</h2>
|
||||
|
||||
<div class="example-box">
|
||||
<h3>Example: Organizing a Workshop</h3>
|
||||
<p>Sarah wants to run a soldering workshop:</p>
|
||||
<ol>
|
||||
<li>She posts on Slack: "Planning a soldering workshop for next Saturday 2-5pm"</li>
|
||||
<li>Gets feedback about material costs and space availability</li>
|
||||
<li>Orders supplies using the workshop budget</li>
|
||||
<li>Runs the workshop</li>
|
||||
<li>Documents attendance and expenses on the wiki</li>
|
||||
</ol>
|
||||
<p class="text-muted">
|
||||
Sarah didn't need permission - she took initiative, communicated, and made it happen.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="example-box">
|
||||
<h3>Example: Tool Area Reorganization</h3>
|
||||
<p>Mike notices the electronics bench is chaotic:</p>
|
||||
<ol>
|
||||
<li>Takes photos of current state</li>
|
||||
<li>Posts proposal with mockup on wiki: "Reorganizing electronics bench for better workflow"</li>
|
||||
<li>Waits 10 days for feedback, incorporates suggestions</li>
|
||||
<li>Spends a Saturday reorganizing with help from volunteers</li>
|
||||
<li>Updates tool documentation with new layout</li>
|
||||
</ol>
|
||||
<p class="text-muted">
|
||||
Mike communicated first because this affected others' workspaces, but still led the change himself.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="budget">
|
||||
<h2>Do-ocracy Budget Guidelines</h2>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Amount</th>
|
||||
<th>Process</th>
|
||||
<th>Documentation</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Under $50</td>
|
||||
<td>Just do it</td>
|
||||
<td>Save receipt, note in expense log</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>$50 - $200</td>
|
||||
<td>Post intent, wait 72 hours for feedback</td>
|
||||
<td>Receipt + brief wiki entry</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Over $200</td>
|
||||
<td>Formal proposal at meeting</td>
|
||||
<td>Full proposal + receipts + report</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<CalloutBox type="info">
|
||||
<p>
|
||||
<strong>Reimbursement:</strong> Submit receipts with documentation to the
|
||||
treasurer. Approved do-ocracy expenses are reimbursed within 30 days.
|
||||
</p>
|
||||
</CalloutBox>
|
||||
</section>
|
||||
|
||||
<section id="boundaries">
|
||||
<h2>Boundaries and Limitations</h2>
|
||||
|
||||
<h3>Do-ocracy Does NOT Apply To:</h3>
|
||||
<ul>
|
||||
<li><strong>Safety violations:</strong> Never compromise safety for expediency</li>
|
||||
<li><strong>Others' property:</strong> Don't modify someone else's project without permission</li>
|
||||
<li><strong>Irreversible changes:</strong> Major alterations need group consensus</li>
|
||||
<li><strong>Legal matters:</strong> Contracts, liability issues need board approval</li>
|
||||
<li><strong>Access control:</strong> Membership and access decisions follow formal process</li>
|
||||
</ul>
|
||||
|
||||
<h3>Conflict Resolution</h3>
|
||||
<p>When do-ocracy actions conflict:</p>
|
||||
<ol>
|
||||
<li><strong>Direct dialogue:</strong> Talk to each other first</li>
|
||||
<li><strong>Seek mediation:</strong> Ask a neutral member to help</li>
|
||||
<li><strong>Community input:</strong> Bring to next meeting if needed</li>
|
||||
<li><strong>Board intervention:</strong> Only for unresolvable disputes</li>
|
||||
</ol>
|
||||
</section>
|
||||
|
||||
<section id="tips">
|
||||
<h2>Tips for Successful Do-ocracy</h2>
|
||||
|
||||
<div class="tips-grid">
|
||||
<div class="tip">
|
||||
<h4>Start Small</h4>
|
||||
<p>Build trust by successfully completing small projects before taking on major initiatives.</p>
|
||||
</div>
|
||||
|
||||
<div class="tip">
|
||||
<h4>Document Everything</h4>
|
||||
<p>Future members benefit from knowing what was done and why. Over-documentation beats under-documentation.</p>
|
||||
</div>
|
||||
|
||||
<div class="tip">
|
||||
<h4>Ask for Help</h4>
|
||||
<p>Do-ocracy doesn't mean working alone. Recruit others who share your vision.</p>
|
||||
</div>
|
||||
|
||||
<div class="tip">
|
||||
<h4>Accept Feedback Gracefully</h4>
|
||||
<p>Not all ideas work out. Be ready to adjust or even abandon plans based on community input.</p>
|
||||
</div>
|
||||
|
||||
<div class="tip">
|
||||
<h4>Celebrate Successes</h4>
|
||||
<p>Share what you accomplished! It inspires others and builds community momentum.</p>
|
||||
</div>
|
||||
|
||||
<div class="tip">
|
||||
<h4>Learn from Failures</h4>
|
||||
<p>Things will go wrong. Document what didn't work so others can learn.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<CalloutBox type="tip" title="Remember">
|
||||
<p>
|
||||
<strong>Perfect is the enemy of done.</strong> It's better to do something
|
||||
imperfectly than to do nothing perfectly. The community will help iterate
|
||||
and improve over time.
|
||||
</p>
|
||||
</CalloutBox>
|
||||
|
||||
<section id="resources">
|
||||
<h2>Resources</h2>
|
||||
<ul>
|
||||
<li>Wiki: Document your projects and read about others</li>
|
||||
<li>Slack #do-ocracy: Coordinate with other doers</li>
|
||||
<li>Physical board: Post plans and gather feedback</li>
|
||||
<li>Treasurer: Submit reimbursement requests</li>
|
||||
<li>Meeting notes: Review past do-ocracy discussions</li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import DocumentHeader from '@/components/document/DocumentHeader.vue'
|
||||
import CalloutBox from '@/components/ui/CalloutBox.vue'
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.do-ocracy-page {
|
||||
max-width: $max-content-width;
|
||||
|
||||
section {
|
||||
margin-bottom: $space-7;
|
||||
}
|
||||
|
||||
.process-steps {
|
||||
margin: $space-5 0;
|
||||
|
||||
.step {
|
||||
padding: $space-4;
|
||||
margin-bottom: $space-3;
|
||||
background-color: $color-paper-light;
|
||||
border-left: 4px solid $color-accent;
|
||||
border-radius: $radius-md;
|
||||
|
||||
h3 {
|
||||
color: $color-accent;
|
||||
margin-bottom: $space-2;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.decision-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||
gap: $space-4;
|
||||
margin: $space-5 0;
|
||||
|
||||
.decision-card {
|
||||
padding: $space-4;
|
||||
border-radius: $radius-md;
|
||||
|
||||
h3 {
|
||||
margin-bottom: $space-3;
|
||||
font-size: $font-size-lg;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding-left: $space-4;
|
||||
}
|
||||
|
||||
&.act {
|
||||
background-color: rgba($color-success, 0.05);
|
||||
border: 2px solid $color-success;
|
||||
|
||||
h3 {
|
||||
color: $color-success;
|
||||
}
|
||||
}
|
||||
|
||||
&.discuss {
|
||||
background-color: rgba($color-warning, 0.05);
|
||||
border: 2px solid $color-warning;
|
||||
|
||||
h3 {
|
||||
color: $color-warning;
|
||||
}
|
||||
}
|
||||
|
||||
&.vote {
|
||||
background-color: rgba($color-accent, 0.05);
|
||||
border: 2px solid $color-accent;
|
||||
|
||||
h3 {
|
||||
color: $color-accent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.example-box {
|
||||
padding: $space-5;
|
||||
margin: $space-4 0;
|
||||
background-color: $color-paper-light;
|
||||
border-radius: $radius-md;
|
||||
|
||||
h3 {
|
||||
color: $color-accent;
|
||||
margin-bottom: $space-3;
|
||||
}
|
||||
|
||||
ol {
|
||||
margin: $space-3 0;
|
||||
}
|
||||
}
|
||||
|
||||
.tips-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: $space-4;
|
||||
margin: $space-5 0;
|
||||
|
||||
.tip {
|
||||
padding: $space-3;
|
||||
background-color: $color-paper-light;
|
||||
border-radius: $radius-md;
|
||||
|
||||
h4 {
|
||||
color: $color-accent;
|
||||
margin-bottom: $space-2;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
font-size: $font-size-sm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
table {
|
||||
margin: $space-5 0;
|
||||
}
|
||||
}</style>
|
||||
@@ -0,0 +1,225 @@
|
||||
<template>
|
||||
<div class="home-page">
|
||||
<DocumentHeader
|
||||
title="Hackerspace Governance in a Box"
|
||||
description="A complete governance framework for hackerspaces, based on do-ocracy principles and community-driven decision making."
|
||||
:show-meta="false"
|
||||
/>
|
||||
|
||||
<section class="intro-section">
|
||||
<h2>Welcome to Your Governance Framework</h2>
|
||||
<p class="lead">
|
||||
This site contains everything you need to run a successful hackerspace:
|
||||
bylaws, community standards, decision-making processes, and operational
|
||||
guidelines that actually work in practice.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<CalloutBox type="tip" title="Adapt This for Your Space">
|
||||
<p>
|
||||
While this framework is tailored for {{ hackerspaceStore.hackerspace.name }},
|
||||
it's designed to be easily adapted for any hackerspace. Replace our name
|
||||
with yours, adjust the specifics to match your community's needs, and
|
||||
you'll have a complete governance system ready to go.
|
||||
</p>
|
||||
</CalloutBox>
|
||||
|
||||
<section class="principles-section">
|
||||
<h2>Core Principles</h2>
|
||||
|
||||
<div class="principle-grid">
|
||||
<div class="principle-card">
|
||||
<h3>Do-ocracy</h3>
|
||||
<p>
|
||||
If you want something done, do it. Authority comes from taking action,
|
||||
not from titles or elections. Those who do the work make the decisions.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="principle-card">
|
||||
<h3>Be Excellent</h3>
|
||||
<p>
|
||||
Respect everyone's right to exist and make things. Take care of the
|
||||
space so others can use it. Handle conflicts directly when you can.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="principle-card">
|
||||
<h3>Community First</h3>
|
||||
<p>
|
||||
The space exists so people can make things. Every decision should
|
||||
support that mission. We protect the community's ability to create.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="principle-card">
|
||||
<h3>Iterate & Improve</h3>
|
||||
<p>
|
||||
Our governance isn't perfect, and that's okay. We continuously update
|
||||
our systems based on what works and what doesn't.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="structure-section">
|
||||
<h2>How This Framework Works</h2>
|
||||
|
||||
<dl class="structure-list">
|
||||
<dt>Bylaws</dt>
|
||||
<dd>
|
||||
The legal foundation required for 501(c)(3) status. Minimal and
|
||||
empowering, designed to meet legal requirements while maximizing
|
||||
member autonomy.
|
||||
</dd>
|
||||
|
||||
<dt>Community Standards</dt>
|
||||
<dd>
|
||||
Clear expectations for behavior and a transparent accountability
|
||||
process. Protects everyone's ability to participate safely.
|
||||
</dd>
|
||||
|
||||
<dt>Do-ocracy Guide</dt>
|
||||
<dd>
|
||||
How to actually get things done. When to act independently, when
|
||||
to seek feedback, and how to document your work.
|
||||
</dd>
|
||||
|
||||
<dt>Decision Making</dt>
|
||||
<dd>
|
||||
When meetings are needed vs when you can just act. Designed for
|
||||
9-14 day proposal cycles, not months of bureaucracy.
|
||||
</dd>
|
||||
|
||||
<dt>The Board</dt>
|
||||
<dd>
|
||||
Limited to infrastructure and conflict resolution. Board members
|
||||
are "wardens" not leaders, maintaining the space without
|
||||
controlling its direction.
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
|
||||
<section class="getting-started">
|
||||
<h2>Getting Started</h2>
|
||||
|
||||
<p>
|
||||
Whether you're a new member, a board member, or starting your own
|
||||
hackerspace, here's how to use this framework:
|
||||
</p>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
<strong>New Members:</strong> Start with the Community Standards
|
||||
to understand expectations, then read the Do-ocracy Guide to learn
|
||||
how to contribute.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Active Members:</strong> Reference the Decision Making
|
||||
section when proposing changes. Use the Do-ocracy Guide for daily
|
||||
operations.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Board Members:</strong> Focus on the Bylaws and Board
|
||||
sections. Remember: your role is to maintain, not to lead.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Other Hackerspaces:</strong> Jump to "Adapt This" for a
|
||||
guide on customizing this framework for your community.
|
||||
</li>
|
||||
</ol>
|
||||
</section>
|
||||
|
||||
<CalloutBox type="info" title="About This Framework">
|
||||
<p>
|
||||
This governance framework synthesizes best practices from successful
|
||||
hackerspaces worldwide, particularly drawing from the Hackerspace
|
||||
Blueprint and decades of community experience. It's licensed under
|
||||
Creative Commons for sharing and adaptation.
|
||||
</p>
|
||||
</CalloutBox>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import DocumentHeader from '@/components/document/DocumentHeader.vue'
|
||||
import CalloutBox from '@/components/ui/CalloutBox.vue'
|
||||
import { useHackerspaceStore } from '@/stores/hackerspace'
|
||||
|
||||
const hackerspaceStore = useHackerspaceStore()
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.home-page {
|
||||
max-width: $max-content-width;
|
||||
}
|
||||
|
||||
.intro-section {
|
||||
margin-bottom: $space-7;
|
||||
}
|
||||
|
||||
.principles-section {
|
||||
margin-bottom: $space-7;
|
||||
}
|
||||
|
||||
.principle-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||
gap: $space-5;
|
||||
margin-top: $space-5;
|
||||
}
|
||||
|
||||
.principle-card {
|
||||
padding: $space-5;
|
||||
background-color: $color-paper-light;
|
||||
border-radius: $radius-md;
|
||||
border-left: 4px solid $color-accent;
|
||||
|
||||
h3 {
|
||||
font-size: $font-size-lg;
|
||||
margin-bottom: $space-3;
|
||||
color: $color-accent;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
font-size: $font-size-sm;
|
||||
}
|
||||
}
|
||||
|
||||
.structure-section {
|
||||
margin-bottom: $space-7;
|
||||
}
|
||||
|
||||
.structure-list {
|
||||
margin-top: $space-5;
|
||||
|
||||
dt {
|
||||
font-weight: 600;
|
||||
margin-bottom: $space-2;
|
||||
color: $color-accent;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-bottom: $space-4;
|
||||
margin-left: 0;
|
||||
padding-left: $space-5;
|
||||
border-left: 2px solid $color-border;
|
||||
color: $color-text;
|
||||
}
|
||||
}
|
||||
|
||||
.getting-started {
|
||||
margin-bottom: $space-7;
|
||||
|
||||
ol {
|
||||
margin-top: $space-4;
|
||||
padding-left: $space-5;
|
||||
|
||||
li {
|
||||
margin-bottom: $space-3;
|
||||
line-height: 1.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,470 @@
|
||||
<template>
|
||||
<div class="membership-page">
|
||||
<DocumentHeader
|
||||
title="Membership"
|
||||
description="How to join HeatSync Labs, membership levels, benefits, and expectations."
|
||||
:last-updated="new Date('2024-12-05')"
|
||||
/>
|
||||
|
||||
<CalloutBox type="info">
|
||||
<p>
|
||||
<strong>HeatSync Labs is open to everyone.</strong> You don't need to be an
|
||||
expert, have specific skills, or fit any particular mold. If you want to
|
||||
make things and learn alongside others, you belong here.
|
||||
</p>
|
||||
</CalloutBox>
|
||||
|
||||
<section id="becoming-member">
|
||||
<h2>Becoming a Member</h2>
|
||||
|
||||
<div class="membership-steps">
|
||||
<div class="step">
|
||||
<h3>1. Visit the Space</h3>
|
||||
<p>Come to an open house or public event. Get a feel for the community and space.</p>
|
||||
</div>
|
||||
|
||||
<div class="step">
|
||||
<h3>2. Attend Orientation</h3>
|
||||
<p>Learn about safety, culture, and how to use the space effectively.</p>
|
||||
</div>
|
||||
|
||||
<div class="step">
|
||||
<h3>3. Submit Application</h3>
|
||||
<p>Simple form with emergency contact and agreement to community standards.</p>
|
||||
</div>
|
||||
|
||||
<div class="step">
|
||||
<h3>4. Pay Dues</h3>
|
||||
<p>Monthly dues support rent, utilities, and supplies. Sliding scale available.</p>
|
||||
</div>
|
||||
|
||||
<div class="step">
|
||||
<h3>5. Get Access</h3>
|
||||
<p>Receive your key/card and start making things!</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="membership-levels">
|
||||
<h2>Membership Levels</h2>
|
||||
|
||||
<div class="membership-grid">
|
||||
<div class="membership-card">
|
||||
<h3>Friend of the Space</h3>
|
||||
<p class="price">Free</p>
|
||||
<ul>
|
||||
<li>Attend public events</li>
|
||||
<li>Use space during open hours</li>
|
||||
<li>Join mailing list/Slack</li>
|
||||
<li>Participate in community</li>
|
||||
</ul>
|
||||
<p class="note">No voting rights or 24/7 access</p>
|
||||
</div>
|
||||
|
||||
<div class="membership-card featured">
|
||||
<h3>Regular Member</h3>
|
||||
<p class="price">$50/month</p>
|
||||
<ul>
|
||||
<li>24/7 access to space</li>
|
||||
<li>Storage space (small)</li>
|
||||
<li>Tool certification eligibility</li>
|
||||
<li>Workshop discounts</li>
|
||||
<li>Voting rights after 3 months</li>
|
||||
</ul>
|
||||
<p class="note">Standard membership for most</p>
|
||||
</div>
|
||||
|
||||
<div class="membership-card">
|
||||
<h3>Supporting Member</h3>
|
||||
<p class="price">$100+/month</p>
|
||||
<ul>
|
||||
<li>All regular member benefits</li>
|
||||
<li>Additional storage space</li>
|
||||
<li>Priority workshop registration</li>
|
||||
<li>Guest passes (2/month)</li>
|
||||
<li>Good karma and our thanks</li>
|
||||
</ul>
|
||||
<p class="note">For those who can contribute more</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<CalloutBox type="tip">
|
||||
<p>
|
||||
<strong>Sliding Scale Available:</strong> We never want money to be a barrier.
|
||||
If you can't afford full dues, talk to a board member about reduced rates
|
||||
or work-trade options. We'd rather have you as an active member than not at all.
|
||||
</p>
|
||||
</CalloutBox>
|
||||
</section>
|
||||
|
||||
<section id="voting-member">
|
||||
<h2>Becoming a Voting Member</h2>
|
||||
|
||||
<p>
|
||||
Voting members shape the direction of HeatSync Labs. To become one:
|
||||
</p>
|
||||
|
||||
<ol>
|
||||
<li><strong>Be a dues-paying member</strong> in good standing</li>
|
||||
<li><strong>Actively contribute</strong> within the last 6 months</li>
|
||||
<li><strong>Complete orientation</strong> and understand our culture</li>
|
||||
<li><strong>Participate regularly</strong> in space activities</li>
|
||||
</ol>
|
||||
|
||||
<h3>What Counts as Active Contribution?</h3>
|
||||
<ul>
|
||||
<li>Working on projects in the space</li>
|
||||
<li>Teaching workshops or skills</li>
|
||||
<li>Maintaining tools or areas</li>
|
||||
<li>Organizing events</li>
|
||||
<li>Improving documentation</li>
|
||||
<li>Helping other members</li>
|
||||
<li>Participating in workdays</li>
|
||||
</ul>
|
||||
|
||||
<p class="text-muted">
|
||||
Contribution is self-documented. If you're doing things, you're contributing.
|
||||
No need for formal tracking or approval.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section id="member-benefits">
|
||||
<h2>Member Benefits</h2>
|
||||
|
||||
<div class="benefits-grid">
|
||||
<div class="benefit">
|
||||
<h4>24/7 Access</h4>
|
||||
<p>Work on projects whenever inspiration strikes</p>
|
||||
</div>
|
||||
|
||||
<div class="benefit">
|
||||
<h4>Tool Library</h4>
|
||||
<p>Access to thousands of dollars worth of tools</p>
|
||||
</div>
|
||||
|
||||
<div class="benefit">
|
||||
<h4>Community Knowledge</h4>
|
||||
<p>Learn from experts in dozens of fields</p>
|
||||
</div>
|
||||
|
||||
<div class="benefit">
|
||||
<h4>Project Space</h4>
|
||||
<p>Room to work on things you can't do at home</p>
|
||||
</div>
|
||||
|
||||
<div class="benefit">
|
||||
<h4>Storage</h4>
|
||||
<p>Keep projects and materials at the space</p>
|
||||
</div>
|
||||
|
||||
<div class="benefit">
|
||||
<h4>Classes & Workshops</h4>
|
||||
<p>Free or discounted learning opportunities</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="expectations">
|
||||
<h2>Member Expectations</h2>
|
||||
|
||||
<p>
|
||||
With membership comes responsibility. We expect all members to:
|
||||
</p>
|
||||
|
||||
<h3>Follow the Prime Directive</h3>
|
||||
<ul>
|
||||
<li><strong>Be excellent to each other</strong></li>
|
||||
<li>Follow Community Standards</li>
|
||||
<li>Respect others' work and space</li>
|
||||
<li>Communicate constructively</li>
|
||||
</ul>
|
||||
|
||||
<h3>Maintain the Space</h3>
|
||||
<ul>
|
||||
<li>Clean up after yourself</li>
|
||||
<li>Return tools to their homes</li>
|
||||
<li>Report broken things</li>
|
||||
<li>Participate in occasional workdays</li>
|
||||
<li>Leave things better than you found them</li>
|
||||
</ul>
|
||||
|
||||
<h3>Engage with Community</h3>
|
||||
<ul>
|
||||
<li>Share knowledge when you can</li>
|
||||
<li>Ask for help when you need it</li>
|
||||
<li>Attend meetings occasionally</li>
|
||||
<li>Contribute to the culture</li>
|
||||
</ul>
|
||||
|
||||
<h3>Pay Your Dues</h3>
|
||||
<ul>
|
||||
<li>Pay on time (by the 5th)</li>
|
||||
<li>Communicate if you have issues</li>
|
||||
<li>Update payment info when needed</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="guest-policy">
|
||||
<h2>Guest Policy</h2>
|
||||
|
||||
<p>
|
||||
Members can bring guests, but are responsible for them:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>Always accompany guests</strong> - Don't leave them alone</li>
|
||||
<li><strong>Explain safety rules</strong> - Especially for tools</li>
|
||||
<li><strong>Limit frequency</strong> - Regular visitors should become members</li>
|
||||
<li><strong>Take responsibility</strong> - You're liable for guest actions</li>
|
||||
<li><strong>Sign them in</strong> - Log in the guest book</li>
|
||||
</ul>
|
||||
|
||||
<CalloutBox type="info">
|
||||
<p>
|
||||
Guests are welcome during open hours without a member host.
|
||||
This policy applies to 24/7 access times.
|
||||
</p>
|
||||
</CalloutBox>
|
||||
</section>
|
||||
|
||||
<section id="suspension">
|
||||
<h2>Suspension & Termination</h2>
|
||||
|
||||
<p>
|
||||
We hate to lose members, but sometimes it's necessary:
|
||||
</p>
|
||||
|
||||
<h3>Automatic Suspension</h3>
|
||||
<ul>
|
||||
<li>Dues 60+ days overdue</li>
|
||||
<li>During investigation of serious violations</li>
|
||||
<li>Safety violations endangering others</li>
|
||||
</ul>
|
||||
|
||||
<h3>Termination Causes</h3>
|
||||
<ul>
|
||||
<li>Serious Community Standards violations</li>
|
||||
<li>Theft or intentional damage</li>
|
||||
<li>Repeated violations after warnings</li>
|
||||
<li>Actions harming the organization</li>
|
||||
</ul>
|
||||
|
||||
<h3>Due Process</h3>
|
||||
<ol>
|
||||
<li>Member notified of issue</li>
|
||||
<li>Opportunity to respond</li>
|
||||
<li>Board review and decision</li>
|
||||
<li>Appeal to membership if desired</li>
|
||||
</ol>
|
||||
|
||||
<p class="text-muted">
|
||||
See Community Standards for detailed violation and appeals process.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section id="taking-break">
|
||||
<h2>Taking a Break</h2>
|
||||
|
||||
<p>
|
||||
Life happens. If you need to pause membership:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>Notify the board</strong> before dues are due</li>
|
||||
<li><strong>Return any borrowed items</strong></li>
|
||||
<li><strong>Clean out personal storage</strong></li>
|
||||
<li><strong>Stay connected</strong> via Slack/mailing list if desired</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
We'll welcome you back whenever you're ready. Alumni are always
|
||||
part of the HeatSync family.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section id="how-to-join">
|
||||
<h2>Ready to Join?</h2>
|
||||
|
||||
<div class="join-options">
|
||||
<div class="join-card">
|
||||
<h3>Visit First</h3>
|
||||
<p>Come to our next open house:</p>
|
||||
<ul>
|
||||
<li>Every Thursday, 7-10 PM</li>
|
||||
<li>First Saturday, 12-4 PM</li>
|
||||
<li>Or any public event</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="join-card">
|
||||
<h3>Apply Online</h3>
|
||||
<p>If you've visited:</p>
|
||||
<ul>
|
||||
<li>Fill out application</li>
|
||||
<li>Schedule orientation</li>
|
||||
<li>Set up payment</li>
|
||||
</ul>
|
||||
<a href="#" class="btn">Apply Now</a>
|
||||
</div>
|
||||
|
||||
<div class="join-card">
|
||||
<h3>Questions?</h3>
|
||||
<p>Contact us:</p>
|
||||
<ul>
|
||||
<li>membership@heatsynclabs.org</li>
|
||||
<li>Join Slack for quick answers</li>
|
||||
<li>Ask any member</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<CalloutBox type="tip">
|
||||
<p>
|
||||
<strong>Pro tip:</strong> The best way to know if HeatSync is right for you
|
||||
is to visit. Every community has its own vibe. Come see if ours matches what
|
||||
you're looking for.
|
||||
</p>
|
||||
</CalloutBox>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import DocumentHeader from '@/components/document/DocumentHeader.vue'
|
||||
import CalloutBox from '@/components/ui/CalloutBox.vue'
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.membership-page {
|
||||
max-width: $max-content-width;
|
||||
|
||||
section {
|
||||
margin-bottom: $space-7;
|
||||
}
|
||||
|
||||
.membership-steps {
|
||||
display: grid;
|
||||
gap: $space-3;
|
||||
margin: $space-5 0;
|
||||
|
||||
.step {
|
||||
display: flex;
|
||||
gap: $space-4;
|
||||
padding: $space-3;
|
||||
background-color: $color-paper-light;
|
||||
border-radius: $radius-md;
|
||||
|
||||
h3 {
|
||||
color: $color-accent;
|
||||
margin: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.membership-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||
gap: $space-4;
|
||||
margin: $space-5 0;
|
||||
|
||||
.membership-card {
|
||||
padding: $space-5;
|
||||
border: 2px solid $color-border;
|
||||
border-radius: $radius-md;
|
||||
text-align: center;
|
||||
|
||||
&.featured {
|
||||
border-color: $color-accent;
|
||||
background-color: rgba($color-accent, 0.02);
|
||||
}
|
||||
|
||||
h3 {
|
||||
color: $color-accent;
|
||||
margin-bottom: $space-2;
|
||||
}
|
||||
|
||||
.price {
|
||||
font-size: $font-size-2xl;
|
||||
font-weight: 700;
|
||||
color: $color-text;
|
||||
margin: $space-3 0;
|
||||
}
|
||||
|
||||
ul {
|
||||
text-align: left;
|
||||
margin: $space-4 0;
|
||||
padding-left: $space-4;
|
||||
}
|
||||
|
||||
.note {
|
||||
font-size: $font-size-sm;
|
||||
color: $color-text-muted;
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.benefits-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: $space-4;
|
||||
margin: $space-5 0;
|
||||
|
||||
.benefit {
|
||||
padding: $space-3;
|
||||
background-color: $color-paper-light;
|
||||
border-radius: $radius-md;
|
||||
|
||||
h4 {
|
||||
color: $color-accent;
|
||||
margin-bottom: $space-2;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
font-size: $font-size-sm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.join-options {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||
gap: $space-4;
|
||||
margin: $space-5 0;
|
||||
|
||||
.join-card {
|
||||
padding: $space-4;
|
||||
background-color: $color-paper-light;
|
||||
border-radius: $radius-md;
|
||||
|
||||
h3 {
|
||||
color: $color-accent;
|
||||
margin-bottom: $space-3;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: $space-3 0;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: inline-block;
|
||||
padding: $space-2 $space-4;
|
||||
background-color: $color-accent;
|
||||
color: white;
|
||||
border-radius: $radius-md;
|
||||
text-decoration: none;
|
||||
margin-top: $space-3;
|
||||
|
||||
&:hover {
|
||||
background-color: darken($color-accent, 10%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}</style>
|
||||
@@ -0,0 +1,418 @@
|
||||
<template>
|
||||
<div class="resources-page">
|
||||
<DocumentHeader
|
||||
title="Resources & Templates"
|
||||
description="Practical tools, templates, and resources for running your hackerspace."
|
||||
:last-updated="new Date('2024-12-05')"
|
||||
/>
|
||||
|
||||
<section id="templates">
|
||||
<h2>Document Templates</h2>
|
||||
|
||||
<div class="template-grid">
|
||||
<div class="template-card">
|
||||
<h3>Meeting Templates</h3>
|
||||
<ul>
|
||||
<li>Meeting agenda template</li>
|
||||
<li>Meeting minutes format</li>
|
||||
<li>Proposal template</li>
|
||||
<li>Action items tracker</li>
|
||||
</ul>
|
||||
<button class="btn-download">Download Pack</button>
|
||||
</div>
|
||||
|
||||
<div class="template-card">
|
||||
<h3>Membership Forms</h3>
|
||||
<ul>
|
||||
<li>Membership application</li>
|
||||
<li>Liability waiver</li>
|
||||
<li>Guest sign-in sheet</li>
|
||||
<li>Orientation checklist</li>
|
||||
</ul>
|
||||
<button class="btn-download">Download Pack</button>
|
||||
</div>
|
||||
|
||||
<div class="template-card">
|
||||
<h3>Financial Documents</h3>
|
||||
<ul>
|
||||
<li>Budget template</li>
|
||||
<li>Expense report form</li>
|
||||
<li>Reimbursement request</li>
|
||||
<li>Monthly treasurer report</li>
|
||||
</ul>
|
||||
<button class="btn-download">Download Pack</button>
|
||||
</div>
|
||||
|
||||
<div class="template-card">
|
||||
<h3>Safety & Training</h3>
|
||||
<ul>
|
||||
<li>Tool certification form</li>
|
||||
<li>Safety checklist</li>
|
||||
<li>Incident report</li>
|
||||
<li>Training log</li>
|
||||
</ul>
|
||||
<button class="btn-download">Download Pack</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="guides">
|
||||
<h2>How-To Guides</h2>
|
||||
|
||||
<div class="guide-list">
|
||||
<div class="guide-item">
|
||||
<h3>Starting a Hackerspace</h3>
|
||||
<p>Step-by-step guide from idea to opening day</p>
|
||||
<ul>
|
||||
<li>Finding founding members</li>
|
||||
<li>Choosing a legal structure</li>
|
||||
<li>Finding and negotiating space</li>
|
||||
<li>Initial fundraising</li>
|
||||
<li>Building community</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="guide-item">
|
||||
<h3>501(c)(3) Application</h3>
|
||||
<p>Navigate the nonprofit application process</p>
|
||||
<ul>
|
||||
<li>Form 1023 walkthrough</li>
|
||||
<li>Required documentation</li>
|
||||
<li>Common pitfalls</li>
|
||||
<li>Timeline expectations</li>
|
||||
<li>State-specific requirements</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="guide-item">
|
||||
<h3>Insurance for Hackerspaces</h3>
|
||||
<p>Protect your organization and members</p>
|
||||
<ul>
|
||||
<li>General liability basics</li>
|
||||
<li>Directors & Officers insurance</li>
|
||||
<li>Equipment coverage</li>
|
||||
<li>Event insurance</li>
|
||||
<li>Working with brokers</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="guide-item">
|
||||
<h3>Tool Acquisition</h3>
|
||||
<p>Building your tool library strategically</p>
|
||||
<ul>
|
||||
<li>Priority tool lists by area</li>
|
||||
<li>New vs used equipment</li>
|
||||
<li>Donation strategies</li>
|
||||
<li>Grants and funding</li>
|
||||
<li>Maintenance planning</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="software">
|
||||
<h2>Recommended Software</h2>
|
||||
|
||||
<div class="software-grid">
|
||||
<div class="software-card">
|
||||
<h3>Membership Management</h3>
|
||||
<ul>
|
||||
<li><strong>Wild Apricot:</strong> All-in-one membership platform</li>
|
||||
<li><strong>MemberPress:</strong> WordPress-based solution</li>
|
||||
<li><strong>Open Source:</strong> CiviCRM for nonprofits</li>
|
||||
<li><strong>DIY:</strong> Google Workspace + scripts</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="software-card">
|
||||
<h3>Access Control</h3>
|
||||
<ul>
|
||||
<li><strong>RFID:</strong> DIY solutions on GitHub</li>
|
||||
<li><strong>Commercial:</strong> Kisi, Brivo systems</li>
|
||||
<li><strong>Hybrid:</strong> Arduino + cloud services</li>
|
||||
<li><strong>Simple:</strong> Keypad locks + codes</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="software-card">
|
||||
<h3>Communication</h3>
|
||||
<ul>
|
||||
<li><strong>Chat:</strong> Slack, Discord, Matrix</li>
|
||||
<li><strong>Forum:</strong> Discourse, phpBB</li>
|
||||
<li><strong>Wiki:</strong> MediaWiki, DokuWiki</li>
|
||||
<li><strong>Calendar:</strong> Google Calendar, Nextcloud</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="software-card">
|
||||
<h3>Financial Tools</h3>
|
||||
<ul>
|
||||
<li><strong>Accounting:</strong> QuickBooks, Wave</li>
|
||||
<li><strong>Payments:</strong> Stripe, PayPal, Square</li>
|
||||
<li><strong>Expense:</strong> Expensify for reimbursements</li>
|
||||
<li><strong>Fundraising:</strong> Open Collective</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="community">
|
||||
<h2>Hackerspace Community</h2>
|
||||
|
||||
<h3>Networks & Organizations</h3>
|
||||
<ul>
|
||||
<li><strong>Hackerspace.org:</strong> Global hackerspace wiki and directory</li>
|
||||
<li><strong>Space Federation:</strong> European hackerspace network</li>
|
||||
<li><strong>School Factory:</strong> Educational programs framework</li>
|
||||
<li><strong>Maker Faire:</strong> Event network and resources</li>
|
||||
</ul>
|
||||
|
||||
<h3>Conferences & Events</h3>
|
||||
<ul>
|
||||
<li><strong>Chaos Communication Congress:</strong> Annual hacker conference</li>
|
||||
<li><strong>DEF CON:</strong> Security and hacking conference</li>
|
||||
<li><strong>Maker Faire:</strong> Regional maker events</li>
|
||||
<li><strong>EMF Camp:</strong> UK hacker camp</li>
|
||||
</ul>
|
||||
|
||||
<h3>Online Resources</h3>
|
||||
<ul>
|
||||
<li><strong>Hackerspace Design Patterns:</strong> hackerspace.design</li>
|
||||
<li><strong>Hackerspace Blueprint:</strong> GitHub repository</li>
|
||||
<li><strong>Discourse Forum:</strong> discuss.hackerspaces.org</li>
|
||||
<li><strong>Reddit:</strong> r/hackerspaces</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="books">
|
||||
<h2>Recommended Reading</h2>
|
||||
|
||||
<div class="book-grid">
|
||||
<div class="book">
|
||||
<h4>The Hackerspace Cookbook</h4>
|
||||
<p>Practical recipes for common hackerspace challenges</p>
|
||||
</div>
|
||||
|
||||
<div class="book">
|
||||
<h4>Making Spaces</h4>
|
||||
<p>Design patterns for collaborative workshops</p>
|
||||
</div>
|
||||
|
||||
<div class="book">
|
||||
<h4>The Art of Community</h4>
|
||||
<p>Building and managing online and offline communities</p>
|
||||
</div>
|
||||
|
||||
<div class="book">
|
||||
<h4>Nonprofit Kit for Dummies</h4>
|
||||
<p>Comprehensive guide to nonprofit management</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="legal">
|
||||
<h2>Legal Resources</h2>
|
||||
|
||||
<CalloutBox type="warning">
|
||||
<p>
|
||||
<strong>Not Legal Advice:</strong> These resources are for reference only.
|
||||
Always consult with a qualified attorney for your specific situation.
|
||||
</p>
|
||||
</CalloutBox>
|
||||
|
||||
<h3>Key Documents</h3>
|
||||
<ul>
|
||||
<li>IRS 501(c)(3) requirements and forms</li>
|
||||
<li>State nonprofit incorporation guides</li>
|
||||
<li>Sample bylaws from other hackerspaces</li>
|
||||
<li>Liability waiver templates</li>
|
||||
<li>Insurance requirement checklists</li>
|
||||
</ul>
|
||||
|
||||
<h3>Legal Help</h3>
|
||||
<ul>
|
||||
<li><strong>Pro Bono:</strong> Local bar association referrals</li>
|
||||
<li><strong>Low Cost:</strong> Legal aid societies</li>
|
||||
<li><strong>Specialized:</strong> Nonprofit law centers</li>
|
||||
<li><strong>Online:</strong> LegalZoom, Nolo guides</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="downloads">
|
||||
<h2>Quick Downloads</h2>
|
||||
|
||||
<div class="download-section">
|
||||
<h3>Complete Governance Package</h3>
|
||||
<p>All documents from this site in various formats:</p>
|
||||
<div class="download-buttons">
|
||||
<button class="btn-download">PDF Package</button>
|
||||
<button class="btn-download">Markdown Files</button>
|
||||
<button class="btn-download">Word Documents</button>
|
||||
<button class="btn-download">Google Docs Templates</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="download-section">
|
||||
<h3>Source Code</h3>
|
||||
<p>This website's source code for your own adaptation:</p>
|
||||
<div class="download-buttons">
|
||||
<a href="https://github.com/yourusername/governance-site" class="btn-download">
|
||||
View on GitHub
|
||||
</a>
|
||||
<button class="btn-download">Download ZIP</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<CalloutBox type="tip">
|
||||
<p>
|
||||
<strong>Contributing:</strong> Have resources to share? Submit a pull request
|
||||
on GitHub or email resources@heatsynclabs.org with your suggestions.
|
||||
</p>
|
||||
</CalloutBox>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import DocumentHeader from '@/components/document/DocumentHeader.vue'
|
||||
import CalloutBox from '@/components/ui/CalloutBox.vue'
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.resources-page {
|
||||
max-width: $max-content-width;
|
||||
|
||||
section {
|
||||
margin-bottom: $space-7;
|
||||
}
|
||||
|
||||
.template-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||
gap: $space-4;
|
||||
margin: $space-5 0;
|
||||
|
||||
.template-card {
|
||||
padding: $space-4;
|
||||
background-color: $color-paper-light;
|
||||
border-radius: $radius-md;
|
||||
|
||||
h3 {
|
||||
color: $color-accent;
|
||||
margin-bottom: $space-3;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: $space-3 0;
|
||||
font-size: $font-size-sm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.guide-list {
|
||||
.guide-item {
|
||||
margin-bottom: $space-5;
|
||||
padding: $space-4;
|
||||
background-color: $color-paper-light;
|
||||
border-radius: $radius-md;
|
||||
|
||||
h3 {
|
||||
color: $color-accent;
|
||||
margin-bottom: $space-2;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: $space-3;
|
||||
font-style: italic;
|
||||
color: $color-text-muted;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.software-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||
gap: $space-4;
|
||||
margin: $space-5 0;
|
||||
|
||||
.software-card {
|
||||
padding: $space-4;
|
||||
border: 1px solid $color-border;
|
||||
border-radius: $radius-md;
|
||||
|
||||
h3 {
|
||||
color: $color-accent;
|
||||
margin-bottom: $space-3;
|
||||
}
|
||||
|
||||
ul {
|
||||
font-size: $font-size-sm;
|
||||
|
||||
li {
|
||||
margin-bottom: $space-2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.book-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: $space-4;
|
||||
margin: $space-5 0;
|
||||
|
||||
.book {
|
||||
padding: $space-3;
|
||||
background-color: $color-paper-light;
|
||||
border-radius: $radius-md;
|
||||
|
||||
h4 {
|
||||
color: $color-accent;
|
||||
margin-bottom: $space-2;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: $font-size-sm;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.download-section {
|
||||
margin-bottom: $space-5;
|
||||
padding: $space-4;
|
||||
background-color: $color-paper-light;
|
||||
border-radius: $radius-md;
|
||||
|
||||
h3 {
|
||||
color: $color-accent;
|
||||
margin-bottom: $space-2;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: $space-3;
|
||||
}
|
||||
|
||||
.download-buttons {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: $space-2;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-download {
|
||||
padding: $space-2 $space-4;
|
||||
background-color: $color-accent;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: $radius-md;
|
||||
cursor: pointer;
|
||||
font-size: $font-size-sm;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
|
||||
&:hover {
|
||||
background-color: darken($color-accent, 10%);
|
||||
}
|
||||
}
|
||||
}</style>
|
||||
@@ -0,0 +1,77 @@
|
||||
import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router'
|
||||
import HomePage from '@/pages/HomePage.vue'
|
||||
import BylawsPage from '@/pages/BylawsPage.vue'
|
||||
import CommunityStandardsPage from '@/pages/CommunityStandardsPage.vue'
|
||||
import DoOcracyPage from '@/pages/DoOcracyPage.vue'
|
||||
import DecisionMakingPage from '@/pages/DecisionMakingPage.vue'
|
||||
import MembershipPage from '@/pages/MembershipPage.vue'
|
||||
import BoardPage from '@/pages/BoardPage.vue'
|
||||
import ResourcesPage from '@/pages/ResourcesPage.vue'
|
||||
import AdaptThisPage from '@/pages/AdaptThisPage.vue'
|
||||
|
||||
const routes: RouteRecordRaw[] = [
|
||||
{
|
||||
path: '/',
|
||||
name: 'home',
|
||||
component: HomePage
|
||||
},
|
||||
{
|
||||
path: '/bylaws',
|
||||
name: 'bylaws',
|
||||
component: BylawsPage
|
||||
},
|
||||
{
|
||||
path: '/community-standards',
|
||||
name: 'community-standards',
|
||||
component: CommunityStandardsPage
|
||||
},
|
||||
{
|
||||
path: '/do-ocracy',
|
||||
name: 'do-ocracy',
|
||||
component: DoOcracyPage
|
||||
},
|
||||
{
|
||||
path: '/decision-making',
|
||||
name: 'decision-making',
|
||||
component: DecisionMakingPage
|
||||
},
|
||||
{
|
||||
path: '/membership',
|
||||
name: 'membership',
|
||||
component: MembershipPage
|
||||
},
|
||||
{
|
||||
path: '/board',
|
||||
name: 'board',
|
||||
component: BoardPage
|
||||
},
|
||||
{
|
||||
path: '/resources',
|
||||
name: 'resources',
|
||||
component: ResourcesPage
|
||||
},
|
||||
{
|
||||
path: '/adapt-this',
|
||||
name: 'adapt-this',
|
||||
component: AdaptThisPage
|
||||
}
|
||||
]
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes,
|
||||
scrollBehavior(to, _from, savedPosition) {
|
||||
if (to.hash) {
|
||||
return {
|
||||
el: to.hash,
|
||||
behavior: 'smooth'
|
||||
}
|
||||
}
|
||||
if (savedPosition) {
|
||||
return savedPosition
|
||||
}
|
||||
return { top: 0 }
|
||||
}
|
||||
})
|
||||
|
||||
export default router
|
||||
@@ -0,0 +1,21 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
import type { Hackerspace } from '@/types'
|
||||
|
||||
export const useHackerspaceStore = defineStore('hackerspace', () => {
|
||||
const hackerspace = ref<Hackerspace>({
|
||||
name: 'HeatSync Labs',
|
||||
location: 'Mesa, Arizona',
|
||||
website: 'https://heatsynclabs.org',
|
||||
established: new Date('2009-01-01')
|
||||
})
|
||||
|
||||
const updateHackerspace = (updates: Partial<Hackerspace>) => {
|
||||
hackerspace.value = { ...hackerspace.value, ...updates }
|
||||
}
|
||||
|
||||
return {
|
||||
hackerspace,
|
||||
updateHackerspace
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,77 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
import type { NavItem } from '@/types'
|
||||
|
||||
export const useNavigationStore = defineStore('navigation', () => {
|
||||
const navItems = ref<NavItem[]>([
|
||||
{
|
||||
id: 'home',
|
||||
title: 'Introduction',
|
||||
path: '/'
|
||||
},
|
||||
{
|
||||
id: 'bylaws',
|
||||
title: 'Bylaws',
|
||||
path: '/bylaws'
|
||||
},
|
||||
{
|
||||
id: 'community-standards',
|
||||
title: 'Community Standards',
|
||||
path: '/community-standards'
|
||||
},
|
||||
{
|
||||
id: 'do-ocracy',
|
||||
title: 'Do-ocracy Guide',
|
||||
path: '/do-ocracy'
|
||||
},
|
||||
{
|
||||
id: 'decision-making',
|
||||
title: 'Decision Making',
|
||||
path: '/decision-making'
|
||||
},
|
||||
{
|
||||
id: 'membership',
|
||||
title: 'Membership',
|
||||
path: '/membership'
|
||||
},
|
||||
{
|
||||
id: 'board',
|
||||
title: 'The Board',
|
||||
path: '/board'
|
||||
},
|
||||
{
|
||||
id: 'resources',
|
||||
title: 'Resources',
|
||||
path: '/resources'
|
||||
},
|
||||
{
|
||||
id: 'adapt-this',
|
||||
title: 'Adapt This',
|
||||
path: '/adapt-this'
|
||||
}
|
||||
])
|
||||
|
||||
const isMenuOpen = ref(false)
|
||||
const activeSection = ref<string>('')
|
||||
|
||||
const toggleMenu = () => {
|
||||
isMenuOpen.value = !isMenuOpen.value
|
||||
}
|
||||
|
||||
const closeMenu = () => {
|
||||
isMenuOpen.value = false
|
||||
}
|
||||
|
||||
const setActiveSection = (sectionId: string) => {
|
||||
activeSection.value = sectionId
|
||||
}
|
||||
|
||||
return {
|
||||
navItems,
|
||||
isMenuOpen,
|
||||
activeSection,
|
||||
toggleMenu,
|
||||
closeMenu,
|
||||
setActiveSection
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,79 @@
|
||||
:root {
|
||||
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||
line-height: 1.5;
|
||||
font-weight: 400;
|
||||
|
||||
color-scheme: light dark;
|
||||
color: rgba(255, 255, 255, 0.87);
|
||||
background-color: #242424;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: 500;
|
||||
color: #646cff;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
a:hover {
|
||||
color: #535bf2;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
place-items: center;
|
||||
min-width: 320px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.2em;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 8px;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.6em 1.2em;
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
font-family: inherit;
|
||||
background-color: #1a1a1a;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.25s;
|
||||
}
|
||||
button:hover {
|
||||
border-color: #646cff;
|
||||
}
|
||||
button:focus,
|
||||
button:focus-visible {
|
||||
outline: 4px auto -webkit-focus-ring-color;
|
||||
}
|
||||
|
||||
.card {
|
||||
padding: 2em;
|
||||
}
|
||||
|
||||
#app {
|
||||
max-width: 1280px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
color: #213547;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
a:hover {
|
||||
color: #747bff;
|
||||
}
|
||||
button {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
// Print styles
|
||||
@media print {
|
||||
body {
|
||||
font-size: 12pt;
|
||||
line-height: 1.4;
|
||||
color: #000;
|
||||
background: white;
|
||||
}
|
||||
|
||||
// Hide navigation and unnecessary elements
|
||||
nav,
|
||||
.navigation,
|
||||
.sidebar,
|
||||
.header,
|
||||
.footer,
|
||||
.no-print,
|
||||
button,
|
||||
.btn {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
// Ensure content uses full width
|
||||
.content,
|
||||
.container {
|
||||
max-width: 100% !important;
|
||||
width: 100% !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
// Typography adjustments
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
page-break-after: avoid;
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 24pt;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 20pt;
|
||||
border-bottom: 1pt solid #ccc;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 16pt;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 14pt;
|
||||
}
|
||||
|
||||
p, ul, ol, blockquote {
|
||||
orphans: 3;
|
||||
widows: 3;
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
|
||||
// Links
|
||||
a {
|
||||
color: #000;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a[href^="http"]:after {
|
||||
content: " (" attr(href) ")";
|
||||
font-size: 10pt;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
a[href^="#"]:after,
|
||||
a[href^="javascript:"]:after {
|
||||
content: "";
|
||||
}
|
||||
|
||||
// Tables
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
th, td {
|
||||
border: 1pt solid #ccc;
|
||||
padding: 4pt;
|
||||
}
|
||||
|
||||
th {
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
// Code blocks
|
||||
pre, code {
|
||||
font-family: monospace;
|
||||
font-size: 10pt;
|
||||
background-color: #f5f5f5;
|
||||
border: 1pt solid #ddd;
|
||||
}
|
||||
|
||||
pre {
|
||||
padding: 8pt;
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
|
||||
// Images
|
||||
img {
|
||||
max-width: 100% !important;
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
|
||||
// Page breaks
|
||||
.page-break {
|
||||
page-break-before: always;
|
||||
}
|
||||
|
||||
.no-page-break {
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
// Modern CSS Reset
|
||||
*, *::before, *::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
html {
|
||||
font-size: $font-size-base;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
font-family: $font-family-base;
|
||||
line-height: $line-height-base;
|
||||
color: $color-text;
|
||||
background-color: $color-paper;
|
||||
}
|
||||
|
||||
img, picture, video, canvas, svg {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
input, button, textarea, select {
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
p, h1, h2, h3, h4, h5, h6 {
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $color-accent;
|
||||
text-decoration: none;
|
||||
transition: color $transition-fast;
|
||||
|
||||
&:hover, &:focus {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: 2px solid $color-accent;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
cursor: pointer;
|
||||
background: transparent;
|
||||
border: none;
|
||||
|
||||
&:focus-visible {
|
||||
outline: 2px solid $color-accent;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
list-style-position: inside;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 4px solid $color-border;
|
||||
padding-left: $space-4;
|
||||
margin: $space-4 0;
|
||||
color: $color-text-muted;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-top: 1px solid $color-border;
|
||||
margin: $space-6 0;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: $font-family-mono;
|
||||
font-size: 0.875em;
|
||||
background-color: $color-paper-light;
|
||||
padding: 2px 6px;
|
||||
border-radius: $radius-sm;
|
||||
}
|
||||
|
||||
pre {
|
||||
font-family: $font-family-mono;
|
||||
font-size: 0.875rem;
|
||||
background-color: $color-paper-light;
|
||||
padding: $space-4;
|
||||
border-radius: $radius-md;
|
||||
overflow-x: auto;
|
||||
|
||||
code {
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
// Typography System
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
line-height: $line-height-heading;
|
||||
font-weight: 600;
|
||||
margin-bottom: $space-3;
|
||||
color: $color-text;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: $font-size-3xl;
|
||||
margin-bottom: $space-5;
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: $font-size-2xl;
|
||||
margin-top: $space-7;
|
||||
margin-bottom: $space-4;
|
||||
padding-bottom: $space-2;
|
||||
border-bottom: 1px solid $color-border;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: $font-size-xl;
|
||||
margin-top: $space-6;
|
||||
margin-bottom: $space-3;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: $font-size-lg;
|
||||
margin-top: $space-5;
|
||||
margin-bottom: $space-3;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: $font-size-md;
|
||||
margin-top: $space-4;
|
||||
margin-bottom: $space-2;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: $font-size-sm;
|
||||
margin-top: $space-4;
|
||||
margin-bottom: $space-2;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: $space-4;
|
||||
max-width: $max-content-width;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.lead {
|
||||
font-size: $font-size-lg;
|
||||
line-height: 1.5;
|
||||
color: $color-text-muted;
|
||||
margin-bottom: $space-5;
|
||||
}
|
||||
|
||||
.text-small {
|
||||
font-size: $font-size-sm;
|
||||
}
|
||||
|
||||
.text-xs {
|
||||
font-size: $font-size-xs;
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
color: $color-text-muted;
|
||||
}
|
||||
|
||||
.text-mono {
|
||||
font-family: $font-family-mono;
|
||||
}
|
||||
|
||||
strong, b {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
em, i {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
mark {
|
||||
background-color: rgba($color-warning, 0.2);
|
||||
padding: 2px 4px;
|
||||
border-radius: $radius-sm;
|
||||
}
|
||||
|
||||
// Lists
|
||||
ul, ol {
|
||||
margin-bottom: $space-4;
|
||||
padding-left: $space-5;
|
||||
|
||||
li {
|
||||
margin-bottom: $space-2;
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
margin-top: $space-2;
|
||||
margin-bottom: $space-2;
|
||||
}
|
||||
}
|
||||
|
||||
// Definition lists
|
||||
dl {
|
||||
margin-bottom: $space-4;
|
||||
|
||||
dt {
|
||||
font-weight: 600;
|
||||
margin-bottom: $space-1;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-bottom: $space-3;
|
||||
margin-left: $space-5;
|
||||
color: $color-text-muted;
|
||||
}
|
||||
}
|
||||
|
||||
// Tables
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-bottom: $space-5;
|
||||
font-size: $font-size-sm;
|
||||
|
||||
th, td {
|
||||
padding: $space-3;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid $color-border;
|
||||
}
|
||||
|
||||
th {
|
||||
font-weight: 600;
|
||||
background-color: $color-paper-light;
|
||||
}
|
||||
|
||||
tbody tr:hover {
|
||||
background-color: rgba($color-paper-light, 0.5);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
// Utility Classes
|
||||
|
||||
// Display
|
||||
.d-none { display: none !important; }
|
||||
.d-block { display: block !important; }
|
||||
.d-inline { display: inline !important; }
|
||||
.d-inline-block { display: inline-block !important; }
|
||||
.d-flex { display: flex !important; }
|
||||
.d-grid { display: grid !important; }
|
||||
|
||||
// Flexbox
|
||||
.flex-row { flex-direction: row !important; }
|
||||
.flex-column { flex-direction: column !important; }
|
||||
.flex-wrap { flex-wrap: wrap !important; }
|
||||
.flex-nowrap { flex-wrap: nowrap !important; }
|
||||
.justify-start { justify-content: flex-start !important; }
|
||||
.justify-center { justify-content: center !important; }
|
||||
.justify-end { justify-content: flex-end !important; }
|
||||
.justify-between { justify-content: space-between !important; }
|
||||
.justify-around { justify-content: space-around !important; }
|
||||
.align-start { align-items: flex-start !important; }
|
||||
.align-center { align-items: center !important; }
|
||||
.align-end { align-items: flex-end !important; }
|
||||
.align-stretch { align-items: stretch !important; }
|
||||
.flex-grow { flex-grow: 1 !important; }
|
||||
.flex-shrink-0 { flex-shrink: 0 !important; }
|
||||
|
||||
// Grid
|
||||
.gap-1 { gap: $space-1 !important; }
|
||||
.gap-2 { gap: $space-2 !important; }
|
||||
.gap-3 { gap: $space-3 !important; }
|
||||
.gap-4 { gap: $space-4 !important; }
|
||||
.gap-5 { gap: $space-5 !important; }
|
||||
.gap-6 { gap: $space-6 !important; }
|
||||
|
||||
// Spacing
|
||||
@each $size, $value in (
|
||||
1: $space-1,
|
||||
2: $space-2,
|
||||
3: $space-3,
|
||||
4: $space-4,
|
||||
5: $space-5,
|
||||
6: $space-6,
|
||||
7: $space-7,
|
||||
8: $space-8,
|
||||
9: $space-9
|
||||
) {
|
||||
.m-#{$size} { margin: $value !important; }
|
||||
.mt-#{$size} { margin-top: $value !important; }
|
||||
.mr-#{$size} { margin-right: $value !important; }
|
||||
.mb-#{$size} { margin-bottom: $value !important; }
|
||||
.ml-#{$size} { margin-left: $value !important; }
|
||||
.mx-#{$size} {
|
||||
margin-left: $value !important;
|
||||
margin-right: $value !important;
|
||||
}
|
||||
.my-#{$size} {
|
||||
margin-top: $value !important;
|
||||
margin-bottom: $value !important;
|
||||
}
|
||||
|
||||
.p-#{$size} { padding: $value !important; }
|
||||
.pt-#{$size} { padding-top: $value !important; }
|
||||
.pr-#{$size} { padding-right: $value !important; }
|
||||
.pb-#{$size} { padding-bottom: $value !important; }
|
||||
.pl-#{$size} { padding-left: $value !important; }
|
||||
.px-#{$size} {
|
||||
padding-left: $value !important;
|
||||
padding-right: $value !important;
|
||||
}
|
||||
.py-#{$size} {
|
||||
padding-top: $value !important;
|
||||
padding-bottom: $value !important;
|
||||
}
|
||||
}
|
||||
|
||||
.m-0 { margin: 0 !important; }
|
||||
.p-0 { padding: 0 !important; }
|
||||
.m-auto { margin: auto !important; }
|
||||
.mx-auto {
|
||||
margin-left: auto !important;
|
||||
margin-right: auto !important;
|
||||
}
|
||||
|
||||
// Width & Height
|
||||
.w-full { width: 100% !important; }
|
||||
.w-auto { width: auto !important; }
|
||||
.h-full { height: 100% !important; }
|
||||
.h-auto { height: auto !important; }
|
||||
.min-h-screen { min-height: 100vh !important; }
|
||||
|
||||
// Position
|
||||
.relative { position: relative !important; }
|
||||
.absolute { position: absolute !important; }
|
||||
.fixed { position: fixed !important; }
|
||||
.sticky { position: sticky !important; }
|
||||
.top-0 { top: 0 !important; }
|
||||
.right-0 { right: 0 !important; }
|
||||
.bottom-0 { bottom: 0 !important; }
|
||||
.left-0 { left: 0 !important; }
|
||||
|
||||
// Text
|
||||
.text-left { text-align: left !important; }
|
||||
.text-center { text-align: center !important; }
|
||||
.text-right { text-align: right !important; }
|
||||
.text-justify { text-align: justify !important; }
|
||||
|
||||
// Visibility
|
||||
.visible { visibility: visible !important; }
|
||||
.invisible { visibility: hidden !important; }
|
||||
|
||||
// Overflow
|
||||
.overflow-auto { overflow: auto !important; }
|
||||
.overflow-hidden { overflow: hidden !important; }
|
||||
.overflow-scroll { overflow: scroll !important; }
|
||||
.overflow-x-auto { overflow-x: auto !important; }
|
||||
.overflow-y-auto { overflow-y: auto !important; }
|
||||
|
||||
// Borders
|
||||
.border { border: 1px solid $color-border !important; }
|
||||
.border-0 { border: 0 !important; }
|
||||
.border-t { border-top: 1px solid $color-border !important; }
|
||||
.border-r { border-right: 1px solid $color-border !important; }
|
||||
.border-b { border-bottom: 1px solid $color-border !important; }
|
||||
.border-l { border-left: 1px solid $color-border !important; }
|
||||
|
||||
// Border radius
|
||||
.rounded { border-radius: $radius-md !important; }
|
||||
.rounded-sm { border-radius: $radius-sm !important; }
|
||||
.rounded-lg { border-radius: $radius-lg !important; }
|
||||
.rounded-0 { border-radius: 0 !important; }
|
||||
|
||||
// Shadows
|
||||
.shadow-sm { box-shadow: $shadow-sm !important; }
|
||||
.shadow-md { box-shadow: $shadow-md !important; }
|
||||
.shadow-lg { box-shadow: $shadow-lg !important; }
|
||||
.shadow-none { box-shadow: none !important; }
|
||||
|
||||
// Responsive utilities
|
||||
@media (min-width: $breakpoint-sm) {
|
||||
.sm\:d-none { display: none !important; }
|
||||
.sm\:d-block { display: block !important; }
|
||||
.sm\:d-flex { display: flex !important; }
|
||||
}
|
||||
|
||||
@media (min-width: $breakpoint-md) {
|
||||
.md\:d-none { display: none !important; }
|
||||
.md\:d-block { display: block !important; }
|
||||
.md\:d-flex { display: flex !important; }
|
||||
}
|
||||
|
||||
@media (min-width: $breakpoint-lg) {
|
||||
.lg\:d-none { display: none !important; }
|
||||
.lg\:d-block { display: block !important; }
|
||||
.lg\:d-flex { display: flex !important; }
|
||||
}
|
||||
|
||||
// Container
|
||||
.container {
|
||||
width: 100%;
|
||||
max-width: 1280px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding-left: $space-4;
|
||||
padding-right: $space-4;
|
||||
|
||||
@media (min-width: $breakpoint-md) {
|
||||
padding-left: $space-5;
|
||||
padding-right: $space-5;
|
||||
}
|
||||
|
||||
@media (min-width: $breakpoint-lg) {
|
||||
padding-left: $space-6;
|
||||
padding-right: $space-6;
|
||||
}
|
||||
}
|
||||
|
||||
// Screen reader only
|
||||
.sr-only {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
white-space: nowrap;
|
||||
border: 0;
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
// Color Palette
|
||||
$color-paper: #FAFAF8;
|
||||
$color-paper-light: #F5F5F0;
|
||||
$color-text: #1A1A1A;
|
||||
$color-text-muted: #666666;
|
||||
$color-accent: #0066CC;
|
||||
$color-warning: #D97706;
|
||||
$color-error: #DC2626;
|
||||
$color-success: #059669;
|
||||
$color-border: #E5E5E5;
|
||||
|
||||
// Typography
|
||||
$font-family-base: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
|
||||
$font-family-mono: 'SF Mono', 'Monaco', 'Inconsolata', 'Fira Code', 'Fira Mono', 'Droid Sans Mono', monospace;
|
||||
|
||||
$font-size-base: 16px;
|
||||
$line-height-base: 1.6;
|
||||
$line-height-heading: 1.2;
|
||||
|
||||
// Typography Scale (Golden Ratio)
|
||||
$font-size-xs: 0.618rem;
|
||||
$font-size-sm: 0.875rem;
|
||||
$font-size-md: 1rem;
|
||||
$font-size-lg: 1.25rem;
|
||||
$font-size-xl: 1.618rem;
|
||||
$font-size-2xl: 2.058rem;
|
||||
$font-size-3xl: 2.618rem;
|
||||
$font-size-4xl: 3.272rem;
|
||||
|
||||
// Spacing Scale
|
||||
$space-1: 4px;
|
||||
$space-2: 8px;
|
||||
$space-3: 12px;
|
||||
$space-4: 16px;
|
||||
$space-5: 24px;
|
||||
$space-6: 32px;
|
||||
$space-7: 48px;
|
||||
$space-8: 64px;
|
||||
$space-9: 96px;
|
||||
|
||||
// Layout
|
||||
$max-content-width: 75ch;
|
||||
$sidebar-width: 280px;
|
||||
$header-height: 64px;
|
||||
|
||||
// Breakpoints
|
||||
$breakpoint-sm: 640px;
|
||||
$breakpoint-md: 768px;
|
||||
$breakpoint-lg: 1024px;
|
||||
$breakpoint-xl: 1280px;
|
||||
|
||||
// Transitions
|
||||
$transition-fast: 150ms ease-in-out;
|
||||
$transition-base: 250ms ease-in-out;
|
||||
$transition-slow: 350ms ease-in-out;
|
||||
|
||||
// Shadows
|
||||
$shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
||||
$shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
||||
$shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
|
||||
|
||||
// Border Radius
|
||||
$radius-sm: 2px;
|
||||
$radius-md: 4px;
|
||||
$radius-lg: 8px;
|
||||
@@ -0,0 +1,5 @@
|
||||
@import 'variables';
|
||||
@import 'reset';
|
||||
@import 'typography';
|
||||
@import 'utilities';
|
||||
@import 'print';
|
||||
@@ -0,0 +1,30 @@
|
||||
export interface NavItem {
|
||||
id: string
|
||||
title: string
|
||||
path: string
|
||||
children?: NavItem[]
|
||||
}
|
||||
|
||||
export interface DocumentSection {
|
||||
id: string
|
||||
title: string
|
||||
content: string
|
||||
order: number
|
||||
subsections?: DocumentSection[]
|
||||
}
|
||||
|
||||
export interface GovernanceDocument {
|
||||
id: string
|
||||
title: string
|
||||
description: string
|
||||
lastUpdated: Date
|
||||
sections: DocumentSection[]
|
||||
}
|
||||
|
||||
export interface Hackerspace {
|
||||
name: string
|
||||
location: string
|
||||
website?: string
|
||||
established?: Date
|
||||
logo?: string
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"extends": "@vue/tsconfig/tsconfig.dom.json",
|
||||
"compilerOptions": {
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||
"types": ["vite/client", "node"],
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["src/*"]
|
||||
},
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedSideEffectImports": true,
|
||||
"noImplicitAny": true,
|
||||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": true,
|
||||
"strictBindCallApply": true,
|
||||
"strictPropertyInitialization": true,
|
||||
"noImplicitThis": true,
|
||||
"alwaysStrict": true
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"files": [],
|
||||
"references": [
|
||||
{ "path": "./tsconfig.app.json" },
|
||||
{ "path": "./tsconfig.node.json" }
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
||||
"target": "ES2023",
|
||||
"lib": ["ES2023"],
|
||||
"module": "ESNext",
|
||||
"types": ["node"],
|
||||
"skipLibCheck": true,
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"moduleDetection": "force",
|
||||
"noEmit": true,
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"erasableSyntaxOnly": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedSideEffectImports": true
|
||||
},
|
||||
"include": ["vite.config.ts"]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import { fileURLToPath, URL } from 'node:url'
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [vue()],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': fileURLToPath(new URL('./src', import.meta.url))
|
||||
}
|
||||
},
|
||||
css: {
|
||||
preprocessorOptions: {
|
||||
scss: {
|
||||
additionalData: `@import "@/styles/_variables.scss";`
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user