Updated the core site style and removed AI fuzz.

This commit is contained in:
Joseph Robles Jr.
2026-10-13 12:56:07 -06:00
parent b1ff9802b6
commit c05a158569
9 changed files with 951 additions and 2209 deletions
+46 -105
View File
@@ -4,146 +4,87 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Amateur Radio License Exams – BYU-Idaho Amateur Radio Society</title> <title>Amateur Radio License Exams – BYU-Idaho Amateur Radio Society</title>
<script src="https://cdn.tailwindcss.com"></script> <link rel="stylesheet" href="style.css" />
<script> <script src="script.js" defer></script>
tailwind.config = {
darkMode: 'class'
}
</script>
<script>
if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.classList.add('dark')
} else {
document.documentElement.classList.remove('dark')
}
</script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js" defer></script>
<style>
.accent-bg { background-color: #006eb6; }
.banner-bg { background-color: #a2daff; }
</style>
</head> </head>
<body class="bg-white dark:bg-gray-900 text-gray-800 dark:text-gray-100 min-h-screen flex flex-col" x-data="appData()" x-init="init()"> <body>
<!-- Banner --> <!-- Announcement Banner -->
<template x-if="banner.title && banner.content"> <div id="banner" class="banner-bg hidden">
<div class="w-full banner-bg text-black text-center py-2 px-4"> <strong id="banner-title"></strong>: <span id="banner-content"></span>
<strong x-text="banner.title"></strong>: <span x-text="banner.content"></span>
</div> </div>
</template>
<!-- Navbar --> <!-- Navigation Bar -->
<nav class="accent-bg text-white px-4 py-3 shadow-md" x-data="{ open: false }"> <nav class="navbar accent-bg">
<div class="flex flex-wrap items-center justify-between"> <div class="nav-container">
<a href="/" class="text-xl font-semibold mr-4">BYU-I Amateur Radio Society</a> <a href="/" class="nav-brand">BYU-I Amateur Radio Society</a>
<button @click="open = !open" class="sm:hidden text-white ml-auto focus:outline-none">
<svg x-show="!open" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <!-- Mobile Hamburger Toggle -->
<button id="menu-toggle" class="icon-button mobile-only" aria-label="Toggle Navigation Menu">
<svg id="icon-hamburger" class="icon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
</svg> </svg>
<svg x-show="open" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <svg id="icon-close" class="icon hidden" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg> </svg>
</button> </button>
<div class="hidden sm:flex flex-grow justify-center space-x-4">
<template x-for="page in pages" :key="page.path"> <!-- Desktop Links -->
<a :href="page.path" :class="{ 'font-bold underline': currentPath === page.path }" class="hover:opacity-80 transition"> <div id="desktop-links" class="nav-links desktop-only"></div>
<span x-text="page.name"></span>
</a> <!-- Desktop Dark Mode Toggle -->
</template> <button class="theme-toggle icon-button desktop-only" aria-label="Toggle Dark Mode">
</div> <svg class="icon icon-sun hidden" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<div class="hidden sm:flex ml-auto"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m8.66-8.66h-1M4.34 12H3m15.36 6.36l-.71-.71M6.34 6.34l-.71-.71m12.02 0l-.71.71M6.34 17.66l-.71.71M6.34 17.66l-.71.71M12 5a7 7 0 100 14 7 7 0 000-14z" />
<button @click="toggleDarkMode" class="ml-4 text-white focus:outline-none" title="Toggle dark mode">
<svg x-show="!darkMode" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m8.66-8.66h-1M4.34 12H3m15.36 6.36l-.71-.71M6.34 6.34l-.71-.71m12.02 0l-.71.71M6.34 17.66l-.71.71M12 5a7 7 0 100 14 7 7 0 000-14z" />
</svg> </svg>
<svg x-show="darkMode" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <svg class="icon icon-moon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12.79A9 9 0 1111.21 3a7 7 0 009.79 9.79z" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12.79A9 9 0 1111.21 3a7 7 0 009.79 9.79z" />
</svg> </svg>
</button> </button>
</div> </div>
</div>
<div x-show="open" class="sm:hidden mt-2 space-y-2"> <!-- Mobile Dropdown Menu -->
<template x-for="page in pages" :key="page.path"> <div id="mobile-menu" class="mobile-menu mobile-only hidden">
<a :href="page.path" :class="{ 'font-bold underline': currentPath === page.path }" class="block px-2 py-1 hover:bg-white/10"> <div id="mobile-links"></div>
<span x-text="page.name"></span> <button class="theme-toggle mobile-theme-btn" aria-label="Toggle Dark Mode">
</a> <span class="theme-text">🌙 Dark Mode</span>
</template>
<button @click="toggleDarkMode" class="w-full text-left px-2 py-1 text-white hover:bg-white/10" title="Toggle dark mode">
<span x-text="darkMode ? '☀️ Light Mode' : '🌙 Dark Mode'"></span>
</button> </button>
</div> </div>
</nav> </nav>
<main class="flex-grow p-6"> <!-- Main Content -->
<h1 class="text-3xl font-bold mb-4">License Exams</h1> <main class="main-content">
<h1>License Exams</h1>
<p class="mb-4"> <p>
Interested in getting your amateur radio license? The BYU-I Amateur Radio Society hosts exam sessions right here in Rexburg! Interested in getting your amateur radio license? The BYU-I Amateur Radio Society hosts exam sessions right here in Rexburg!
</p> </p>
<h2 class="text-xl font-semibold mt-6 mb-2">Upcoming Exam Sessions</h2> <h2>Upcoming Exam Sessions</h2>
<ul class="list-disc pl-6 space-y-2"> <ul id="exams-list" class="styled-list">
<template x-if="exams.length"> <!-- Dynamically populated from /assets/exams.json via script.js -->
<template x-for="exam in exams" :key="exam.date">
<li>
<span x-text="exam.date"></span>,
<span x-text="exam.time"></span> –
<span x-text="exam.location"></span> –
<a :href="exam.register" class="text-blue-400 underline" target="_blank">Register Here</a>
</li>
</template>
</template>
<template x-if="!exams.length">
<li>
We don't have any sessions scheduled right now, but if you're ready to test let us know and we'll set one up!
</li>
</template>
</ul> </ul>
<h2 class="text-xl font-semibold mt-6 mb-2">Before You Test</h2> <h2>Before You Test</h2>
<ul class="list-disc pl-6 space-y-2"> <ul class="styled-list">
<li>Study using <a href="https://hamstudy.org/" class="text-blue-400 underline">HamStudy.org</a> or other resources</li> <li>Study using <a href="https://hamstudy.org/" class="link" target="_blank" rel="noopener">HamStudy.org</a> or other resources</li>
<li>Take practice exams and be sure you're consistently scoring at least 80% (not required, but helpful)</li> <li>Take practice exams and be sure you're consistently scoring at least 80% (not required, but helpful)</li>
<li>Get your <a href="https://apps.fcc.gov/cores/userLogin.do" class="text-blue-400 underline">FCC FRN</a></li> <li>Get your <a href="https://apps.fcc.gov/cores/userLogin.do" class="link" target="_blank" rel="noopener">FCC FRN</a></li>
<li>Register for your session, or contact us to set one up</li> <li>Register for your session, or contact us to set one up</li>
</ul> </ul>
<h2 class="text-xl font-semibold mt-6 mb-2">When You Test</h2> <h2>When You Test</h2>
<ul class="list-disc pl-6 space-y-2"> <ul class="styled-list">
<li>Bring a government-issued photo ID and a current student ID (students test free!) or $14 for the exam fee</li> <li>Bring a government-issued photo ID and a current student ID (students test free!) or $14 for the exam fee</li>
<li>If you have a calculator and are okay clearing its memory, feel free to bring it!</li> <li>If you have a calculator and are okay clearing its memory, feel free to bring it!</li>
<li>Our sessions typically run for at least an hour and often start a little early, so don't stress if you're running early or late. Just relax</li> <li>Our sessions typically run for at least an hour and often start a little early, so don't stress if you're running early or late. Just relax</li>
</ul> </ul>
</main> </main>
<footer class="accent-bg text-white text-center py-4"> <!-- Footer -->
&copy; 2025-<span x-text="new Date().getFullYear()"></span> BYU-Idaho Amateur Radio Society. All rights reserved. <footer class="footer accent-bg">
&copy; 2025–<span id="current-year"></span> BYU-Idaho Amateur Radio Society. All rights reserved.
</footer> </footer>
<script>
function appData() {
return {
darkMode: document.documentElement.classList.contains('dark'),
currentPath: window.location.pathname,
banner: { title: '', content: '' },
pages: [],
async init() {
const navResp = await fetch('/assets/pages.json');
this.pages = await navResp.json();
const bannerResp = await fetch('/assets/banner.json?t=${Date.now()}');
this.banner = await bannerResp.json();
const examResp = await fetch('/assets/exams.json?t=${Date.now()}');
this.exams = await examResp.json();
},
toggleDarkMode() {
this.darkMode = !this.darkMode;
document.documentElement.classList.toggle('dark');
localStorage.theme = this.darkMode ? 'dark' : 'light';
}
}
}
</script>
</body> </body>
</html> </html>
+39 -81
View File
@@ -3,114 +3,72 @@
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>History – BYU-I Amateur Radio Society</title> <title>History – BYU-Idaho Amateur Radio Society</title>
<script src="https://cdn.tailwindcss.com"></script> <link rel="stylesheet" href="style.css" />
<script> <script src="script.js" defer></script>
tailwind.config = {
darkMode: 'class'
}
</script>
<script>
if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.classList.add('dark')
} else {
document.documentElement.classList.remove('dark')
}
</script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js" defer></script>
<style>
.accent-bg { background-color: #006eb6; }
.banner-bg { background-color: #a2daff; }
</style>
</head> </head>
<body class="bg-white dark:bg-gray-900 text-gray-800 dark:text-gray-100 min-h-screen flex flex-col" x-data="appData()" x-init="init()"> <body>
<!-- Banner --> <!-- Announcement Banner -->
<template x-if="banner.title && banner.content"> <div id="banner" class="banner-bg hidden">
<div class="w-full banner-bg text-black text-center py-2 px-4"> <strong id="banner-title"></strong>: <span id="banner-content"></span>
<strong x-text="banner.title"></strong>: <span x-text="banner.content"></span>
</div> </div>
</template>
<!-- Navbar --> <!-- Navigation Bar -->
<nav class="accent-bg text-white px-4 py-3 shadow-md" x-data="{ open: false }"> <nav class="navbar accent-bg">
<div class="flex flex-wrap items-center justify-between"> <div class="nav-container">
<a href="/" class="text-xl font-semibold mr-4">BYU-I Amateur Radio Society</a> <a href="/" class="nav-brand">BYU-I Amateur Radio Society</a>
<button @click="open = !open" class="sm:hidden text-white ml-auto focus:outline-none">
<svg x-show="!open" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <!-- Mobile Hamburger Toggle -->
<button id="menu-toggle" class="icon-button mobile-only" aria-label="Toggle Navigation Menu">
<svg id="icon-hamburger" class="icon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
</svg> </svg>
<svg x-show="open" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <svg id="icon-close" class="icon hidden" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg> </svg>
</button> </button>
<div class="hidden sm:flex flex-grow justify-center space-x-4">
<template x-for="page in pages" :key="page.path"> <!-- Desktop Links -->
<a :href="page.path" :class="{ 'font-bold underline': currentPath === page.path }" class="hover:opacity-80 transition"> <div id="desktop-links" class="nav-links desktop-only"></div>
<span x-text="page.name"></span>
</a> <!-- Desktop Dark Mode Toggle -->
</template> <button class="theme-toggle icon-button desktop-only" aria-label="Toggle Dark Mode">
</div> <svg class="icon icon-sun hidden" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<div class="hidden sm:flex ml-auto">
<button @click="toggleDarkMode" class="ml-4 text-white focus:outline-none" title="Toggle dark mode">
<svg x-show="!darkMode" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m8.66-8.66h-1M4.34 12H3m15.36 6.36l-.71-.71M6.34 6.34l-.71-.71m12.02 0l-.71.71M6.34 17.66l-.71.71M12 5a7 7 0 100 14 7 7 0 000-14z" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m8.66-8.66h-1M4.34 12H3m15.36 6.36l-.71-.71M6.34 6.34l-.71-.71m12.02 0l-.71.71M6.34 17.66l-.71.71M12 5a7 7 0 100 14 7 7 0 000-14z" />
</svg> </svg>
<svg x-show="darkMode" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <svg class="icon icon-moon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12.79A9 9 0 1111.21 3a7 7 0 009.79 9.79z" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12.79A9 9 0 1111.21 3a7 7 0 009.79 9.79z" />
</svg> </svg>
</button> </button>
</div> </div>
</div>
<div x-show="open" class="sm:hidden mt-2 space-y-2"> <!-- Mobile Dropdown Menu -->
<template x-for="page in pages" :key="page.path"> <div id="mobile-menu" class="mobile-menu mobile-only hidden">
<a :href="page.path" :class="{ 'font-bold underline': currentPath === page.path }" class="block px-2 py-1 hover:bg-white/10"> <div id="mobile-links"></div>
<span x-text="page.name"></span> <button class="theme-toggle mobile-theme-btn" aria-label="Toggle Dark Mode">
</a> <span class="theme-text">🌙 Dark Mode</span>
</template>
<button @click="toggleDarkMode" class="w-full text-left px-2 py-1 text-white hover:bg-white/10" title="Toggle dark mode">
<span x-text="darkMode ? '☀️ Light Mode' : '🌙 Dark Mode'"></span>
</button> </button>
</div> </div>
</nav> </nav>
<main class="flex-grow p-6"> <!-- Main Content -->
<h1 class="text-3xl font-bold mb-4">Our History</h1> <main class="main-content">
<h1>Our History</h1>
<p class="mb-4"> <p>
The BYU-Idaho Amateur Radio Society has a long-standing tradition of service, education, and community involvement. Our roots go back to Rick's College in the mid-1900s, and we're proud to still be here thriving today. The BYU-Idaho Amateur Radio Society has a long-standing tradition of service, education, and community involvement. Our roots go back to Ricks College in the mid-1900s, and we're proud to still be thriving today.
</p> </p>
<p class="mb-4"> <p>
This page is a work in progress — check back soon for a more detailed history of our club's leadership, milestones, and notable moments! This page is a work in progress — check back soon for a more detailed history of our club's leadership, milestones, and notable moments!
</p> </p>
</main> </main>
<footer class="accent-bg text-white text-center py-4"> <!-- Footer -->
&copy; <span x-text="new Date().getFullYear()"></span> BYU-Idaho Amateur Radio Society. All rights reserved. <footer class="footer accent-bg">
&copy; 2025–<span id="current-year"></span> BYU-Idaho Amateur Radio Society. All rights reserved.
</footer> </footer>
<script>
function appData() {
return {
darkMode: document.documentElement.classList.contains('dark'),
currentPath: window.location.pathname,
banner: { title: '', content: '' },
pages: [],
async init() {
const navResp = await fetch('/assets/pages.json');
this.pages = await navResp.json();
const bannerResp = await fetch('/assets/banner.json?t=${Date.now()}');
this.banner = await bannerResp.json();
},
toggleDarkMode() {
this.darkMode = !this.darkMode;
document.documentElement.classList.toggle('dark');
localStorage.theme = this.darkMode ? 'dark' : 'light';
}
}
}
</script>
</body> </body>
</html> </html>
+61 -102
View File
@@ -4,136 +4,95 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>BYU-Idaho Amateur Radio Society</title> <title>BYU-Idaho Amateur Radio Society</title>
<script src="https://cdn.tailwindcss.com"></script> <link rel="stylesheet" href="style.css" />
<script> <script src="script.js" defer></script>
tailwind.config = {
darkMode: 'class'
}
</script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js" defer></script>
<script>
// Dark mode persistence
if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.classList.add('dark')
} else {
document.documentElement.classList.remove('dark')
}
</script>
<style>
.accent-bg { background-color: #006eb6; }
.banner-bg { background-color: #a2daff; }
</style>
</head> </head>
<body class="bg-white dark:bg-gray-900 text-gray-800 dark:text-gray-100 min-h-screen flex flex-col" x-data="appData()" x-init="init()"> <body>
<!-- Banner --> <!-- Announcement Banner -->
<template x-if="banner.title && banner.content"> <div id="banner" class="banner-bg hidden">
<div class="w-full banner-bg text-black text-center py-2 px-4"> <strong id="banner-title"></strong>: <span id="banner-content"></span>
<strong x-text="banner.title"></strong>: <span x-text="banner.content"></span>
</div> </div>
</template>
<!-- Navbar --> <!-- Navigation Bar -->
<nav class="accent-bg text-white px-4 py-3 shadow-md" x-data="{ open: false }"> <nav class="navbar accent-bg">
<div class="flex flex-wrap items-center justify-between"> <div class="nav-container">
<a href="/" class="text-xl font-semibold mr-4">BYU-I Amateur Radio Society</a> <a href="/" class="nav-brand">BYU-I Amateur Radio Society</a>
<button @click="open = !open" class="sm:hidden text-white ml-auto focus:outline-none">
<svg x-show="!open" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <!-- Mobile Hamburger Toggle -->
<button id="menu-toggle" class="icon-button mobile-only" aria-label="Toggle Navigation Menu">
<svg id="icon-hamburger" class="icon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
</svg> </svg>
<svg x-show="open" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <svg id="icon-close" class="icon hidden" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg> </svg>
</button> </button>
<div class="hidden sm:flex flex-grow justify-center space-x-4">
<template x-for="page in pages" :key="page.path"> <!-- Desktop Links -->
<a :href="page.path" :class="{ 'font-bold underline': currentPath === page.path }" class="hover:opacity-80 transition"> <div id="desktop-links" class="nav-links desktop-only"></div>
<span x-text="page.name"></span>
</a> <!-- Desktop Dark Mode Toggle -->
</template> <button class="theme-toggle icon-button desktop-only" aria-label="Toggle Dark Mode">
</div> <svg class="icon icon-sun hidden" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<div class="hidden sm:flex ml-auto">
<button @click="toggleDarkMode" class="ml-4 text-white focus:outline-none" title="Toggle dark mode">
<svg x-show="!darkMode" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m8.66-8.66h-1M4.34 12H3m15.36 6.36l-.71-.71M6.34 6.34l-.71-.71m12.02 0l-.71.71M6.34 17.66l-.71.71M12 5a7 7 0 100 14 7 7 0 000-14z" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m8.66-8.66h-1M4.34 12H3m15.36 6.36l-.71-.71M6.34 6.34l-.71-.71m12.02 0l-.71.71M6.34 17.66l-.71.71M12 5a7 7 0 100 14 7 7 0 000-14z" />
</svg> </svg>
<svg x-show="darkMode" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <svg class="icon icon-moon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12.79A9 9 0 1111.21 3a7 7 0 009.79 9.79z" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12.79A9 9 0 1111.21 3a7 7 0 009.79 9.79z" />
</svg> </svg>
</button> </button>
</div> </div>
</div>
<div x-show="open" class="sm:hidden mt-2 space-y-2"> <!-- Mobile Dropdown Menu -->
<template x-for="page in pages" :key="page.path"> <div id="mobile-menu" class="mobile-menu mobile-only hidden">
<a :href="page.path" :class="{ 'font-bold underline': currentPath === page.path }" class="block px-2 py-1 hover:bg-white/10"> <div id="mobile-links"></div>
<span x-text="page.name"></span> <button class="theme-toggle mobile-theme-btn" aria-label="Toggle Dark Mode">
</a> <span class="theme-text">🌙 Dark Mode</span>
</template>
<button @click="toggleDarkMode" class="w-full text-left px-2 py-1 text-white hover:bg-white/10" title="Toggle dark mode">
<span x-text="darkMode ? '☀️ Light Mode' : '🌙 Dark Mode'"></span>
</button> </button>
</div> </div>
</nav> </nav>
<!-- Main Content --> <!-- Main Content -->
<main class="flex-grow p-6"> <main class="main-content home-content">
<h1 class="text-3xl font-bold mb-4">Welcome to the BYU-Idaho Amateur Radio Society!</h1> <section class="hero" aria-labelledby="welcome-heading">
<p>Established in the mid-1900s, the BYU-Idaho Amateur Radio Society is one of the University's longest-operating student groups.</p> <div class="hero-copy">
<p class="eyebrow">K7BYI · Rexburg, Idaho</p>
<h2 class="text-xl font-semibold mt-6 mb-2">Get Involved</h2> <h1 id="welcome-heading">Explore radio. Build community.</h1>
<p>We meet most Wednesdays during the semester in STC 231, and host weekly <a href="/net/" class="text-blue-400 underline">nets</a> on the 146.510 MHz K7BYI Repeater. <p class="hero-lede">The BYU-Idaho Amateur Radio Society is one of the University's longest-running student groups—open to curious beginners and experienced operators alike.</p>
<br> <div class="hero-actions">
For more information on current events and what we're up to, join our <a href="https://discord.gg/D9fZ6uWugH" class="text-blue-400 underline">Discord</a>! <a class="button button-primary" href="https://discord.gg/D9fZ6uWugH" target="_blank" rel="noopener">Join our Discord <span aria-hidden="true">→</span></a>
<a class="button button-secondary" href="/exams.html">Get licensed</a>
<br><br>We have activies for all skill levels, and no license is required to participate with us (though we'd be happy to help you get yours if you like)</p> </div>
<!-- Homepage Banner Image --> </div>
<div class="my-6"> <figure class="hero-image">
<img <img
src="/assets/i/summerfieldday_20250628_130113.jpg" src="/assets/i/summerfieldday_20250628_130113.jpg"
alt="BYUIARS members at Summer Field Day 2025" alt="BYUIARS members at Summer Field Day 2025"
class="w-full max-w-5xl mx-auto rounded shadow-md" class="featured-image"
/> />
</div> <figcaption>Summer Field Day 2025</figcaption>
</figure>
</section>
<h2 class="text-xl font-semibold mt-6 mb-2">Why Should I Join the Amateur Radio Society?</h2> <section class="intro-section" aria-labelledby="involved-heading">
<ul class="list-disc pl-6 space-y-2"> <div>
<li>Hands-on opportunities to learn about, use, and build radios and antennas</li> <p class="eyebrow">Start here</p>
<li>Learn and apply physics</li> <h2 id="involved-heading">Find your signal</h2>
<li>Be better prepared for emergencies and wilderness activities</li> </div>
<li>Connect and network with some pretty cool folks</li> <p>We meet most Wednesdays during the semester in STC 243 and host weekly <a href="/net/" class="link">nets</a> on the 146.510 MHz K7BYI repeater. No license or prior experience is required—we'll help you get started.</p>
<li>Obtain your federal Amateur Radio License at no cost to you (A $50 value!)</li> </section>
<li>Plentiful scholarship opportunities</li>
<li>Inter-Society collaboration opportunities</li> <section class="card-grid" aria-label="Reasons to join">
<li>Great project opportunities. Have a cool idea? We probably have people with the knowledge to help you make it happen!</li> <article class="info-card"><span class="card-number" aria-hidden="true">01</span><h2>Learn by doing</h2><p>Use and build radios, antennas, and practical projects with people who can help bring an idea to life.</p></article>
</ul> <article class="info-card"><span class="card-number" aria-hidden="true">02</span><h2>Be ready</h2><p>Develop communication skills useful for emergencies, wilderness activities, and everyday problem-solving.</p></article>
</main> <article class="info-card"><span class="card-number" aria-hidden="true">03</span><h2>Make connections</h2><p>Meet fellow makers, find project collaborators, and explore scholarship and inter-society opportunities.</p></article>
</section>
</main>ß
<!-- Footer --> <!-- Footer -->
<footer class="accent-bg text-white text-center py-4"> <footer class="footer accent-bg">
&copy; 2025-<span x-text="new Date().getFullYear()"></span> BYU-Idaho Amateur Radio Society. All rights reserved. &copy; 2025–<span id="current-year"></span> BYU-Idaho Amateur Radio Society. All rights reserved.
</footer> </footer>
<script>
function appData() {
return {
darkMode: document.documentElement.classList.contains('dark'),
currentPath: window.location.pathname,
banner: { title: '', content: '' },
pages: [],
async init() {
const navResp = await fetch('/assets/pages.json');
this.pages = await navResp.json();
const bannerResp = await fetch('/assets/banner.json?t=${Date.now()}');
this.banner = await bannerResp.json();
},
toggleDarkMode() {
this.darkMode = !this.darkMode;
document.documentElement.classList.toggle('dark');
localStorage.theme = this.darkMode ? 'dark' : 'light';
}
}
}
</script>
</body> </body>
</html> </html>
+222 -1551
View File
File diff suppressed because it is too large Load Diff
+52 -91
View File
@@ -3,133 +3,94 @@
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Rexburg Mesh - BYU-I Amateur Radio Society</title> <title>Rexburg Mesh – BYU-Idaho Amateur Radio Society</title>
<script src="https://cdn.tailwindcss.com"></script> <link rel="stylesheet" href="/style.css" />
<script> <script src="/script.js" defer></script>
tailwind.config = {
darkMode: 'class'
}
</script>
<script>
if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.classList.add('dark')
} else {
document.documentElement.classList.remove('dark')
}
</script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js" defer></script>
<style>
.accent-bg { background-color: #006eb6; }
.banner-bg { background-color: #a2daff; }
</style>
</head> </head>
<body class="bg-white dark:bg-gray-900 text-gray-800 dark:text-gray-100 min-h-screen flex flex-col" x-data="appData()" x-init="init()"> <body>
<!-- Banner --> <!-- Announcement Banner -->
<template x-if="banner.title && banner.content"> <div id="banner" class="banner-bg hidden">
<div class="w-full banner-bg text-black text-center py-2 px-4"> <strong id="banner-title"></strong>: <span id="banner-content"></span>
<strong x-text="banner.title"></strong>: <span x-text="banner.content"></span>
</div> </div>
</template>
<!-- Navbar --> <!-- Navigation Bar -->
<nav class="accent-bg text-white px-4 py-3 shadow-md" x-data="{ open: false }"> <nav class="navbar accent-bg">
<div class="flex flex-wrap items-center justify-between"> <div class="nav-container">
<a href="/" class="text-xl font-semibold mr-4">BYU-I Amateur Radio Society</a> <a href="/" class="nav-brand">BYU-I Amateur Radio Society</a>
<button @click="open = !open" class="sm:hidden text-white ml-auto focus:outline-none">
<svg x-show="!open" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <!-- Mobile Hamburger Toggle -->
<button id="menu-toggle" class="icon-button mobile-only" aria-label="Toggle Navigation Menu">
<svg id="icon-hamburger" class="icon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
</svg> </svg>
<svg x-show="open" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <svg id="icon-close" class="icon hidden" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg> </svg>
</button> </button>
<div class="hidden sm:flex flex-grow justify-center space-x-4">
<template x-for="page in pages" :key="page.path"> <!-- Desktop Links -->
<a :href="page.path" :class="{ 'font-bold underline': currentPath === page.path }" class="hover:opacity-80 transition"> <div id="desktop-links" class="nav-links desktop-only"></div>
<span x-text="page.name"></span>
</a> <!-- Desktop Dark Mode Toggle -->
</template> <button class="theme-toggle icon-button desktop-only" aria-label="Toggle Dark Mode">
</div> <svg class="icon icon-sun hidden" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<div class="hidden sm:flex ml-auto">
<button @click="toggleDarkMode" class="ml-4 text-white focus:outline-none" title="Toggle dark mode">
<svg x-show="!darkMode" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m8.66-8.66h-1M4.34 12H3m15.36 6.36l-.71-.71M6.34 6.34l-.71-.71m12.02 0l-.71.71M6.34 17.66l-.71.71M12 5a7 7 0 100 14 7 7 0 000-14z" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m8.66-8.66h-1M4.34 12H3m15.36 6.36l-.71-.71M6.34 6.34l-.71-.71m12.02 0l-.71.71M6.34 17.66l-.71.71M12 5a7 7 0 100 14 7 7 0 000-14z" />
</svg> </svg>
<svg x-show="darkMode" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <svg class="icon icon-moon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12.79A9 9 0 1111.21 3a7 7 0 009.79 9.79z" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12.79A9 9 0 1111.21 3a7 7 0 009.79 9.79z" />
</svg> </svg>
</button> </button>
</div> </div>
</div>
<div x-show="open" class="sm:hidden mt-2 space-y-2"> <!-- Mobile Dropdown Menu -->
<template x-for="page in pages" :key="page.path"> <div id="mobile-menu" class="mobile-menu mobile-only hidden">
<a :href="page.path" :class="{ 'font-bold underline': currentPath === page.path }" class="block px-2 py-1 hover:bg-white/10"> <div id="mobile-links"></div>
<span x-text="page.name"></span> <button class="theme-toggle mobile-theme-btn" aria-label="Toggle Dark Mode">
</a> <span class="theme-text">🌙 Dark Mode</span>
</template>
<button @click="toggleDarkMode" class="w-full text-left px-2 py-1 text-white hover:bg-white/10" title="Toggle dark mode">
<span x-text="darkMode ? '☀️ Light Mode' : '🌙 Dark Mode'"></span>
</button> </button>
</div> </div>
</nav> </nav>
<main class="flex-grow p-6"> <!-- Main Content -->
<h1 class="text-3xl font-bold mb-4">Rexburg Meshtastic and MeshCore</h1> <main class="main-content">
<h1>Rexburg Meshtastic and MeshCore</h1>
<p class="mb-4"> <p>
The BYU-I Amateur Radio Society is experimenting with Meshtastic and MeshCore! These are low-power, long-range mesh radio networks using LoRa devices to support off-grid communication. They are open for all to use and most nodes are designed to continue working in emergencies and extended power outages. The BYU-I Amateur Radio Society is experimenting with Meshtastic and MeshCore! These are low-power, long-range mesh radio networks using LoRa devices to support off-grid communication. They are open for all to use and most nodes are designed to continue working in emergencies and extended power outages.
</p> </p>
<h2 class="text-xl font-semibold mt-6 mb-2">How to Get Involved</h2> <h2>How to Get Involved</h2>
<ul class="list-disc pl-6 space-y-2"> <ul class="styled-list">
<li>Purchase a supported LoRa radio (many of our members go with the Heltec V3 or RAK 4631), or check one out at one of our weekly meetings</li> <li>Purchase a supported LoRa radio (many of our members go with the Heltec V3 or RAK 4631), or check one out at one of our weekly meetings</li>
<li>Flash the latest <a href="https://flasher.meshtastic.org/" class="text-blue-400 underline">Meshtastic</a> or <a href="https://flasher.meshcore.co.uk/" class="text-blue-400 underline">MeshCore</a> firmware</li> <li>Flash the latest <a href="https://flasher.meshtastic.org/" class="link" target="_blank" rel="noopener">Meshtastic</a> or <a href="https://meshcore.io/flasher" class="link" target="_blank" rel="noopener">MeshCore</a> firmware</li>
<li>For Meshtastic: Change your Modem Preset to MediumFast, save, then change your Frequency Slot to 51. Then, change your Channel 0 name to Freq51 and the key to 1A==</li> <li>For Meshtastic: Change your Modem Preset to MediumFast, save, then change your Frequency Slot to 51. Then, change your Channel 0 name to Freq51 and the key to 1A==</li>
<li>For MeshCore: Set your radio preset to United States and you're good to go!</li> <li>For MeshCore: Set your radio preset to United States and you're good to go!</li>
<li>Join our <a href="https://discord.gg/D9fZ6uWugH" class="text-blue-400 underline">Discord</a> to get help, share your setup, and connect with us</li> <li>Join our <a href="https://discord.gg/D9fZ6uWugH" class="link" target="_blank" rel="noopener">Discord</a> to get help, share your setup, and connect with us</li>
<li>Get your node on the map (if it's stationary) by letting us know about it</li> <li>Get your node on the map (if it's stationary) by letting us know about it</li>
</ul> </ul>
<h2 class="text-xl font-semibold mt-6 mb-2">MeshCore Propagation Maps</h2>
<p class="mb-4">Thanks to Roger Coudé and his work on RadioMobile, we have propagation maps available.<br><a href="./eimeshcore.htm" class="text-blue-400 underline">Click here to view.</a></p> <h2>MeshCore Propagation Maps</h2>
<h2 class="text-xl font-semibold mt-6 mb-2">Current Meshtastic Node Map</h2> <p>
<div class="aspect-w-16 aspect-h-9 mb-4"> Thanks to Roger Coudé and his work on RadioMobile, we have propagation maps available.<br />
<a href="./eimeshcore.htm" class="link">Click here to view.</a>
</p>
<h2>Current Meshtastic Node Map</h2>
<div class="map-container">
<iframe <iframe
src="https://www.google.com/maps/d/u/1/embed?mid=1P5dIeUwP6589f-JT1CaLcsottrrgGRM&ehbc=2E312F" src="https://eastidahomesh.com/live-map.html"
width="100%" title="Current Meshtastic Node Map"
height="560"
class="w-full rounded shadow-md"
loading="lazy" loading="lazy"
allowfullscreen> allowfullscreen>
</iframe> </iframe>
</div> </div>
</main> </main>
<footer class="accent-bg text-white text-center py-4"> <!-- Footer -->
&copy; 2025-<span x-text="new Date().getFullYear()"></span> BYU-Idaho Amateur Radio Society. All rights reserved. <footer class="footer accent-bg">
&copy; 2025–<span id="current-year"></span> BYU-Idaho Amateur Radio Society. All rights reserved.
</footer> </footer>
<script>
function appData() {
return {
darkMode: document.documentElement.classList.contains('dark'),
currentPath: window.location.pathname,
banner: { title: '', content: '' },
pages: [],
async init() {
const navResp = await fetch('/assets/pages.json');
this.pages = await navResp.json();
const bannerResp = await fetch('/assets/banner.json?t=${Date.now()}');
this.banner = await bannerResp.json();
},
toggleDarkMode() {
this.darkMode = !this.darkMode;
document.documentElement.classList.toggle('dark');
localStorage.theme = this.darkMode ? 'dark' : 'light';
}
}
}
</script>
</body> </body>
</html> </html>
+51 -115
View File
@@ -3,146 +3,82 @@
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Net Check-Ins – BYU-I Amateur Radio Society</title> <title>Net Check-Ins – BYU-Idaho Amateur Radio Society</title>
<script src="https://cdn.tailwindcss.com"></script> <link rel="stylesheet" href="/style.css" />
<script> <script src="/script.js" defer></script>
tailwind.config = { <script src="/net/netScript.js" defer></script>
darkMode: 'class'
}
</script>
<script>
if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.classList.add('dark')
} else {
document.documentElement.classList.remove('dark')
}
</script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js" defer></script>
<style>
.accent-bg { background-color: #006eb6; }
.banner-bg { background-color: #a2daff; }
</style>
</head> </head>
<body class="bg-white dark:bg-gray-900 text-gray-800 dark:text-gray-100 min-h-screen flex flex-col" x-data="appData()" x-init="init()"> <body>
<!-- Banner --> <!-- Announcement Banner -->
<template x-if="banner.title && banner.content"> <div id="banner" class="banner-bg hidden">
<div class="w-full banner-bg text-black text-center py-2 px-4"> <strong id="banner-title"></strong>: <span id="banner-content"></span>
<strong x-text="banner.title"></strong>: <span x-text="banner.content"></span>
</div> </div>
</template>
<!-- Navbar --> <!-- Navigation Bar -->
<nav class="accent-bg text-white px-4 py-3 shadow-md" x-data="{ open: false }"> <nav class="navbar accent-bg">
<div class="flex flex-wrap items-center justify-between"> <div class="nav-container">
<a href="/" class="text-xl font-semibold mr-4">BYU-I Amateur Radio Society</a> <a href="/" class="nav-brand">BYU-I Amateur Radio Society</a>
<button @click="open = !open" class="sm:hidden text-white ml-auto focus:outline-none">
<svg x-show="!open" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <!-- Mobile Hamburger Toggle -->
<button id="menu-toggle" class="icon-button mobile-only" aria-label="Toggle Navigation Menu">
<svg id="icon-hamburger" class="icon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
</svg> </svg>
<svg x-show="open" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <svg id="icon-close" class="icon hidden" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg> </svg>
</button> </button>
<div class="hidden sm:flex flex-grow justify-center space-x-4">
<template x-for="page in pages" :key="page.path"> <!-- Desktop Links -->
<a :href="page.path" :class="{ 'font-bold underline': currentPath === page.path }" class="hover:opacity-80 transition"> <div id="desktop-links" class="nav-links desktop-only"></div>
<span x-text="page.name"></span>
</a> <!-- Desktop Dark Mode Toggle -->
</template> <button class="theme-toggle icon-button desktop-only" aria-label="Toggle Dark Mode">
</div> <svg class="icon icon-sun hidden" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<div class="hidden sm:flex ml-auto">
<button @click="toggleDarkMode" class="ml-4 text-white focus:outline-none" title="Toggle dark mode">
<svg x-show="!darkMode" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m8.66-8.66h-1M4.34 12H3m15.36 6.36l-.71-.71M6.34 6.34l-.71-.71m12.02 0l-.71.71M6.34 17.66l-.71.71M12 5a7 7 0 100 14 7 7 0 000-14z" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m8.66-8.66h-1M4.34 12H3m15.36 6.36l-.71-.71M6.34 6.34l-.71-.71m12.02 0l-.71.71M6.34 17.66l-.71.71M12 5a7 7 0 100 14 7 7 0 000-14z" />
</svg> </svg>
<svg x-show="darkMode" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <svg class="icon icon-moon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12.79A9 9 0 1111.21 3a7 7 0 009.79 9.79z" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12.79A9 9 0 1111.21 3a7 7 0 009.79 9.79z" />
</svg> </svg>
</button> </button>
</div> </div>
</div>
<div x-show="open" class="sm:hidden mt-2 space-y-2"> <!-- Mobile Dropdown Menu -->
<template x-for="page in pages" :key="page.path"> <div id="mobile-menu" class="mobile-menu mobile-only hidden">
<a :href="page.path" :class="{ 'font-bold underline': currentPath === page.path }" class="block px-2 py-1 hover:bg-white/10"> <div id="mobile-links"></div>
<span x-text="page.name"></span> <button class="theme-toggle mobile-theme-btn" aria-label="Toggle Dark Mode">
</a> <span class="theme-text">🌙 Dark Mode</span>
</template>
<button @click="toggleDarkMode" class="w-full text-left px-2 py-1 text-white hover:bg-white/10" title="Toggle dark mode">
<span x-text="darkMode ? '☀️ Light Mode' : '🌙 Dark Mode'"></span>
</button> </button>
</div> </div>
</nav> </nav>
<main class="flex-grow p-6"> <!-- Main Content -->
<h1 class="text-3xl font-bold mb-4">Weekly Net Check-Ins</h1> <main class="main-content">
<p>Our net meets each Tuesday at 8pm on the 146.510 repeater, which has a -6MHz offset and a bidirectional 100Hz tone. We'd love to hear you!</p> <h1>Weekly Net Check-Ins</h1>
<br><br> <p>
<div x-data="netStats()" x-init="load()"> Our net meets each Tuesday at 8pm on the 146.510 repeater, which has a -6MHz offset and a bidirectional 100Hz tone. We'd love to hear you!
</p>
<template x-if="callsigns.length"> <section id="callsigns-section" class="stats-section hidden">
<div> <h2>Callsigns That Have Checked In since January 2025</h2>
<h2 class="text-xl font-semibold mb-2">Callsigns That Have Checked In since January 2025</h2> <ul id="callsigns-list" class="column-list">
<ul class="columns-2 sm:columns-3 md:columns-4"> <!-- Dynamically populated from /net/net.json -->
<template x-for="call in callsigns" :key="call">
<li x-text="call"></li>
</template>
</ul> </ul>
</div> </section>
</template>
<br><br> <section id="weekly-section" class="stats-section hidden">
<template x-if="weekly.length"> <h2>Check-Ins Per Week</h2>
<div class="mb-6"> <ul id="weekly-list" class="styled-list">
<h2 class="text-xl font-semibold mb-2">Check-Ins Per Week</h2> <!-- Dynamically populated from /net/net.json -->
<ul class="space-y-1">
<template x-for="week in weekly" :key="week.date">
<li>
<span x-text="week.date"></span>: <strong x-text="week.count"></strong> check-ins
</li>
</template>
</ul> </ul>
</div> </section>
</template>
</div>
</main> </main>
<footer class="accent-bg text-white text-center py-4"> <!-- Footer -->
&copy; 2025-<span x-text="new Date().getFullYear()"></span> BYU-Idaho Amateur Radio Society. All rights reserved. <footer class="footer accent-bg">
&copy; 2025–<span id="current-year"></span> BYU-Idaho Amateur Radio Society. All rights reserved.
</footer> </footer>
<script>
function appData() {
return {
darkMode: document.documentElement.classList.contains('dark'),
currentPath: window.location.pathname,
banner: { title: '', content: '' },
pages: [],
async init() {
const navResp = await fetch('/assets/pages.json');
this.pages = await navResp.json();
const bannerResp = await fetch('/assets/banner.json?t=${Date.now()}');
this.banner = await bannerResp.json();
},
toggleDarkMode() {
this.darkMode = !this.darkMode;
document.documentElement.classList.toggle('dark');
localStorage.theme = this.darkMode ? 'dark' : 'light';
}
}
}
function netStats() {
return {
weekly: [],
callsigns: [],
async load() {
const data = await fetch('/net/net.json').then(res => res.json());
this.weekly = data.weekly || [];
this.callsigns = data.callsigns || [];
}
}
}
</script>
</body> </body>
</html> </html>
+30
View File
@@ -0,0 +1,30 @@
/* -------------------------------------------------------------------------- */
/* Net Statistics Rendering */
/* -------------------------------------------------------------------------- */
function renderNetStats(data, callsignsContainer, weeklyContainer) {
const callsigns = data.callsigns || [];
const weekly = data.weekly || [];
// Render Callsigns List
if (callsignsContainer && callsigns.length > 0) {
callsignsContainer.innerHTML = '';
callsigns.forEach(call => {
const li = document.createElement('li');
li.textContent = call;
callsignsContainer.appendChild(li);
});
document.getElementById('callsigns-section')?.classList.remove('hidden');
}
// Render Weekly Check-Ins List
if (weeklyContainer && weekly.length > 0) {
weeklyContainer.innerHTML = '';
weekly.forEach(week => {
const li = document.createElement('li');
li.innerHTML = `${week.date}: <strong>${week.count}</strong> check-ins`;
weeklyContainer.appendChild(li);
});
document.getElementById('weekly-section')?.classList.remove('hidden');
}
}
+186
View File
@@ -0,0 +1,186 @@
document.addEventListener('DOMContentLoaded', () => {
initTheme();
initFooterYear();
initMobileMenu();
fetchPageData();
});
/* -------------------------------------------------------------------------- */
/* Theme / Dark Mode Management */
/* -------------------------------------------------------------------------- */
function initTheme() {
const isDarkStored = localStorage.theme === 'dark';
const noThemeStored = !('theme' in localStorage);
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
if (isDarkStored || (noThemeStored && prefersDark)) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
updateThemeUI();
document.querySelectorAll('.theme-toggle').forEach(button => {
button.addEventListener('click', toggleDarkMode);
});
}
function toggleDarkMode() {
const isDark = document.documentElement.classList.toggle('dark');
localStorage.theme = isDark ? 'dark' : 'light';
updateThemeUI();
}
function updateThemeUI() {
const isDark = document.documentElement.classList.contains('dark');
document.querySelectorAll('.icon-sun').forEach(el => el.classList.toggle('hidden', !isDark));
document.querySelectorAll('.icon-moon').forEach(el => el.classList.toggle('hidden', isDark));
document.querySelectorAll('.theme-text').forEach(el => {
el.textContent = isDark ? '☀️ Light Mode' : '🌙 Dark Mode';
});
}
/* -------------------------------------------------------------------------- */
/* Footer Year Handler */
/* -------------------------------------------------------------------------- */
function initFooterYear() {
const yearEl = document.getElementById('current-year');
if (yearEl) {
yearEl.textContent = new Date().getFullYear();
}
}
/* -------------------------------------------------------------------------- */
/* Mobile Menu Toggle */
/* -------------------------------------------------------------------------- */
function initMobileMenu() {
const menuToggleBtn = document.getElementById('menu-toggle');
const mobileMenu = document.getElementById('mobile-menu');
const iconHamburger = document.getElementById('icon-hamburger');
const iconClose = document.getElementById('icon-close');
if (!menuToggleBtn || !mobileMenu) return;
menuToggleBtn.setAttribute('aria-expanded', 'false');
menuToggleBtn.addEventListener('click', () => {
const isHidden = mobileMenu.classList.toggle('hidden');
menuToggleBtn.setAttribute('aria-expanded', String(!isHidden));
iconHamburger.classList.toggle('hidden', !isHidden);
iconClose.classList.toggle('hidden', isHidden);
});
}
/* -------------------------------------------------------------------------- */
/* Async Data Fetching (Pages, Banner & Exam Schedule) */
/* -------------------------------------------------------------------------- */
async function fetchPageData() {
const currentPath = window.location.pathname;
// 1. Fetch Banner Data
try {
const bannerResp = await fetch(`/assets/banner.json?t=${Date.now()}`);
if (bannerResp.ok) {
const banner = await bannerResp.json();
if (banner && banner.title && banner.content) {
document.getElementById('banner-title').textContent = banner.title;
document.getElementById('banner-content').textContent = banner.content;
document.getElementById('banner').classList.remove('hidden');
}
}
} catch (err) {
console.error('Failed to load banner data:', err);
}
// 2. Fetch Navigation Links
try {
const navResp = await fetch('/assets/pages.json');
if (navResp.ok) {
const pages = await navResp.json();
renderNavigation(pages, currentPath);
}
} catch (err) {
console.error('Failed to load navigation data:', err);
}
// 3. Fetch Exam Schedule (only runs if the #exams-list element exists)
const examsContainer = document.getElementById('exams-list');
if (examsContainer) {
try {
const examResp = await fetch(`/assets/exams.json?t=${Date.now()}`);
if (examResp.ok) {
const exams = await examResp.json();
renderExams(exams, examsContainer);
}
} catch (err) {
console.error('Failed to load exam data:', err);
}
}
// 4. Fetch Net Check-In Data (only runs on pages containing #callsigns-list or #weekly-list)
const callsignsContainer = document.getElementById('callsigns-list');
const weeklyContainer = document.getElementById('weekly-list');
if (callsignsContainer || weeklyContainer) {
try {
const netResp = await fetch('/net/net.json');
if (netResp.ok) {
const data = await netResp.json();
renderNetStats(data, callsignsContainer, weeklyContainer);
}
} catch (err) {
console.error('Failed to load net statistics data:', err);
}
}
}
function renderNavigation(pages, currentPath) {
const desktopContainer = document.getElementById('desktop-links');
const mobileContainer = document.getElementById('mobile-links');
if (!desktopContainer || !mobileContainer) return;
desktopContainer.innerHTML = '';
mobileContainer.innerHTML = '';
pages.forEach(page => {
const desktopLink = document.createElement('a');
desktopLink.href = page.path;
desktopLink.textContent = page.name;
if (currentPath === page.path) desktopLink.classList.add('active');
desktopContainer.appendChild(desktopLink);
const mobileLink = document.createElement('a');
mobileLink.href = page.path;
mobileLink.textContent = page.name;
if (currentPath === page.path) mobileLink.classList.add('active');
mobileContainer.appendChild(mobileLink);
});
}
function renderExams(exams, container) {
container.innerHTML = '';
if (Array.isArray(exams) && exams.length > 0) {
exams.forEach(exam => {
const li = document.createElement('li');
li.append(`${exam.date}, ${exam.time} – ${exam.location} – `);
const link = document.createElement('a');
link.href = exam.register;
link.className = 'link';
link.target = '_blank';
link.rel = 'noopener';
link.textContent = 'Register here';
li.appendChild(link);
container.appendChild(li);
});
} else {
const li = document.createElement('li');
li.textContent = "We don't have any sessions scheduled right now, but if you're ready to test let us know and we'll set one up!";
container.appendChild(li);
}
}
+100
View File
@@ -0,0 +1,100 @@
:root {
--bg-color: #f7f9fb;
--surface-color: #ffffff;
--text-color: #17212b;
--muted-color: #536272;
--accent-color: #005da8;
--accent-strong: #00477f;
--banner-bg: #d8efff;
--banner-text: #123653;
--link-color: #005da8;
--border-color: #dce4ea;
--nav-hover: rgba(255, 255, 255, 0.16);
--shadow: 0 12px 30px rgba(23, 33, 43, 0.08);
--border-radius: 12px;
--font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
:root.dark {
--bg-color: #111a23;
--surface-color: #18242f;
--text-color: #edf4f8;
--muted-color: #b3c0ca;
--banner-bg: #173b58;
--banner-text: #e1f3ff;
--border-color: #2d3d4a;
--link-color: #82c9fa;
--shadow: 0 12px 30px rgba(0, 0, 0, 0.22);
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body { background: var(--bg-color); color: var(--text-color); display: flex; flex-direction: column; font-family: var(--font-family); line-height: 1.65; min-height: 100vh; }
.hidden { display: none !important; }
.accent-bg { background-color: var(--accent-color); color: #fff; }
.banner-bg { background-color: var(--banner-bg); color: var(--banner-text); }
.link { color: var(--link-color); font-weight: 600; text-decoration-thickness: 0.1em; text-underline-offset: 0.15em; }
a:focus-visible, button:focus-visible { outline: 3px solid #f4b942; outline-offset: 3px; }
#banner { font-size: 0.925rem; padding: 0.65rem 1rem; text-align: center; }
.navbar { box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12); padding: 0.9rem 1.25rem; }
.nav-container { align-items: center; display: flex; justify-content: space-between; margin: 0 auto; max-width: 1120px; }
.nav-brand { color: #fff; font-size: 1.1rem; font-weight: 700; letter-spacing: -0.02em; text-decoration: none; }
.nav-links { display: flex; gap: 0.25rem; }
.nav-links a { border-radius: 0.4rem; color: #fff; padding: 0.4rem 0.65rem; text-decoration: none; transition: background-color 0.2s ease; }
.nav-links a:hover, .nav-links a.active { background-color: var(--nav-hover); }
.nav-links a.active { font-weight: 700; }
.icon-button { align-items: center; background: none; border: 0; border-radius: 0.4rem; color: #fff; cursor: pointer; display: flex; padding: 0.4rem; }
.icon { height: 1.5rem; width: 1.5rem; }
.mobile-menu { display: flex; flex-direction: column; gap: 0.25rem; margin-top: 0.5rem; }
.mobile-menu a, .mobile-theme-btn { background: none; border: 0; border-radius: var(--border-radius); color: #fff; cursor: pointer; font-size: 1rem; padding: 0.5rem; text-align: left; text-decoration: none; }
.mobile-menu a:hover, .mobile-theme-btn:hover { background-color: var(--nav-hover); }
.main-content { flex-grow: 1; margin: 0 auto; max-width: 960px; padding: clamp(2rem, 5vw, 4.5rem) 1.25rem; width: 100%; }
h1 { font-size: clamp(2rem, 5vw, 3.75rem); font-weight: 700; letter-spacing: -0.045em; line-height: 1.05; margin-bottom: 1.25rem; }
h2 { font-size: clamp(1.25rem, 2vw, 1.55rem); font-weight: 700; letter-spacing: -0.025em; margin: 2rem 0 0.5rem; }
p { margin-bottom: 1rem; max-width: 70ch; }
.styled-list { margin-bottom: 1rem; padding-left: 1.5rem; }
.styled-list li { margin-bottom: 0.6rem; }
.footer { font-size: 0.875rem; margin-top: auto; padding: 1.5rem 1rem; text-align: center; }
.home-content { max-width: 1120px; }
.hero { align-items: center; display: grid; gap: clamp(2rem, 5vw, 4.5rem); grid-template-columns: 1fr 1fr; min-height: 29rem; }
.eyebrow { color: var(--accent-color); font-size: 0.78rem; font-weight: 800; letter-spacing: 0.11em; margin-bottom: 0.8rem; text-transform: uppercase; }
.hero-lede { color: var(--muted-color); font-size: clamp(1.05rem, 1.8vw, 1.2rem); }
.hero-actions { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 1.5rem; }
.button { align-items: center; border-radius: 0.5rem; display: inline-flex; font-weight: 750; justify-content: center; min-height: 2.75rem; padding: 0.55rem 1rem; text-decoration: none; transition: background-color 0.2s ease, transform 0.2s ease; }
.button:hover { transform: translateY(-1px); }
.button-primary { background: var(--accent-color); color: #fff; }
.button-primary:hover { background: var(--accent-strong); }
.button-secondary { border: 1px solid var(--border-color); color: var(--text-color); }
.button-secondary:hover { background: var(--surface-color); }
.hero-image { margin: 0; position: relative; }
.hero-image figcaption { color: var(--muted-color); font-size: 0.8rem; margin-top: 0.5rem; }
.featured-image { aspect-ratio: 4 / 3; border-radius: var(--border-radius); box-shadow: var(--shadow); display: block; object-fit: cover; width: 100%; }
.intro-section { border-block: 1px solid var(--border-color); display: grid; gap: 2rem; grid-template-columns: minmax(11rem, 0.75fr) 1.25fr; margin: clamp(3rem, 8vw, 6rem) 0 2rem; padding: 2rem 0; }
.intro-section h2 { margin: 0; }
.intro-section p { color: var(--muted-color); font-size: 1.05rem; margin: 0; }
.card-grid { display: grid; gap: 1rem; grid-template-columns: repeat(3, 1fr); }
.info-card { background: var(--surface-color); border: 1px solid var(--border-color); border-radius: var(--border-radius); box-shadow: 0 2px 5px rgba(23, 33, 43, 0.025); padding: 1.5rem; }
.info-card h2 { font-size: 1.15rem; margin: 0.35rem 0 0.65rem; }
.info-card p { color: var(--muted-color); font-size: 0.95rem; margin: 0; }
.card-number { color: var(--accent-color); font-size: 0.75rem; font-weight: 800; letter-spacing: 0.1em; }
.stats-section { margin-top: 2rem; }
.column-list { column-count: 2; column-gap: 1.5rem; list-style: none; padding: 0; }
.column-list li { margin-bottom: 0.25rem; }
.map-container { border-radius: var(--border-radius); box-shadow: var(--shadow); margin-bottom: 1.5rem; overflow: hidden; position: relative; width: 100%; }
.map-container iframe { border: 0; display: block; height: 560px; width: 100%; }
@media (min-width: 640px) { .mobile-only { display: none !important; } .column-list { column-count: 3; } }
@media (min-width: 768px) { .column-list { column-count: 4; } }
@media (max-width: 639px) {
.desktop-only { display: none !important; }
.navbar { padding-inline: 1rem; }
.nav-brand { font-size: 1rem; }
.hero, .intro-section { grid-template-columns: 1fr; }
.hero { min-height: 0; }
.hero-image { grid-row: 1; }
.card-grid { grid-template-columns: 1fr; }
.map-container iframe { height: 380px; }
}