> ## Documentation Index
> Fetch the complete documentation index at: https://help.hoopai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Designing beautiful landing pages & websites

> Learn the design principles and builder techniques that make funnel and website pages look professional, convert visitors, and work across all devices.

export const CourseTracker = ({courseId, lessonId, videoId}) => {
  const [progress, setProgress] = useState({});
  const [expanded, setExpanded] = useState(false);
  useEffect(() => {
    setProgress(loadProgress());
    document.body.setAttribute("data-academy", "true");
    return () => document.body.removeAttribute("data-academy");
  }, []);
  const course = COURSES[courseId];
  if (!course) return null;
  const lessons = course.lessons;
  const currentIndex = lessons.findIndex(l => l.id === lessonId);
  const completedCount = lessons.filter(l => !!progress[courseId + "/" + l.id]).length;
  const percent = lessons.length > 0 ? Math.round(completedCount / lessons.length * 100) : 0;
  const isCurrentDone = !!progress[courseId + "/" + lessonId];
  const prev = currentIndex > 0 ? lessons[currentIndex - 1] : null;
  const next = currentIndex < lessons.length - 1 ? lessons[currentIndex + 1] : null;
  const totalDuration = formatTotalDuration(lessons);
  const handleToggle = () => {
    const key = courseId + "/" + lessonId;
    const updated = {
      ...progress
    };
    if (updated[key]) {
      delete updated[key];
    } else {
      updated[key] = Date.now();
    }
    setProgress(updated);
    persistProgress(updated);
  };
  const lessonPath = lesson => "/academy/" + course.dir + "/" + lesson.id;
  const videoEmbed = videoId ? <div style={{
    position: "relative",
    width: "100%",
    paddingBottom: "56.25%",
    borderRadius: "var(--ds-radius-lg)",
    overflow: "hidden",
    marginBottom: "24px",
    background: "#000"
  }}>
      <iframe src={"https://www.youtube-nocookie.com/embed/" + videoId + "?rel=0"} title="Lesson video" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen style={{
    position: "absolute",
    top: 0,
    left: 0,
    width: "100%",
    height: "100%",
    border: "none"
  }} />
    </div> : null;
  const lessonList = lessons.map(lesson => {
    const isActive = lesson.id === lessonId;
    const isDone = !!progress[courseId + "/" + lesson.id];
    const itemStyle = {
      display: "flex",
      alignItems: "center",
      gap: "8px",
      padding: "10px 16px",
      borderTop: "1px solid var(--academy-border-subtle, #f3f4f6)",
      background: isActive ? "var(--academy-active-bg, #f9fafb)" : "transparent",
      textDecoration: "none",
      cursor: isActive ? "default" : "pointer",
      color: "inherit",
      transition: "background 0.15s"
    };
    const titleStyle = {
      flex: 1,
      fontSize: "13px",
      fontWeight: isActive ? 600 : 400,
      color: isActive ? "var(--academy-text, #111827)" : "var(--academy-text-secondary, #6b7280)",
      overflow: "hidden",
      textOverflow: "ellipsis",
      whiteSpace: "nowrap",
      lineHeight: "1.4"
    };
    const durationStyle = {
      fontSize: "12px",
      color: "var(--academy-text-muted, #9ca3af)",
      whiteSpace: "nowrap"
    };
    const inner = <>
        {isDone ? <CheckCircle /> : <VideoIcon />}
        <span style={titleStyle}>{lesson.title}</span>
        <span style={durationStyle}>{lesson.duration}</span>
      </>;
    if (isActive) {
      return <div key={lesson.id} style={itemStyle}>
          {inner}
        </div>;
    }
    return <a key={lesson.id} href={lessonPath(lesson)} style={itemStyle}>
        {inner}
      </a>;
  });
  return <div className="not-prose" id="academy-course-tracker">
      {videoEmbed}
      <div className="academy-tracker" style={{
    fontFamily: "Inter, -apple-system, BlinkMacSystemFont, sans-serif",
    borderRadius: "var(--ds-radius-lg)",
    border: "1px solid var(--academy-border, #e5e7eb)",
    background: "var(--academy-bg, #ffffff)",
    overflow: "hidden",
    marginBottom: "24px"
  }}>
        {}
        <div style={{
    padding: "16px 16px 0"
  }}>
          <h3 style={{
    margin: 0,
    fontSize: "16px",
    fontWeight: 600,
    lineHeight: "1.4",
    color: "var(--academy-text, #111827)"
  }}>
            {course.title}
          </h3>
          <div style={{
    display: "flex",
    gap: "12px",
    marginTop: "8px"
  }}>
            <span style={{
    display: "flex",
    alignItems: "center",
    gap: "5px",
    fontSize: "12px",
    color: "var(--academy-text-secondary, #6b7280)",
    padding: "3px 8px 3px 6px",
    borderRadius: "var(--ds-radius-sm)",
    border: "1px solid var(--academy-border, #e5e7eb)"
  }}>
              <BookIcon /> {lessons.length} lessons
            </span>
            <span style={{
    display: "flex",
    alignItems: "center",
    gap: "5px",
    fontSize: "12px",
    color: "var(--academy-text-secondary, #6b7280)",
    padding: "3px 8px 3px 6px",
    borderRadius: "var(--ds-radius-sm)",
    border: "1px solid var(--academy-border, #e5e7eb)"
  }}>
              <ClockIcon /> Approx. {totalDuration}
            </span>
          </div>
        </div>

        {}
        <div style={{
    padding: "14px 16px 16px"
  }}>
          <div style={{
    display: "flex",
    justifyContent: "space-between",
    fontSize: "12px",
    color: "var(--academy-text-secondary, #6b7280)"
  }}>
            <span>Your progress</span>
            <span style={{
    fontWeight: 500,
    color: "var(--academy-text, #111827)"
  }}>
              {percent}%
            </span>
          </div>
          <div style={{
    height: "6px",
    borderRadius: "var(--ds-radius-full)",
    background: "var(--academy-track, #f3f4f6)",
    marginTop: "8px",
    overflow: "hidden"
  }}>
            <div style={{
    height: "100%",
    borderRadius: "var(--ds-radius-full)",
    background: "var(--academy-progress, #3b82f6)",
    transition: "width 0.5s cubic-bezier(0.4, 0, 0.2, 1)",
    width: percent + "%"
  }} />
          </div>
        </div>

        {}
        <div className="academy-lessons-desktop">{lessonList}</div>

        {}
        <div className="academy-lessons-mobile">
          <button onClick={() => setExpanded(!expanded)} aria-expanded={expanded} style={{
    display: "flex",
    alignItems: "center",
    justifyContent: "space-between",
    padding: "12px 16px",
    cursor: "pointer",
    borderTop: "1px solid var(--academy-border-subtle, #f3f4f6)",
    background: "transparent",
    border: "none",
    borderTopStyle: "solid",
    borderTopWidth: "1px",
    borderTopColor: "var(--academy-border-subtle, #f3f4f6)",
    width: "100%",
    textAlign: "left",
    color: "var(--academy-text-secondary, #6b7280)",
    fontSize: "13px",
    fontWeight: 500,
    fontFamily: "inherit"
  }}>
            <span>
              {expanded ? "Hide lessons" : "Show all " + lessons.length + " lessons"}
            </span>
            <ChevronDown open={expanded} />
          </button>
          {expanded && lessonList}
        </div>

        {}
        <div style={{
    display: "flex",
    alignItems: "center",
    justifyContent: "space-between",
    borderTop: "1px solid var(--academy-border, #e5e7eb)",
    padding: "10px 16px"
  }}>
          {prev ? <a href={lessonPath(prev)} style={{
    fontSize: "13px",
    color: "var(--academy-text-secondary, #6b7280)",
    textDecoration: "none",
    display: "flex",
    alignItems: "center",
    gap: "4px"
  }}>
              ‹ Previous
            </a> : <div />}
          <button onClick={handleToggle} style={{
    fontSize: "13px",
    fontWeight: 500,
    cursor: "pointer",
    padding: "6px 14px",
    borderRadius: "var(--ds-radius-md)",
    border: isCurrentDone ? "1px solid var(--academy-border, #e5e7eb)" : "none",
    background: isCurrentDone ? "var(--academy-bg, #ffffff)" : "var(--academy-btn-bg, #111827)",
    color: isCurrentDone ? "var(--academy-complete, #10b981)" : "var(--academy-btn-text, #ffffff)",
    display: "flex",
    alignItems: "center",
    gap: "6px",
    transition: "all 0.2s",
    lineHeight: "1.4",
    fontFamily: "inherit"
  }}>
            {isCurrentDone ? <>
                <CheckCircle /> Completed
              </> : "Mark as completed"}
          </button>
          {next ? <a href={lessonPath(next)} style={{
    fontSize: "13px",
    color: "var(--academy-text-secondary, #6b7280)",
    textDecoration: "none",
    display: "flex",
    alignItems: "center",
    gap: "4px"
  }}>
              Next ›
            </a> : <div />}
        </div>
      </div>
    </div>;
};

<CourseTracker courseId="funnels-websites" lessonId="designing-beautiful-landing-pages-websites" />

Your pages are your digital storefront — they shape every visitor's first impression of your brand. A well-designed page is not just visually appealing; it guides visitors toward action, builds trust, and reflects the quality of your business. This guide covers the core design principles and practical techniques for building pages that look great and convert.

<Frame caption="The Designing Beautiful Landing Pages and Websites lesson in the HoopAI Academy">
  <img src="https://mintcdn.com/hoopai-84ec0cdc/gyU98wGhFXcTdqFf/images/academy-funnels-creating.png?fit=max&auto=format&n=gyU98wGhFXcTdqFf&q=85&s=28d21ce2a08059b0dc7abc6e718f221f" alt="Designing beautiful landing pages and websites article" width="1536" height="826" data-path="images/academy-funnels-creating.png" />
</Frame>

## Why this matters

Research consistently shows that visitors form an opinion about a website in less than one second. A page that looks dated or unprofessional signals that the business behind it may be too. Conversely, a clean, well-designed page that communicates value clearly converts a higher percentage of visitors into leads and customers — regardless of how much traffic you send to it.

## Core design principles

<AccordionGroup>
  <Accordion title="Visual hierarchy — guide the eye">
    Design your page so the most important element is seen first. Use a large, clear headline at the top. Follow it with a supporting subheadline, then the call-to-action button. Visitors should understand your offer and what to do next within the first 3 seconds.

    * Use larger font sizes for headlines, smaller for body text
    * Place your primary CTA button above the fold (visible without scrolling)
    * Use whitespace to separate sections and reduce visual clutter
  </Accordion>

  <Accordion title="Consistent branding">
    Every page should look like it belongs to the same brand. Before you start building, define:

    * **Primary and secondary colors** — use these consistently throughout
    * **Font choices** — one font for headings, one for body text
    * **Logo placement** — consistent position, usually top left or top center
    * **Button style** — consistent color, size, and shape across all pages
  </Accordion>

  <Accordion title="Mobile-first design">
    More than half of all web traffic comes from mobile devices. After designing your page on desktop, always switch to the mobile preview and check:

    * Headlines are not too large to read on a small screen
    * Buttons are large enough to tap comfortably
    * Images resize correctly
    * Text is not cut off or overlapping with other elements
  </Accordion>

  <Accordion title="Compelling imagery">
    Use high-quality, relevant images. Avoid generic stock photos when possible — real photos of your team, product, or clients build more trust. Keep images consistent in style and tone. Use the media library to store and reuse approved brand images across all pages.
  </Accordion>

  <Accordion title="Clear calls to action">
    Every page needs one primary call to action. Make the button:

    * **Visible:** Use a contrasting color that stands out from the background
    * **Action-oriented:** Use verbs — "Book My Call," "Get the Guide," "Start Now"
    * **Repeated:** Include the CTA button at the top and bottom of longer pages

    Avoid placing multiple competing CTAs on the same page — pick one goal per page.
  </Accordion>
</AccordionGroup>

## How to design effectively in the builder

<Steps>
  <Step title="Start with a template">
    Choose a template that closely matches your layout goal. Templates provide a tested structure — modify the content without redesigning the layout from scratch. This saves time and produces better results than starting from a blank page.

    <Frame caption="Selecting a starting template from the branded template library">
      <img src="https://mintcdn.com/hoopai-84ec0cdc/gyU98wGhFXcTdqFf/images/academy-funnels-creating.png?fit=max&auto=format&n=gyU98wGhFXcTdqFf&q=85&s=28d21ce2a08059b0dc7abc6e718f221f" alt="Branded template selection" width="1536" height="826" data-path="images/academy-funnels-creating.png" />
    </Frame>
  </Step>

  <Step title="Set global styles">
    Before editing individual sections, configure global font and color settings in the builder. This ensures consistency across all sections without manually styling each element.
  </Step>

  <Step title="Edit section by section">
    Work through the page top to bottom — header, hero, value section, social proof, CTA. Edit one section at a time: update the copy, swap in your images, adjust colors and spacing.

    <Frame caption="Editing page sections from top to bottom in the drag-and-drop builder">
      <img src="https://mintcdn.com/hoopai-84ec0cdc/gyU98wGhFXcTdqFf/images/academy-onboarding-webchat-widget.png?fit=max&auto=format&n=gyU98wGhFXcTdqFf&q=85&s=66e9548553a7c885294aae986c271a46" alt="Page builder section editing" width="1536" height="826" data-path="images/academy-onboarding-webchat-widget.png" />
    </Frame>
  </Step>

  <Step title="Use columns for layout">
    The builder uses a section > row > column > element structure. Use two-column layouts for side-by-side text and image combinations. Use single-column, full-width sections for hero areas and CTA blocks.
  </Step>

  <Step title="Preview on mobile">
    After completing the desktop design, switch to mobile preview. Adjust font sizes, button sizes, image dimensions, and spacing for mobile screens. Some sections may need to be reordered or simplified for mobile.

    <Frame caption="Mobile preview mode in the builder for checking and adjusting mobile layouts">
      <img src="https://mintcdn.com/hoopai-84ec0cdc/gyU98wGhFXcTdqFf/images/academy-onboarding-business-profile.png?fit=max&auto=format&n=gyU98wGhFXcTdqFf&q=85&s=16ee3d4747e0c5b5fdffec7483279cae" alt="Mobile preview in page builder" width="1536" height="826" data-path="images/academy-onboarding-business-profile.png" />
    </Frame>

    <Tip>
      Make every CTA button at least 44 pixels tall on mobile — this is the minimum recommended touch target size. Anything smaller is difficult to tap accurately on a phone screen.
    </Tip>
  </Step>

  <Step title="Save reusable sections as templates">
    When you create a section you are happy with — a testimonial block, a features grid, or a branded header — save it as a global section or template. You can then reuse it on other pages without rebuilding from scratch.
  </Step>
</Steps>

## Key benefits

<AccordionGroup>
  <Accordion title="Professional results without a designer">
    The template system and design tools make polished pages accessible to any business owner.
  </Accordion>

  <Accordion title="Consistent brand presentation">
    Global styles and branded templates ensure every page reflects your brand accurately.
  </Accordion>

  <Accordion title="Higher conversions">
    Pages built with clear hierarchy, strong CTAs, and fast load times convert more visitors into leads and customers.
  </Accordion>

  <Accordion title="Mobile-ready">
    Built-in mobile editing means your pages look great on every device.
  </Accordion>

  <Accordion title="Reusable components">
    Saved sections and templates reduce design time for every new page you build.
  </Accordion>
</AccordionGroup>
