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

# The Three Most Important Design Considerations for Energy Efficiency

> Learn more about what the three most important enclosure-related factors influencing how much energy a building will consume.

export const BuildingScienceFightClubAbout = () => <div className="flex space-x-6 items-center">
    <img src="https://res.cloudinary.com/acelab/image/upload/v1652126348/CMS/BSFC%20-%20AIA/Christine_Williamson_copy_bxkwit_xrxnyq.jpg" alt="Christine Williamson" className="m-0 shrink-0 w-full max-w-[160px] rounded-full border object-center object-cover" />
    <div className="flex-1">
      <p className="mt-0">
        <strong>Christine Williamson - Assoc. AIA</strong>
        <br />
        <em className="text-sm">Building Scientist | Instructor</em>
      </p>
      <p className="mb-0 text-sm">
        Christine Williamson has spent her career in building science
        forensics, discovering why buildings fail and working with owners,
        architects, and builders to remedy the problems. She is the founder of
        the Instagram account <a href="https://www.instagram.com/buildingsciencefightclub" taget="_blank">@BuildingScienceFightClub</a>, an educational project
        that teaches architects about building science and construction.
      </p>
    </div>
  </div>;

export const AiaCourseEligibility = ({creditType}) => <div className="flex items-center space-x-2">
    <img src="https://res.cloudinary.com/acelab/image/upload/v1786555963/lms-resources/f0t7pi-tb4-aia-logo-bw-cee269f83a.png" alt="AIA logo" className="max-w-[60px] m-0" />
    <p className="m-0">
      This course is eligible for <strong>AIA 0.25 LU|{creditType}</strong>.
    </p>
  </div>;

export const Quiz = ({contentIdentifier, apiBaseUrl, appBaseUrl, authPath = "/docs-auth", authMessageType = "acelab:docs-auth", quizPath = "/lms/learning-content/quiz?pagePath={contentIdentifier}", submissionPath = "/lms/learning-content/quiz/submissions?pagePath={contentIdentifier}", authTimeoutMs = 5000}) => {
  const QUIZ_PHASES = {
    Authenticating: "authenticating",
    Loading: "loading",
    Ready: "ready",
    Submitting: "submitting",
    Passed: "passed",
    Failed: "failed",
    Anonymous: "anonymous",
    Error: "error"
  };
  const TOKEN_STORAGE_KEY = "acelab:docs-auth-token";
  const localDocsHostnames = new Set(["localhost", "127.0.0.1", "[::1]"]);
  const isLocalDocsPreview = typeof window !== "undefined" && localDocsHostnames.has(window.location.hostname);
  const resolvedApiBaseUrl = apiBaseUrl || (isLocalDocsPreview ? "http://localhost:5100/api" : "https://acelab-api-prod-178528813198.us-east4.run.app/api");
  const resolvedAppBaseUrl = appBaseUrl || (isLocalDocsPreview ? "http://localhost:3000" : "https://app.acelabusa.com");
  const inferredContentIdentifier = typeof window === "undefined" ? "" : `/${window.location.pathname.split("/").filter(Boolean).join("/")}`;
  const resolvedContentIdentifier = String(contentIdentifier || "").trim() || inferredContentIdentifier;
  const trimTrailingSlash = value => String(value || "").replace(/\/+$/, "");
  const buildUrl = (baseUrl, path) => {
    const base = trimTrailingSlash(baseUrl);
    const normalizedPath = String(path || "").startsWith("/") ? path : `/${path}`;
    return `${base}${normalizedPath}`;
  };
  const buildContentPath = (pathTemplate, identifier) => pathTemplate.replace("{contentIdentifier}", encodeURIComponent(identifier));
  const readStoredToken = () => {
    try {
      return sessionStorage.getItem(TOKEN_STORAGE_KEY);
    } catch {
      return null;
    }
  };
  const storeToken = authToken => {
    try {
      if (authToken) {
        sessionStorage.setItem(TOKEN_STORAGE_KEY, authToken);
      } else {
        sessionStorage.removeItem(TOKEN_STORAGE_KEY);
      }
    } catch {}
  };
  const requestAuthToken = ({appBaseUrl: requestedAppBaseUrl, authPath: requestedAuthPath, authMessageType: requestedMessageType, timeoutMs}) => new Promise(resolve => {
    const appOrigin = new URL(requestedAppBaseUrl).origin;
    const iframe = document.createElement("iframe");
    let settled = false;
    const finish = authToken => {
      if (settled) return;
      settled = true;
      window.removeEventListener("message", onMessage);
      window.clearTimeout(timeoutId);
      iframe.remove();
      resolve(authToken);
    };
    const onMessage = event => {
      if (event.origin !== appOrigin || event.source !== iframe.contentWindow) {
        return;
      }
      if (!event.data || event.data.type !== requestedMessageType) {
        return;
      }
      finish(typeof event.data.token === "string" ? event.data.token : null);
    };
    const timeoutId = window.setTimeout(() => finish(null), timeoutMs);
    window.addEventListener("message", onMessage);
    iframe.src = buildUrl(requestedAppBaseUrl, requestedAuthPath);
    iframe.title = "Acelab sign-in check";
    iframe.setAttribute("aria-hidden", "true");
    iframe.style.display = "none";
    document.body.appendChild(iframe);
  });
  const parseErrorMessage = async (response, fallback) => {
    try {
      const body = await response.json();
      return body?.message || body?.error || fallback;
    } catch {
      return fallback;
    }
  };
  const validateQuiz = quizToValidate => {
    if (!quizToValidate || !Array.isArray(quizToValidate.questions) || quizToValidate.questions.length === 0) {
      throw new Error("This quiz does not have any questions yet.");
    }
    quizToValidate.questions.forEach(question => {
      if (question.id === undefined || !question.text || !Array.isArray(question.options) || question.options.length < 2 || question.options.some(option => option.id === undefined || !option.text)) {
        throw new Error("The quiz service returned an invalid question.");
      }
    });
    return quizToValidate;
  };
  const validateSubmissionResult = submissionResult => {
    if (!submissionResult || typeof submissionResult.passed !== "boolean" || !Number.isInteger(submissionResult.score) || !Number.isInteger(submissionResult.correctAnswerCount) || !Number.isInteger(submissionResult.incorrectAnswerCount)) {
      throw new Error("The quiz service returned an invalid grading result.");
    }
    return submissionResult;
  };
  const [phase, setPhase] = useState(QUIZ_PHASES.Authenticating);
  const [quiz, setQuiz] = useState(null);
  const [answers, setAnswers] = useState({});
  const [aiaNumber, setAiaNumber] = useState("");
  const [token, setToken] = useState(null);
  const [result, setResult] = useState(null);
  const [errorMessage, setErrorMessage] = useState("");
  const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);
  const quizContainer = useRef(null);
  const authPopup = useRef(null);
  const authPopupPending = useRef(false);
  const authTokenCheckInFlight = useRef(false);
  const authQuizReloadInFlight = useRef(false);
  const scrollIntoView = () => {
    window.setTimeout(() => {
      quizContainer.current?.scrollIntoView({
        behavior: "smooth",
        block: "center"
      });
    }, 0);
  };
  const loadQuiz = async authToken => {
    if (!resolvedApiBaseUrl) {
      throw new Error("The quiz API URL has not been configured.");
    }
    const url = buildUrl(resolvedApiBaseUrl, buildContentPath(quizPath, resolvedContentIdentifier));
    const response = await fetch(url, {
      headers: {
        Accept: "application/json",
        Authorization: `Bearer ${authToken}`
      }
    });
    if (response.status === 401) {
      storeToken(null);
      setToken(null);
      setPhase(QUIZ_PHASES.Anonymous);
      return null;
    }
    if (!response.ok) {
      throw new Error(await parseErrorMessage(response, "We could not load this quiz."));
    }
    return validateQuiz(await response.json());
  };
  useEffect(() => {
    let cancelled = false;
    const initialize = async () => {
      setErrorMessage("");
      setResult(null);
      setAnswers({});
      setAiaNumber("");
      setQuiz(null);
      setCurrentQuestionIndex(0);
      if (!resolvedContentIdentifier) {
        setErrorMessage("This page is missing its quiz content identifier.");
        setPhase(QUIZ_PHASES.Error);
        return;
      }
      try {
        let authToken = readStoredToken();
        if (!authToken) {
          setPhase(QUIZ_PHASES.Authenticating);
          authToken = await requestAuthToken({
            appBaseUrl: resolvedAppBaseUrl,
            authPath,
            authMessageType,
            timeoutMs: authTimeoutMs
          });
        }
        if (cancelled) return;
        if (!authToken) {
          setPhase(QUIZ_PHASES.Anonymous);
          return;
        }
        storeToken(authToken);
        setToken(authToken);
        setPhase(QUIZ_PHASES.Loading);
        const loadedQuiz = await loadQuiz(authToken);
        if (cancelled || !loadedQuiz) return;
        setQuiz(loadedQuiz);
        setAiaNumber(loadedQuiz.aiaNumber || "");
        setPhase(QUIZ_PHASES.Ready);
      } catch (error) {
        if (cancelled) return;
        setErrorMessage(error instanceof Error ? error.message : "We could not load this quiz.");
        setPhase(QUIZ_PHASES.Error);
      }
    };
    initialize();
    return () => {
      cancelled = true;
    };
  }, [resolvedContentIdentifier, resolvedApiBaseUrl, resolvedAppBaseUrl, authPath, authMessageType, quizPath, authTimeoutMs]);
  useEffect(() => {
    let cancelled = false;
    const appOrigin = new URL(resolvedAppBaseUrl).origin;
    const loadQuizAfterAuthentication = async authToken => {
      if (!authToken || authQuizReloadInFlight.current) return;
      authQuizReloadInFlight.current = true;
      authPopupPending.current = false;
      authPopup.current = null;
      try {
        storeToken(authToken);
        setToken(authToken);
        setErrorMessage("");
        setResult(null);
        setAnswers({});
        setAiaNumber("");
        setQuiz(null);
        setCurrentQuestionIndex(0);
        setPhase(QUIZ_PHASES.Loading);
        const loadedQuiz = await loadQuiz(authToken);
        if (cancelled || !loadedQuiz) return;
        setQuiz(loadedQuiz);
        setAiaNumber(loadedQuiz.aiaNumber || "");
        setPhase(QUIZ_PHASES.Ready);
      } catch (error) {
        if (cancelled) return;
        setErrorMessage(error instanceof Error ? error.message : "We could not load this quiz.");
        setPhase(QUIZ_PHASES.Error);
      } finally {
        authQuizReloadInFlight.current = false;
      }
    };
    const onAuthMessage = event => {
      if (event.origin !== appOrigin || event.source !== authPopup.current || !event.data || event.data.type !== authMessageType) {
        return;
      }
      const authToken = typeof event.data.token === "string" ? event.data.token : null;
      if (!authToken) {
        authPopupPending.current = false;
        authPopup.current = null;
        storeToken(null);
        setToken(null);
        setPhase(QUIZ_PHASES.Anonymous);
        return;
      }
      loadQuizAfterAuthentication(authToken);
    };
    const recheckAuthAfterPopup = async () => {
      if (!authPopupPending.current || authTokenCheckInFlight.current || authQuizReloadInFlight.current) {
        return;
      }
      authTokenCheckInFlight.current = true;
      try {
        const authToken = await requestAuthToken({
          appBaseUrl: resolvedAppBaseUrl,
          authPath,
          authMessageType,
          timeoutMs: authTimeoutMs
        });
        if (cancelled || !authPopupPending.current || authQuizReloadInFlight.current) {
          return;
        }
        if (authToken) {
          await loadQuizAfterAuthentication(authToken);
        } else {
          if (!authPopup.current || authPopup.current.closed) {
            authPopupPending.current = false;
            authPopup.current = null;
          }
          setPhase(QUIZ_PHASES.Anonymous);
        }
      } catch (error) {
        if (cancelled) return;
        setErrorMessage(error instanceof Error ? error.message : "We could not check your Acelab sign-in.");
        setPhase(QUIZ_PHASES.Error);
      } finally {
        authTokenCheckInFlight.current = false;
      }
    };
    const onWindowFocus = () => {
      recheckAuthAfterPopup();
    };
    const onVisibilityChange = () => {
      if (document.visibilityState === "visible") {
        recheckAuthAfterPopup();
      }
    };
    window.addEventListener("message", onAuthMessage);
    window.addEventListener("focus", onWindowFocus);
    document.addEventListener("visibilitychange", onVisibilityChange);
    return () => {
      cancelled = true;
      window.removeEventListener("message", onAuthMessage);
      window.removeEventListener("focus", onWindowFocus);
      document.removeEventListener("visibilitychange", onVisibilityChange);
    };
  }, [resolvedApiBaseUrl, authMessageType, authPath, authTimeoutMs, resolvedContentIdentifier, quizPath, resolvedAppBaseUrl]);
  const setAnswer = (questionId, optionId) => {
    setAnswers(current => ({
      ...current,
      [questionId]: optionId
    }));
  };
  const allQuestionsAnswered = quiz?.questions.every(question => answers[question.id] !== undefined) || false;
  const currentQuestion = quiz?.questions[currentQuestionIndex] || null;
  const currentQuestionAnswered = currentQuestion && answers[currentQuestion.id] !== undefined;
  const isLastQuestion = quiz && currentQuestionIndex === quiz.questions.length - 1;
  const showQuestion = questionIndex => {
    setCurrentQuestionIndex(questionIndex);
    scrollIntoView();
  };
  const previousQuestion = () => {
    if (currentQuestionIndex > 0) {
      showQuestion(currentQuestionIndex - 1);
    }
  };
  const nextQuestion = () => {
    if (currentQuestionAnswered && quiz && currentQuestionIndex < quiz.questions.length - 1) {
      showQuestion(currentQuestionIndex + 1);
    }
  };
  const submit = async event => {
    event.preventDefault();
    if (!quiz || !token || !allQuestionsAnswered) return;
    setErrorMessage("");
    setPhase(QUIZ_PHASES.Submitting);
    try {
      const url = buildUrl(resolvedApiBaseUrl, buildContentPath(submissionPath, resolvedContentIdentifier));
      const response = await fetch(url, {
        method: "POST",
        headers: {
          Accept: "application/json",
          Authorization: `Bearer ${token}`,
          "Content-Type": "application/json"
        },
        body: JSON.stringify({
          aiaNumber,
          answers: quiz.questions.map(question => ({
            questionId: question.id,
            optionId: answers[question.id]
          }))
        })
      });
      if (response.status === 401) {
        storeToken(null);
        setToken(null);
        setPhase(QUIZ_PHASES.Anonymous);
        return;
      }
      if (!response.ok) {
        throw new Error(await parseErrorMessage(response, "We could not submit your answers. Please try again."));
      }
      const submissionResult = validateSubmissionResult(await response.json());
      setResult(submissionResult);
      setPhase(submissionResult.passed ? QUIZ_PHASES.Passed : QUIZ_PHASES.Failed);
      scrollIntoView();
    } catch (error) {
      setErrorMessage(error instanceof Error ? error.message : "We could not submit your answers. Please try again.");
      setPhase(QUIZ_PHASES.Ready);
      scrollIntoView();
    }
  };
  const retry = () => {
    setResult(null);
    setErrorMessage("");
    setPhase(QUIZ_PHASES.Ready);
    scrollIntoView();
  };
  const takeAgain = () => {
    setAnswers({});
    setCurrentQuestionIndex(0);
    retry();
  };
  const popupAuthPath = `${authPath}${authPath.includes("?") ? "&" : "?"}popup=1`;
  const loginUrl = typeof window === "undefined" ? buildUrl(resolvedAppBaseUrl, "/login") : `${buildUrl(resolvedAppBaseUrl, "/login")}?redirect=${encodeURIComponent(window.location.href)}`;
  const signupUrl = typeof window === "undefined" ? buildUrl(resolvedAppBaseUrl, "/signup") : `${buildUrl(resolvedAppBaseUrl, "/signup")}?redirect=${encodeURIComponent(window.location.href)}`;
  const popupLoginUrl = `${buildUrl(resolvedAppBaseUrl, "/docs-login")}?redirect=${encodeURIComponent(popupAuthPath)}`;
  const openAuthPopup = (event, popupUrl) => {
    event.preventDefault();
    const popup = window.open(popupUrl, "acelab-docs-auth");
    if (!popup) {
      setErrorMessage("Your browser blocked the sign-in tab. Allow pop-ups for this site and try again.");
      setPhase(QUIZ_PHASES.Anonymous);
      return;
    }
    authPopup.current = popup;
    authPopupPending.current = true;
    setErrorMessage("");
    setPhase(QUIZ_PHASES.Authenticating);
    popup.focus();
  };
  const isBusy = phase === QUIZ_PHASES.Authenticating || phase === QUIZ_PHASES.Loading || phase === QUIZ_PHASES.Submitting;
  const resultQuestionCount = result ? result.correctAnswerCount + result.incorrectAnswerCount : 0;
  return <section ref={quizContainer} id={`quiz-${resolvedContentIdentifier || "unconfigured"}`} className="not-prose mt-10 rounded-xl border border-zinc-200 bg-zinc-50 px-5 py-8 text-zinc-950 dark:border-zinc-800 dark:bg-zinc-900 dark:text-white lg:px-10" aria-labelledby={`quiz-${resolvedContentIdentifier || "unconfigured"}-title`}>
      <div className="border-b border-zinc-200 pb-6 dark:border-zinc-800">
        <h2 id={`quiz-${resolvedContentIdentifier || "unconfigured"}-title`} className="m-0 text-3xl font-semibold">
          Take the Quiz
        </h2>
        <p className="mb-0 mt-3 text-zinc-600 dark:text-zinc-300">
          You can take the quiz as many times as you would like.
        </p>
      </div>

      <div className="pt-8" aria-live="polite" aria-busy={isBusy}>
        {(phase === QUIZ_PHASES.Authenticating || phase === QUIZ_PHASES.Loading) && <p className="m-0 text-zinc-600 dark:text-zinc-300">
            {phase === QUIZ_PHASES.Authenticating ? "Checking your Acelab sign-in..." : "Loading quiz..."}
          </p>}

        {phase === QUIZ_PHASES.Anonymous && <div>
            <p className="mt-0">
              Sign in or create an account to take the quiz.
            </p>
            {errorMessage && <p className="mt-3 text-red-700 dark:text-red-300" role="alert">
                {errorMessage}
              </p>}
            <div className="mt-4 flex flex-wrap gap-3">
              <a href={loginUrl} onClick={event => openAuthPopup(event, popupLoginUrl)} className="rounded-lg bg-emerald-600 px-5 py-3 font-medium text-white no-underline hover:bg-emerald-700">
                Sign in
              </a>
              <a href={signupUrl} className="rounded-lg border border-zinc-300 px-5 py-3 font-medium text-zinc-950 no-underline hover:bg-zinc-100 dark:border-zinc-700 dark:text-white dark:hover:bg-zinc-800">
                Create account
              </a>
            </div>
          </div>}

        {phase === QUIZ_PHASES.Error && <div role="alert">
            <p className="mt-0 font-semibold">Unable to load the quiz!</p>
            <p className="ml-1 mb-0 text-zinc-600 dark:text-zinc-300">
              Try refreshing the page! {errorMessage}
            </p>
          </div>}

        {phase === QUIZ_PHASES.Passed && <div className="flex flex-col items-center text-center">
            <p className="m-0 text-2xl font-semibold">Congratulations!</p>
            <p className="mb-0 mt-3 max-w-lg">
              You answered {result?.correctAnswerCount ?? 0} of{" "}
              {resultQuestionCount} questions correctly and passed with a score
              of {result?.score ?? 0}%.
            </p>
            <p className="mb-0 mt-3 max-w-lg text-zinc-600 dark:text-zinc-300">
              Your continuing education certificate will be emailed to you
              shortly.
            </p>
            <button type="button" className="mt-5 border-0 bg-transparent font-semibold text-emerald-700 underline hover:no-underline dark:text-emerald-400" onClick={takeAgain}>
              Take Quiz Again
            </button>
          </div>}

        {phase === QUIZ_PHASES.Failed && <div className="flex flex-col items-center text-center">
            <p className="m-0 text-2xl font-semibold">Oops!</p>
            <p className="mb-0 mt-3 max-w-md">
              You answered {result?.correctAnswerCount ?? 0} of{" "}
              {resultQuestionCount} questions correctly and scored{" "}
              {result?.score ?? 0}%.
            </p>
            <button type="button" className="mt-5 rounded-lg bg-emerald-600 px-8 py-3 font-semibold text-white hover:bg-emerald-700" onClick={takeAgain}>
              Try Again
            </button>
          </div>}

        {(phase === QUIZ_PHASES.Ready || phase === QUIZ_PHASES.Submitting) && quiz && currentQuestion && <form onSubmit={submit}>
              {errorMessage && <div role="alert" className="mb-6 rounded-lg border border-red-300 bg-red-50 px-4 py-3 text-red-900 dark:border-red-900 dark:bg-red-950 dark:text-red-100">
                  {errorMessage}
                </div>}

              <div className="mb-8">
                <div className="mb-2 text-sm font-medium text-zinc-600 dark:text-zinc-300">
                  <span>
                    Question {currentQuestionIndex + 1} of{" "}
                    {quiz.questions.length}
                  </span>
                </div>
                <div role="progressbar" aria-label="Quiz progress" aria-valuemin={1} aria-valuemax={quiz.questions.length} aria-valuenow={currentQuestionIndex + 1} className="h-2 overflow-hidden rounded-full bg-zinc-200 dark:bg-zinc-700">
                  <div className="h-full rounded-full bg-emerald-500 transition-all duration-300" style={{
    width: `${(currentQuestionIndex + 1) / quiz.questions.length * 100}%`
  }} />
                </div>
              </div>

              <fieldset key={currentQuestion.id} className="m-0 border-0 p-0">
                <legend className="mb-6 flex items-start gap-3 text-lg font-medium">
                  <span className="flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-emerald-500 font-bold text-white">
                    {currentQuestionIndex + 1}
                  </span>
                  <span>{currentQuestion.text}</span>
                </legend>

                <div className="space-y-3 pl-12">
                  {currentQuestion.options.map((option, optionIndex) => {
    const inputId = `quiz-${resolvedContentIdentifier}-${currentQuestion.id}-${option.id}`;
    const selected = answers[currentQuestion.id] === option.id;
    return <label key={option.id} htmlFor={inputId} className={`flex cursor-pointer items-start gap-3 rounded-lg border px-4 py-3 transition-colors ${selected ? "border-emerald-500 bg-emerald-50 font-medium dark:bg-emerald-950" : "border-zinc-200 bg-white hover:border-zinc-400 dark:border-zinc-700 dark:bg-zinc-950 dark:hover:border-zinc-500"}`}>
                        <input id={inputId} type="radio" name={`quiz-question-${currentQuestion.id}`} value={option.id} checked={selected} required={optionIndex === 0} disabled={phase === QUIZ_PHASES.Submitting} className="mt-1 h-4 w-4 accent-emerald-600" onChange={() => setAnswer(currentQuestion.id, option.id)} />
                        <span>{option.text}</span>
                      </label>;
  })}
                </div>
              </fieldset>

              {isLastQuestion && <div className="mt-8 border-t border-zinc-200 pt-6 dark:border-zinc-800">
                  <label htmlFor={`quiz-${resolvedContentIdentifier}-aia-number`} className="block text-sm font-semibold">
                    AIA Number (optional)
                  </label>
                  <input id={`quiz-${resolvedContentIdentifier}-aia-number`} type="text" value={aiaNumber} maxLength={100} disabled={phase === QUIZ_PHASES.Submitting} className="mt-2 w-full rounded-lg border border-zinc-300 bg-white px-4 py-3 text-zinc-950 outline-none focus:border-emerald-500 focus:ring-2 focus:ring-emerald-500/20 disabled:cursor-not-allowed disabled:opacity-50 dark:border-zinc-700 dark:bg-zinc-950 dark:text-white" onChange={event => setAiaNumber(event.target.value)} />
                  <p className="mb-0 mt-2 text-sm text-zinc-600 dark:text-zinc-300">
                    This number will be saved to your Acelab profile and used
                    for your continuing education certificate.
                  </p>
                </div>}

              <div className="flex items-center pt-8 justify-between gap-4 border-zinc-200 dark:border-zinc-800">
                {currentQuestionIndex > 0 ? <button type="button" disabled={phase === QUIZ_PHASES.Submitting} className="rounded-lg border border-gray-200 bg-background-light px-6 py-2 font-medium text-gray-700 hover:bg-gray-600/5 disabled:cursor-not-allowed disabled:opacity-50 dark:border-white/[0.07] dark:bg-background-dark dark:text-gray-300 dark:hover:bg-gray-200/5" onClick={previousQuestion}>
                    Back
                  </button> : <span />}

                {isLastQuestion ? <button type="submit" disabled={phase === QUIZ_PHASES.Submitting || !allQuestionsAnswered} className="rounded-lg border border-gray-200 bg-background-light px-6 py-2 font-medium text-gray-700 hover:bg-gray-600/5 disabled:cursor-not-allowed disabled:opacity-50 dark:border-white/[0.07] dark:bg-background-dark dark:text-gray-300 dark:hover:bg-gray-200/5">
                    {phase === QUIZ_PHASES.Submitting ? "Submitting..." : "Submit your answers"}
                  </button> : <button type="button" disabled={!currentQuestionAnswered} className="rounded-lg border border-gray-200 bg-background-light px-6 py-2 font-medium text-gray-700 hover:bg-gray-600/5 disabled:cursor-not-allowed disabled:opacity-50 dark:border-white/[0.07] dark:bg-background-dark dark:text-gray-300 dark:hover:bg-gray-200/5" onClick={nextQuestion}>
                    Next
                  </button>}
              </div>
            </form>}
      </div>
    </section>;
};

## Introduction

As much as we talk about sustainability in architectural design, we often miss some important context. The three most important enclosure-related factors influencing how much energy a building will consume are, in order: glazing ratio (how much glass is on the building and how good is the glass?), air tightness (how well have we separated the inside from the outside?) and insulation (how much insulation are we using and is it continuous?). This list is not intuitive for a lot of professionals, and in prioritizing design decisions it helps to understand these relationships better, including differences between commercial and residential buildings and where we are as an industry.

<AiaCourseEligibility creditType="HSW" />

**About Building Science Fight Club**

<BuildingScienceFightClubAbout />

## Video: The Three Most Important Design Considerations for Energy Efficiency

<iframe className="w-full aspect-video rounded-xl" src="https://www.youtube.com/embed/jzBXn9iH3P8" title="The Three Most Important Design Considerations for Energy Efficiency | BSFC | AIA" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen />

## Quiz

To earn AIA Continuing Education Units (CEU), you must complete the quiz below and get all 3 questions correctly. Feel free to retake the quiz if needed.

<Quiz />

To keep learning, check out more courses in [Building Science](/resources/building-science-ceu).
