Past Lesson Note

This note is from 8 months ago. You're viewing content from a previous lesson.

Daily Note for September 19, 2025 Past Lesson

At the start of every class, please: 

  1. Make sure you are working from your programming folder
  2. Make sure your python virtual environment is activated
  3. Make sure you can access our test template at 127.0.0.1:5000

 

<!DOCTYPE html>
<html lang="en">
<head>
  <!--
    TITLE: Tailwind "Club Website" — Single Contiguous, Heavily Commented File

    READ THIS FIRST (Tailwind + Layout Guide):
    • Utility-first CSS: You compose styles by stacking utility classes directly on elements.
    • Mobile-first breakpoints (defaults): sm ≥640px, md ≥768px, lg ≥1024px, xl ≥1280px.
      - Unprefixed classes apply to all sizes.
      - sm:/md:/lg:/xl: add or override styles at that width and up.
    • Core layout primitives you’ll see below:
      - max-w-* + mx-auto     → fixed-width centered page content
      - px-* / py-*           → horizontal / vertical padding
      - flex + items-* + gap-*→ 1-D layout (rows/columns), alignment, spacing
      - grid + *:grid-cols-*  → 2-D layout (rows & columns), responsive column counts
      - gap-*                 → gutter between grid/flex children
      - col-span-*            → how many columns a grid child spans
      - sticky top-0          → stick an element to the top on scroll
      - aspect-[W/H]          → maintain aspect ratio boxes
    • Mental model:
      1) Build a good single-column mobile layout.
      2) Add md:*, lg:* to enhance to multi-column on larger screens.
  -->

  <meta charset="utf-8" />
  <!-- Ensures proper scaling on mobile devices -->
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>Your Club – Home</title>

  <!-- Tailwind via CDN (quick start). For production, prefer a build that purges unused CSS. -->
  <script src="https://cdn.tailwindcss.com"></script>

  <!-- Optional: sensible default font stack -->
  <style>
    :root { color-scheme: light dark; }
    html { font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif; }
  </style>
</head>

<!--
  BODY:
  • min-h-screen    : at least full viewport height, lets the footer sit at the bottom on short pages
  • bg-slate-50     : subtle light gray background
  • text-slate-800  : high-contrast dark text for readability
-->
<body class="min-h-screen bg-slate-50 text-slate-800">

  <!--
    SKIP LINK (accessibility): invisible until focused by keyboard users
    • sr-only                    : visually hidden off-screen
    • focus:not-sr-only + focus:*: reveal and position when focused
  -->
  <a href="#main"
     class="sr-only focus:not-sr-only focus:absolute focus:top-2 focus:left-2 focus:bg-white focus:text-slate-900 focus:px-3 focus:py-2 focus:rounded focus:shadow">
     Skip to main content
  </a>

  <!--
    FULL-WIDTH ANNOUNCEMENT BAR:
    • Spans the viewport because it is not inside a width-constrained container
    • text-center: center the inline content within the bar
  -->
  <div class="bg-indigo-600 text-white text-sm text-center px-4 py-2">
    Welcome back! First meeting of the semester: <strong>Wednesday @ 15:45, Room 204</strong>.
  </div>

  <!--
    HEADER / NAV:
    • bg-white border-b : visual separation from page content
    • sticky top-0 z-50 : keeps header pinned during scroll and above other content
    INNER CONTAINER:
    • max-w-6xl mx-auto : fixed max width and center on the page
    • px-4              : horizontal padding so content doesn’t touch viewport edges
    • h-16 flex items-center justify-between : 1-D row layout with vertical centering and space-between
  -->
  <header class="bg-white border-b sticky top-0 z-50">
    <nav class="max-w-6xl mx-auto px-4 h-16 flex items-center justify-between" aria-label="Primary">
      <!-- BRAND GROUP (inline flex) -->
      <a href="#" class="flex items-center gap-2 focus:outline-none focus:ring-2 focus:ring-indigo-600 rounded">
        <span class="inline-block w-8 h-8 rounded-full bg-indigo-600" aria-hidden="true"></span>
        <span class="font-semibold">Your Club</span>
      </a>

      <!-- DESKTOP NAV LINKS:
           • hidden md:flex: collapsed on small screens; becomes flex row at md+ (≥768px)
           • items-center gap-6 text-sm: horizontally aligned items with 1.5rem gaps and compact type
      -->
      <div class="hidden md:flex items-center gap-6 text-sm">
        <a href="#about" class="hover:text-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-600 rounded px-1">About</a>
        <a href="#events" class="hover:text-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-600 rounded px-1">Events</a>
        <a href="#officers" class="hover:text-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-600 rounded px-1">Officers</a>
        <a href="#join" class="hover:text-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-600 rounded px-1">Join</a>
        <a href="#join"
           class="inline-flex items-center rounded-lg bg-indigo-600 px-3 py-2 font-medium text-white hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-600">
          Become a member
        </a>
      </div>

      <!-- MOBILE MENU BUTTON (visible only below md) -->
      <button type="button"
              class="md:hidden inline-flex items-center justify-center rounded-lg border border-slate-300 px-2.5 py-2 hover:bg-slate-100 focus:outline-none focus:ring-2 focus:ring-indigo-600"
              aria-controls="mobile-menu"
              aria-expanded="false"
              id="mobile-menu-button">
        <span class="sr-only">Open menu</span>
        <span class="block w-5 h-0.5 bg-slate-800 mb-1"></span>
        <span class="block w-5 h-0.5 bg-slate-800 mb-1"></span>
        <span class="block w-5 h-0.5 bg-slate-800"></span>
      </button>
    </nav>

    <!--
      MOBILE COLLAPSIBLE MENU:
      • md:hidden : only present below md breakpoint
      • hidden    : start closed; toggled by JS to show/hide
      • Links are block-level so they stack vertically and are easy to tap
    -->
    <div id="mobile-menu" class="md:hidden hidden px-4 py-2 border-t bg-white" role="region" aria-label="Mobile">
      <a href="#about" class="block rounded px-2 py-2 hover:bg-slate-100">About</a>
      <a href="#events" class="block rounded px-2 py-2 hover:bg-slate-100">Events</a>
      <a href="#officers" class="block rounded px-2 py-2 hover:bg-slate-100">Officers</a>
      <a href="#join" class="block rounded px-2 py-2 hover:bg-slate-100">Join</a>
      <a href="#join"
         class="mt-1 inline-flex w-full items-center justify-center rounded-lg bg-indigo-600 px-3 py-2 font-medium text-white hover:bg-indigo-700">
        Become a member
      </a>
    </div>
  </header>

  <!--
    HERO SECTION (INTRO PANEL)
    LAYOUT: RESPONSIVE GRID
    • max-w-6xl mx-auto px-4 : centered, constrained container with side padding
    • py-12 md:py-16         : vertical rhythm (more space on larger screens)
    • grid                   : turns the section into a 2-D layout context
    • md:grid-cols-2         : at md+ → two columns; on mobile (default) → single column
    • gap-8                  : gutters between the two grid children (text & image)
    • items-center           : vertically center grid items within their rows
    RESULT:
    • Mobile: Text ABOVE image (natural source order).
    • Desktop: Text left, image right (two columns).
  -->
  <section class="max-w-6xl mx-auto px-4 py-12 md:py-16 grid md:grid-cols-2 gap-8 items-center">
    <!-- LEFT: TEXT (grid item #1) -->
    <div>
      <h1 class="text-3xl md:text-4xl font-bold leading-tight">
        Build, Learn, and Compete with <span class="text-indigo-700">Your Club</span>
      </h1>
      <p class="mt-4 text-slate-600">
        We’re a community of students who meet weekly to collaborate, learn new skills, and run fun events.
        Everyone is welcome—no experience required.
      </p>
      <!-- Simple button row using flex (independent from grid above) -->
      <div class="mt-6 flex flex-wrap gap-3">
        <a href="#join"
           class="rounded-lg bg-indigo-600 px-4 py-2 font-medium text-white hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-600">
          Join the club
        </a>
        <a href="#events"
           class="rounded-lg border border-slate-300 px-4 py-2 font-medium hover:bg-slate-100 focus:outline-none focus:ring-2 focus:ring-indigo-600">
          See upcoming events
        </a>
      </div>
    </div>

    <!-- RIGHT: IMAGE / ILLUSTRATION (grid item #2) -->
    <!--
      aspect-[16/10] : preserves a 16:10 box ratio (prevents layout shift before image loads)
      rounded-2xl    : soft corners
      shadow         : mild elevation
      bg-gradient-*  : decorative gradient for the placeholder
      flex items-center justify-center : centers the placeholder glyph
      Replace the span with a real <img> later.
    -->
    <div class="aspect-[16/10] rounded-2xl shadow bg-gradient-to-br from-indigo-50 to-slate-100 flex items-center justify-center">
      <span class="text-6xl" aria-hidden="true">★</span>
      <span class="sr-only">Club illustration</span>
    </div>
  </section>

  <!-- MAIN CONTENT -->
  <main id="main" tabindex="-1">
    <!-- ABOUT SECTION -->
    <!--
      GRID OF FEATURE CARDS:
      • grid                   : enable 2-D layout
      • sm:grid-cols-2         : 2 columns from 640px+
      • lg:grid-cols-3         : 3 columns from 1024px+
      • gap-6                  : gutters between cards
      EFFECT:
      • Mobile: 1 column (cards stack)
      • Small tablets: 2 columns
      • Laptops+: 3 columns
    -->
    <section id="about" class="max-w-6xl mx-auto px-4 py-12">
      <h2 class="text-2xl font-semibold">About the Club</h2>
      <p class="mt-3 text-slate-700 leading-relaxed">
        Our mission is to create a welcoming space for students to explore interests, develop leadership,
        and build lasting friendships. We meet every <strong>Wednesday</strong> after school.
      </p>

      <div class="mt-8 grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
        <div class="rounded-xl border border-slate-200 bg-white p-5 shadow-sm">
          <h3 class="font-semibold">Learn</h3>
          <p class="mt-2 text-sm text-slate-600">
            Beginner-friendly sessions and advanced workshops to grow your skills step by step.
          </p>
        </div>
        <div class="rounded-xl border border-slate-200 bg-white p-5 shadow-sm">
          <h3 class="font-semibold">Build</h3>
          <p class="mt-2 text-sm text-slate-600">
            Work on real projects together. Present your work at the end of term showcases.
          </p>
        </div>
        <div class="rounded-xl border border-slate-200 bg-white p-5 shadow-sm">
          <h3 class="font-semibold">Compete</h3>
          <p class="mt-2 text-sm text-slate-600">
            Friendly in-club competitions and events to challenge yourself and have fun.
          </p>
        </div>
      </div>
    </section>

    <!-- EVENTS SECTION -->
    <!--
      TWO-COLUMN CARD LIST ON MD+:
      • grid md:grid-cols-2 : 1 column on mobile, 2 columns from md (≥768px)
      • gap-6               : space between the two columns and rows
      Each article card is a grid child; inside the card we use flex to align header elements.
    -->
    <section id="events" class="max-w-6xl mx-auto px-4 py-12">
      <h2 class="text-2xl font-semibold">Upcoming Events</h2>
      <p class="mt-3 text-slate-700">Here’s what’s happening next.</p>

      <div class="mt-8 grid gap-6 md:grid-cols-2">
        <article class="rounded-xl border border-slate-200 bg-white p-5 shadow-sm">
          <!-- Nested flex row inside a grid item -->
          <div class="flex items-start justify-between gap-4">
            <div>
              <h3 class="font-semibold">Welcome & Kickoff</h3>
              <p class="text-sm text-slate-600 mt-1">Wed, Sep 24 · Room 204</p>
            </div>
            <div class="shrink-0 rounded-lg bg-indigo-50 px-3 py-1 text-xs font-medium text-indigo-700">Week 1</div>
          </div>
          <p class="mt-3 text-sm text-slate-700">
            Meet the officers, plan the term, and share your goals. Snacks provided.
          </p>
          <a href="#" class="mt-4 inline-block text-sm font-medium text-indigo-700 hover:underline">Details</a>
        </article>

        <article class="rounded-xl border border-slate-200 bg-white p-5 shadow-sm">
          <div class="flex items-start justify-between gap-4">
            <div>
              <h3 class="font-semibold">Project Sprint</h3>
              <p class="text-sm text-slate-600 mt-1">Wed, Oct 1 · Room 204</p>
            </div>
            <div class="shrink-0 rounded-lg bg-indigo-50 px-3 py-1 text-xs font-medium text-indigo-700">Week 2</div>
          </div>
          <p class="mt-3 text-sm text-slate-700">
            Form small teams and start building. Mentors available for guidance.
          </p>
          <a href="#" class="mt-4 inline-block text-sm font-medium text-indigo-700 hover:underline">Details</a>
        </article>
      </div>
    </section>

    <!-- OFFICERS SECTION -->
    <!--
      RESPONSIVE GRID 2→3 COLUMNS:
      • grid sm:grid-cols-2 md:grid-cols-3 : 1 col on mobile, 2 on small screens, 3 on md+
      • gap-6                              : gutters between cards
    -->
    <section id="officers" class="max-w-6xl mx-auto px-4 py-12">
      <h2 class="text-2xl font-semibold">Club Officers</h2>
      <p class="mt-3 text-slate-700">Reach out if you have questions or ideas.</p>

      <div class="mt-8 grid gap-6 sm:grid-cols-2 md:grid-cols-3">
        <div class="rounded-xl border border-slate-200 bg-white p-5 shadow-sm">
          <div class="w-14 h-14 rounded-full bg-slate-200"></div>
          <h3 class="mt-3 font-semibold">Alex Johnson</h3>
          <p class="text-sm text-slate-600">President</p>
          <a href="mailto:[email protected]" class="mt-2 inline-block text-sm text-indigo-700 hover:underline">[email protected]</a>
        </div>

        <div class="rounded-xl border border-slate-200 bg-white p-5 shadow-sm">
          <div class="w-14 h-14 rounded-full bg-slate-200"></div>
          <h3 class="mt-3 font-semibold">Brianna Lee</h3>
          <p class="text-sm text-slate-600">Vice President</p>
          <a href="mailto:[email protected]" class="mt-2 inline-block text-sm text-indigo-700 hover:underline">[email protected]</a>
        </div>

        <div class="rounded-xl border border-slate-200 bg-white p-5 shadow-sm">
          <div class="w-14 h-14 rounded-full bg-slate-200"></div>
          <h3 class="mt-3 font-semibold">Carlos Diaz</h3>
          <p class="text-sm text-slate-600">Secretary</p>
          <a href="mailto:[email protected]" class="mt-2 inline-block text-sm text-indigo-700 hover:underline">[email protected]</a>
        </div>
      </div>
    </section>

    <!-- JOIN / CONTACT FORM -->
    <!--
      FORM LAYOUT WITH GRID:
      • max-w-3xl mx-auto     : narrower centered container (forms are easier to read when narrow)
      • Inside the form:
        - grid gap-4          : place fields on a grid with vertical/horizontal spacing
        - md:grid-cols-2      : at md+, use two columns for some fields (first/last name)
        - md:col-span-2       : make a field span both columns (email, interests, checkbox row)
      WHY GRID HERE:
      • Grid makes aligning multi-column forms precise and responsive.
    -->
    <section id="join" class="max-w-3xl mx-auto px-4 py-12">
      <h2 class="text-2xl font-semibold">Join the Club</h2>
      <p class="mt-3 text-slate-700">Fill out this quick form and we’ll contact you with details.</p>

      <form class="mt-8 rounded-xl border border-slate-200 bg-white p-6 shadow-sm" action="#" method="post">
        <div class="grid gap-4 md:grid-cols-2">
          <div>
            <label for="first_name" class="block text-sm font-medium">First name</label>
            <input id="first_name" name="first_name" type="text" required
                   class="mt-1 block w-full rounded-lg border border-slate-300 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-600"
                   placeholder="Ada" />
          </div>
          <div>
            <label for="last_name" class="block text-sm font-medium">Last name</label>
            <input id="last_name" name="last_name" type="text" required
                   class="mt-1 block w-full rounded-lg border border-slate-300 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-600"
                   placeholder="Lovelace" />
          </div>

          <!-- Spans across both columns at md+ -->
          <div class="md:col-span-2">
            <label for="email" class="block text-sm font-medium">Email</label>
            <input id="email" name="email" type="email" required
                   class="mt-1 block w-full rounded-lg border border-slate-300 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-600"
                   placeholder="[email protected]" />
          </div>

          <!-- Spans across both columns at md+ -->
          <div class="md:col-span-2">
            <label for="interests" class="block text-sm font-medium">Interests</label>
            <textarea id="interests" name="interests" rows="4"
                      class="mt-1 block w-full rounded-lg border border-slate-300 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-600"
                      placeholder="Tell us what you’re excited to do..."></textarea>
          </div>

          <!-- Spans across both columns at md+; checkbox row uses flex for alignment -->
          <div class="md:col-span-2 flex items-center gap-2">
            <input id="newsletter" name="newsletter" type="checkbox"
                   class="h-4 w-4 rounded border-slate-300 focus:outline-none focus:ring-2 focus:ring-indigo-600" />
            <label for="newsletter" class="text-sm">Subscribe to updates</label>
          </div>
        </div>

        <div class="mt-6 flex items-center gap-3">
          <button type="submit"
                  class="rounded-lg bg-indigo-600 px-4 py-2 font-medium text-white hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-600">
            Submit
          </button>
          <p class="text-sm text-slate-600">We’ll never share your email.</p>
        </div>
      </form>
    </section>
  </main>

  <!-- FOOTER -->
  <!--
    PAGE-EDGE SEPARATOR + FLEX WRAP:
    • bg-white border-t : visually separates footer from content above
    • Inside container: max-w-6xl mx-auto px-4 py-8
    • flex flex-wrap items-center justify-between gap-4 :
      - becomes a single row on wide screens
      - wraps onto multiple rows on narrow screens
  -->
  <footer class="bg-white border-t">
    <div class="max-w-6xl mx-auto px-4 py-8 flex flex-wrap items-center justify-between gap-4">
      <p class="text-sm text-slate-600">
        © <span id="year"></span> Your Club. All rights reserved.
      </p>
      <div class="flex items-center gap-4 text-sm">
        <a href="#" class="hover:text-indigo-700">Code of Conduct</a>
        <a href="#" class="hover:text-indigo-700">Privacy</a>
        <a href="#" class="hover:text-indigo-700">Contact</a>
      </div>
    </div>
  </footer>

  <!--
    TINY VANILLA JS:
    • Toggles mobile menu visibility by adding/removing the "hidden" class
    • Updates © year automatically
  -->
  <script>
    (function () {
      const btn = document.getElementById('mobile-menu-button');
      const menu = document.getElementById('mobile-menu');
      btn?.addEventListener('click', () => {
        const isOpen = !menu.classList.contains('hidden');
        menu.classList.toggle('hidden');
        btn.setAttribute('aria-expanded', String(!isOpen));
      });

      const year = document.getElementById('year');
      if (year) year.textContent = new Date().getFullYear();
    })();
  </script>
</body>
</html>