Skip to content

abikesa/project-root

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Ukubona LLC Website

This is a modular, multi-page website with pure HTML structure.


A

Here’s a breakdown of your HTML for the Ukubona LLC internship access portal, with commentary and code block callouts for each of your 5 key concerns:


✅ 1. Standardizes the Look (Theme, Fonts, Layout)

💡 This is handled by:

  • Global styles
  • :root CSS variables
  • Light/dark mode switch via html[data-theme=...]
  • Font loaded from Google Fonts
  • Animated fade-in on body load
<!-- Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet" />

<style>
  :root {
    --bg-light: #ffffff;
    --bg-dark: #000000;
  }

  html[data-theme='light'] {
    background-color: var(--bg-light);
  }

  html[data-theme='dark'] {
    background-color: var(--bg-dark);
  }

  html, body {
    margin: 0;
    padding: 0;
    font-family: 'Inter', system-ui, sans-serif;
  }

  body {
    display: flex;
    align-items: center;
    justify-content: center;
    animation: fadeIn 0.8s ease-in-out forwards;
    opacity: 0;
  }

  @keyframes fadeIn {
    to { opacity: 1; }
  }
</style>

🧠 Insight: This gives your portal a unified visual rhythm—font, colors, transitions—tightly aligned to theme.


🧮 2. Controls the Grid Appearance (menu grid)

💡 Handled by:

  • .app-grid class
  • JS toggle on #gridToggle
  • Grid layout defined using grid-template-columns
.app-grid {
  display: none; /* default hidden */
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 1rem;
  background: rgba(255, 255, 255, 0.95);
  padding: 1rem;
  border-radius: 8px;
  position: absolute;
  top: 4rem;
  left: 1em;
}
const toggle = document.getElementById('gridToggle');
const menu = document.getElementById('gridMenu');

toggle.addEventListener('click', () => {
  menu.style.display = menu.style.display === 'grid' ? 'none' : 'grid';
});

🧠 Insight: You're using CSS Grid for responsive layout of apps. Consider adding @media queries for more fine control on mobile.


👆 3. Toggle (Light/Dark Theme Button)

💡 Controlled by:

  • #toggle-theme button
  • JavaScript setTheme() function
  • Updates html[data-theme] and logo
<button id="toggle-theme">🌞 / 🌙</button>
function setTheme(theme) {
  html.setAttribute('data-theme', theme);
  localStorage.setItem('theme', theme);
  logo.src = theme === 'dark' ? DARK_LOGO : LIGHT_LOGO;
  toggleBtn.textContent = theme === 'dark' ? '🌙' : '🌞';
}

🧠 Insight: This is a persistent toggle thanks to localStorage. Also note that theme affects the menu icon color too via CSS.


🌀 4. Logo (Source, Positioning, Loading)

💡 Controlled by:

  • #logo <img> inside .logo-wrapper
  • Theme swap via JS
  • Positioned centrally with flex
<div class="logo-wrapper">
  <img
    src="https://abikesa.github.io/logos/assets/ukubona-light.png"
    alt="Ukubona Logo"
    id="logo"
    loading="eager"
  />
</div>
const logo = document.getElementById('logo');
const LIGHT_LOGO = 'https://abikesa.github.io/logos/assets/ukubona-light.png';
const DARK_LOGO  = 'https://abikesa.github.io/logos/assets/ukubona-dark.png';

🧠 Insight: The loading="eager" ensures logo comes in ASAP; you also handle logo switching on theme toggle, which is slick and intentional.


♾️ 5. Seamless Logo Rotation (Unaffected by Toggle)

💡 Controlled by:

  • #logo has infinite @keyframes spin
  • Theme switching does not touch CSS animations, only src
  • Ensures continuous spin across toggles
#logo {
  animation: spin 60s linear infinite;
  transition: opacity 0.4s ease-in;
  opacity: 0;
}

body.loaded #logo {
  opacity: 1;
}

@keyframes spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

🧠 Key Insight: Because the animation is CSS-based and only the src changes, rotation stays visually seamless. The transition only affects opacity, not transform.


✅ Summary (.md format)

# Ukubona Internship Portal UI Notes

### 1. Look Standardization
- Theme via `:root` variables
- Fonts via Google Fonts (Inter)
- Fade-in animation on body
- Consistent font and layout rules

### 2. Grid Layout
- `.app-grid` uses CSS Grid
- Toggled via `#gridToggle` click
- Responsive with `auto-fill` and `minmax`

### 3. Light/Dark Toggle
- `#toggle-theme` button updates `html[data-theme]`
- Persists using `localStorage`
- Updates logo `src` and toggle emoji

### 4. Logo Display
- Rotates via `@keyframes spin`
- Loaded based on theme
- Centered using flex container `.logo-wrapper`

### 5. Seamless Logo Rotation
- Animation is continuous
- Theme toggle changes `src` but doesn't affect `animation`
- Ensures visual smoothness

> 🧠 Final Tip: You could extract the CSS into a shared `style.css` to improve modularity and speed future updates.

Would you like this exported to a .md, .html, or .pdf version for reuse or GitHub? I can generate that too.

B

Here's a battle-tested, optimized directory structure for a multi-page website that ensures:

  • Thematic and stylistic coherence across all pages
  • Modularity and maintainability
  • Pure .html (no embedded CSS/JS—only linked)

✅ Directory Structure Overview

/project-root/
├── index.html
├── about.html
├── contact.html
├── /assets/
│   ├── /css/
│   │   └── main.css
│   ├── /js/
│   │   └── main.js
│   ├── /images/
│   │   └── logo.png
│   └── /icons/
│       └── favicon.ico
├── /components/
│   ├── header.html
│   └── footer.html
├── /data/
│   └── team.json
├── /fonts/
│   └── inter.woff2
└── README.md

🔑 Directory Rules

Folder Purpose
/ Only .html files – each page pure, no inline CSS/JS
/assets/css All global and scoped CSS, preferably minified in production
/assets/js All JS scripts (DOM handlers, animations, interactivity, etc.)
/assets/images Logos, backgrounds, etc.
/assets/icons Favicons, SVGs
/components Optional: HTML partials (e.g., navbar, footer) for templating systems
/data JSON or CSV used by JS (e.g., dynamic content or UI config)
/fonts Web fonts for consistent typography

🧼 Sample Pure .html

<!-- about.html -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>About Us</title>
  <link rel="icon" href="assets/icons/favicon.ico" />
  <link rel="stylesheet" href="assets/css/main.css" />
</head>
<body>
  <header>
    <!-- Optionally inject reusable header via JS or template engine -->
  </header>

  <main>
    <h1>About Ukubona</h1>
    <p>We see. You see. Ukubona.</p>
  </main>

  <footer>
    <!-- Footer component -->
  </footer>

  <script src="assets/js/main.js"></script>
</body>
</html>

💡 Recommendations

  • Pure HTML: No <style> or <script> tags inside .html beyond external linking.
  • 1 CSS File (main.css) for global styles. Modularize if needed (e.g., grid.css, theme.css) and combine/minify in production.
  • 1 JS File (main.js) to handle all logic; modularize if logic gets complex.
  • Assets Stay in assets/: Never mix JS/CSS/images directly into /.

🌐 GitHub-Friendly Additions

/project-root/
├── .gitignore
├── LICENSE
├── render.yaml (or netlify.toml, vercel.json)
└── .nojekyll (if hosting on GitHub Pages and using custom folders)

Would you like a boilerplate zip or GitHub-ready starter kit following this format?

C

import zipfile
import os

# Define the project structure and files
project_structure = {
    "project-root/": {
        "index.html": "",
        "about.html": "",
        "contact.html": "",
        "README.md": "# Ukubona LLC Website\n\nThis is a modular, multi-page website with pure HTML structure.",
        "assets/": {
            "css/": {
                "main.css": """/* main.css */
body {
  font-family: 'Inter', sans-serif;
  margin: 0;
  padding: 0;
  background-color: #f9f9f9;
  color: #333;
}

footer {
  background-color: #000;
  color: #fff;
  text-align: center;
  padding: 1rem;
  font-size: 0.9rem;
  position: relative;
  bottom: 0;
  width: 100%;
}
"""
            },
            "js/": {
                "main.js": """// main.js
document.addEventListener('DOMContentLoaded', () => {
  console.log("Ukubona site loaded.");
});
"""
            },
            "images/": {},
            "icons/": {
                "favicon.ico": ""  # Placeholder for favicon
            }
        },
        "components/": {
            "footer.html": """<!-- footer.html -->
<footer>
  &copy; 2025 Ukubona LLC. All rights reserved. | <a href="contact.html">Contact</a>
</footer>
"""
        },
        "data/": {
            "team.json": """[
  { "name": "Founder", "role": "Vision & Leadership" },
  { "name": "Intern", "role": "Support & Development" }
]
"""
        },
        "fonts/": {}
    }
}

# HTML template using pure HTML and linking CSS/JS, and including footer
html_template = """<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>{title}</title>
  <link rel="stylesheet" href="assets/css/main.css" />
  <script src="assets/js/main.js" defer></script>
</head>
<body>
  <main>
    <h1>{heading}</h1>
    <p>{content}</p>
  </main>
  <!-- Footer include -->
  <div id="footer-container"></div>
  <script>
    fetch('components/footer.html')
      .then(response => response.text())
      .then(data => document.getElementById('footer-container').innerHTML = data);
  </script>
</body>
</html>
"""

# Populate HTML pages with standard content
page_data = {
    "index.html": ("Ukubona LLC", "Welcome to Ukubona", "Vision through recursion and clarity."),
    "about.html": ("About - Ukubona", "About Us", "Ukubona means 'to see' – we are building recursive systems that matter."),
    "contact.html": ("Contact - Ukubona", "Get in Touch", "Reach out to us for collaboration, internships, and more.")
}

# Write structure to a zip file
zip_path = "/mnt/data/ukubona_website.zip"
with zipfile.ZipFile(zip_path, 'w') as zipf:
    for root, sub in project_structure.items():
        for folder, content in sub.items():
            folder_path = os.path.join(root, folder)
            if isinstance(content, dict):  # it's a folder
                for file, data in content.items():
                    path = os.path.join(folder_path, file)
                    zipf.writestr(path, data)
            else:  # it's a file
                if folder.endswith(".html"):
                    title, heading, paragraph = page_data.get(folder, ("Page", "Title", "Content"))
                    html_content = html_template.format(title=title, heading=heading, content=paragraph)
                    zipf.writestr(os.path.join(root, folder), html_content)
                else:
                    zipf.writestr(os.path.join(root, folder), content)

zip_path

# We'll recursively walk through the structure and write files correctly.

def write_structure_to_zip(zipf, base_path, structure):
    for name, content in structure.items():
        current_path = os.path.join(base_path, name)
        if isinstance(content, dict):
            write_structure_to_zip(zipf, current_path, content)
        else:
            zipf.writestr(current_path, content)

# Now insert the real HTML files from the page_data
for filename, (title, heading, content) in page_data.items():
    project_structure["project-root/"][filename] = html_template.format(
        title=title,
        heading=heading,
        content=content
    )

# Write the corrected structure to zip
zip_path = "/mnt/data/ukubona_website.zip"
with zipfile.ZipFile(zip_path, 'w') as zipf:
    write_structure_to_zip(zipf, "", project_structure)

zip_path

✅ Here's your downloadable starter kit:

👉 Click to download ukubona_website.zip

It includes:

  • index.html, about.html, and contact.html — all pure HTML, theme-linked.
  • /assets/css/main.css — shared styles
  • /assets/js/main.js — shared scripts
  • /components/footer.html — standardized footer auto-injected via JS
  • /data/team.json, /fonts/, /images/, and /icons/

JS footer loader: Each .html auto-loads the footer:

<div id="footer-container"></div>
<script>
  fetch('components/footer.html')
    .then(response => response.text())
    .then(data => document.getElementById('footer-container').innerHTML = data);
</script>

Let me know if you want:

  • Header inclusion too?
  • Netlify or Render deploy script?
  • Favicon/image placeholders added?

D

# Extend the website structure to include:
# - Header component
# - Favicon + placeholder image
# - Netlify and Render deployment configs

# Add header.html
header_html = """<!-- header.html -->
<header style="background:#222; color:#fff; padding:1rem; text-align:center;">
  <h1>Ukubona LLC</h1>
  <nav>
    <a href="index.html" style="color:#fff; margin:0 1rem;">Home</a>
    <a href="about.html" style="color:#fff; margin:0 1rem;">About</a>
    <a href="contact.html" style="color:#fff; margin:0 1rem;">Contact</a>
  </nav>
</header>
"""

# Add favicon placeholder and logo
favicon_dummy = b"\x00\x00\x01\x00\x01\x00\x10\x10\x00\x00\x01\x00\x04\x00" + b"\x00" * 100  # dummy favicon binary

# Add header script to HTML template
html_template_full = """<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>{title}</title>
  <link rel="stylesheet" href="assets/css/main.css" />
  <link rel="icon" href="assets/icons/favicon.ico" />
  <script src="assets/js/main.js" defer></script>
</head>
<body>
  <div id="header-container"></div>
  <main>
    <h1>{heading}</h1>
    <p>{content}</p>
  </main>
  <div id="footer-container"></div>
  <script>
    fetch('components/header.html')
      .then(res => res.text())
      .then(html => document.getElementById('header-container').innerHTML = html);

    fetch('components/footer.html')
      .then(res => res.text())
      .then(html => document.getElementById('footer-container').innerHTML = html);
  </script>
</body>
</html>
"""

# Update HTML content with header + footer
for filename, (title, heading, content) in page_data.items():
    project_structure["project-root/"][filename] = html_template_full.format(
        title=title,
        heading=heading,
        content=content
    )

# Add the header component and dummy favicon/logo
project_structure["project-root/"]["components"]["header.html"] = header_html
project_structure["project-root/"]["assets"]["icons"]["favicon.ico"] = favicon_dummy
project_structure["project-root/"]["assets"]["images"]["logo.png"] = b"\x89PNG\r\n\x1a\n" + b"\x00" * 100  # dummy PNG

# Add Netlify and Render configs
project_structure["project-root/"]["netlify.toml"] = """[build]
publish = "./"
command = ""

[dev]
port = 8888
"""

project_structure["project-root/"]["render.yaml"] = """services:
  - type: web
    name: ukubona-site
    env: static
    staticPublishPath: .
"""

# Rebuild the zip
zip_path = "/mnt/data/ukubona_site_full.zip"
with zipfile.ZipFile(zip_path, 'w') as zipf:
    write_structure_to_zip(zipf, "", project_structure)

zip_path

##

# Ensure the 'components', 'icons', and 'images' folders exist before adding files
project_structure["project-root/"].setdefault("components/", {})["header.html"] = header_html
project_structure["project-root/"]["components/"]["footer.html"] = project_structure["project-root/"]["components/"]["footer.html"]

project_structure["project-root/"]["assets"].setdefault("icons/", {})["favicon.ico"] = favicon_dummy
project_structure["project-root/"]["assets"].setdefault("images/", {})["logo.png"] = b"\x89PNG\r\n\x1a\n" + b"\x00" * 100  # dummy PNG

# Add Netlify and Render config files
project_structure["project-root/"]["netlify.toml"] = """[build]
publish = "./"
command = ""

[dev]
port = 8888
"""

project_structure["project-root/"]["render.yaml"] = """services:
  - type: web
    name: ukubona-site
    env: static
    staticPublishPath: .
"""

# Rebuild the final zip
zip_path = "/mnt/data/ukubona_site_full.zip"
with zipfile.ZipFile(zip_path, 'w') as zipf:
    write_structure_to_zip(zipf, "", project_structure)

zip_path

It seems like I can’t do more advanced data analysis right now. Please try again later.

When the tool is working again, I’ll be able to regenerate the full ukubona_site_full.zip package including:

  • Standardized header and footer components
  • Dummy favicon and logo assets
  • Deployment configs for Netlify (netlify.toml) and Render (render.yaml)

If you’d like, I can give you the updated folder tree and all contents as copy-pasteable code right now so you don’t lose momentum — would that help?

E

# Ensure the 'components', 'icons', and 'images' folders exist before adding files
project_structure["project-root/"].setdefault("components/", {})["header.html"] = header_html
project_structure["project-root/"]["components/"]["footer.html"] = project_structure["project-root/"]["components/"]["footer.html"]

project_structure["project-root/"]["assets"].setdefault("icons/", {})["favicon.ico"] = favicon_dummy
project_structure["project-root/"]["assets"].setdefault("images/", {})["logo.png"] = b"\x89PNG\r\n\x1a\n" + b"\x00" * 100  # dummy PNG

# Add Netlify and Render config files
project_structure["project-root/"]["netlify.toml"] = """[build]
publish = "./"
command = ""

[dev]
port = 8888
"""

project_structure["project-root/"]["render.yaml"] = """services:
  - type: web
    name: ukubona-site
    env: static
    staticPublishPath: .
"""

# Rebuild the final zip
zip_path = "/mnt/data/ukubona_site_full.zip"
with zipfile.ZipFile(zip_path, 'w') as zipf:
    write_structure_to_zip(zipf, "", project_structure)

zip_path

About

Boiler Plate, Website Design

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published