@charset "UTF-8";
/* ==========================================================================
   Main SCSS entrypoint

   Browser note:
   - Browsers do not read SCSS directly.
   - This file compiles to static/css/main.css.

   Structure:
   - base: tokens, reset, and utilities
   - layout: shared page-level layout
   - pages: page-specific shared patterns
   - components: reusable UI components
  ========================================================================== */
/* ==========================================================================
   base/_tokens.scss
   Global design tokens exposed as CSS custom properties.

   Design tokens are named values for repeated design decisions:
   colors, spacing, typography, layout, radii, and shadows.

   CS50W concept:
   - CSS custom properties store reusable values.
   - They reduce repetition and make future theming easier.
   ========================================================================== */
:root {
  /* Color tokens */
  --color-bg: #ffffff;
  --color-surface: #f8fafc;
  --color-surface-raised: #ffffff;
  --color-text: #111827;
  --color-muted: #6b7280;
  --color-border: #e5e7eb;
  --color-primary: #2563eb;
  --color-primary-hover: #1d4ed8;
  --color-link: var(--color-primary);
  --color-link-hover: var(--color-primary-hover);
  --color-focus: var(--color-primary);
  --color-success: #22c55e;
  --color-error: #b91c1c;
  --color-error-surface: #fef2f2;
  /* Spacing tokens */
  --space-1: 0.25rem; /* 4px */
  --space-2: 0.5rem; /* 8px */
  --space-3: 0.75rem; /* 12px */
  --space-4: 1rem; /* 16px */
  --space-5: 1.5rem; /* 24px */
  --space-6: 2rem; /* 32px */
  --space-7: 3rem; /* 48px */
  --space-8: 4rem; /* 64px */
  /* Typography tokens */
  --font-sans: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
  --font-weight-normal: 400;
  --font-weight-medium: 500;
  --font-weight-bold: 700;
  --font-weight-extrabold: 800;
  --text-xs: 0.75rem; /* 12px */
  --text-sm: 0.875rem; /* 14px */
  --text-base: 1rem; /* 16px */
  --text-lg: 1.125rem; /* 18px */
  --text-xl: 1.25rem; /* 20px */
  --text-2xl: 1.5rem; /* 24px */
  --text-3xl: clamp(2rem, 4vw, 3rem);
  --leading-none: 1;
  --leading-tight: 1.2;
  --leading-normal: 1.6;
  --leading-relaxed: 1.7;
  --tracking-tight: -0.02em;
  --measure: 65ch;
  /* Layout tokens */
  --container-narrow: 48rem;
  --container-width: 72rem;
  --site-logo-max-height: 2.25rem;
  /* Radius tokens */
  --radius-sm: 0.375rem;
  --radius-md: 0.75rem;
  --radius-lg: 1.25rem;
  --radius-full: 999px;
  /* Shadow tokens */
  --shadow-soft: 0 1rem 2.5rem rgb(15 23 42 / 0.08);
  /* Focus tokens */
  --ring-color: var(--color-focus);
  --ring-offset: 2px;
  --ring-width: 2px;
}

/* ==========================================================================
  base/reset.scss
  Minimal global reset and default element behavior.

  CS50W concept:
  - Browsers apply default styles.
  - A reset gives us a predictable starting point.
  ========================================================================== */
/*
  Use border-box sizing everywhere.

  This makes width and height calculations easier because padding and border
  are included inside the declared element size.
*/
*,
*::before,
*::after {
  box-sizing: border-box;
}

/*
  Prevent unwanted text resizing behavior on mobile WebKit browsers while
  preserving normal user zoom support.
*/
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

/*
  Remove the browser's default body margin so the layout starts from the
  viewport edge and spacing can be controlled intentionally.
*/
body {
  margin: 0;
}

/*
  Make media elements behave like responsive blocks by default.

  display: block removes inline spacing quirks.
  max-width: 100% prevents media from overflowing its container.
*/
img,
picture,
svg {
  display: block;
  max-width: 100%;
}

/*
  Preserve image aspect ratio when images are scaled down responsively.
*/
img {
  height: auto;
}

/*
  Make form controls inherit the site's typography instead of using
  browser-specific default fonts.
*/
button,
input,
textarea,
select {
  font: inherit;
}

/* ==========================================================================
    base/typography.scss
    Document-level text defaults and link styling.
   ========================================================================== */
/*
  Keep the root font size tied to the user's browser preference.
  Setting 100% means 1rem follows the browser default, usually 16px,
  instead of forcing a fixed pixel size.
*/
html {
  font-size: 100%;
  background: var(--color-bg);
}

/*
  Define the default document text style.
  The 100vh fallback supports older browsers.
  The 100dvh value improves mobile viewport behavior where browser toolbars
  can change the visible height.
*/
body {
  min-height: 100vh;
  min-height: 100dvh;
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: var(--leading-normal);
  color: var(--color-text);
  background: var(--color-bg);
}

/*
  Establish the default top-level heading style.
  text-wrap: balance is a safe progressive enhancement: browsers that support
  it create better headline line breaks; others ignore it.
*/
h1 {
  margin: 0;
  font-size: var(--text-2xl);
  font-weight: var(--font-weight-bold);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  text-wrap: balance;
}

/*
  Keep links visibly recognizable as links.
  The underline uses native text-decoration properties instead of borders,
  so it follows the text more naturally.
*/
a {
  color: var(--color-link);
  text-decoration: underline;
  text-decoration-thickness: 0.08em;
  text-underline-offset: 0.18em;
}

/*
  Give links consistent visual feedback for pointer and keyboard users.
  The actual focus outline is handled globally in base/accessibility.scss.
*/
a:hover,
a:focus-visible {
  color: var(--color-link-hover);
}

/* ==========================================================================
  base/utilities.scss
  Small reusable utility classes.

  CS50W concept:
  - Utility classes solve common layout/accessibility needs.
  - They should be simple and reusable.
   ========================================================================== */
/*
  Center content and keep it readable on wide screens.

  The width calculation keeps a one-token gutter on each side for narrow
  screens, then caps the container at the global max-width token.
*/
.container {
  width: min(100% - var(--space-4) * 2, var(--container-width));
  margin-inline: auto;
}

/* ==========================================================================
    base/accessibility.scss
    Shared accessibility helpers and motion preferences.
   ========================================================================== */
/*
  Provide a visible keyboard focus indicator across the site.
  Component-level focus styles may add extra polish, but this global outline
  ensures keyboard users can always see where focus is.
*/
:focus-visible {
  outline: var(--ring-width) solid var(--ring-color);
  outline-offset: var(--ring-offset);
}

/*
  Visually hide content while keeping it available to screen readers.
  Useful for helper text such as "Menu" inside an icon-only button.
*/
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  white-space: nowrap;
  border: 0;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
}

/*
  Skip link for keyboard users.
  It stays off-screen by default and becomes visible when focused, allowing
  users to jump directly to the main content. Place the skip link near the
  start of the document, before the main navigation.
*/
.skip-link {
  position: absolute;
  inset-block-start: var(--space-4);
  inset-inline-start: var(--space-4);
  z-index: 100;
  transform: translateY(-150%);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--color-bg);
  background: var(--color-text);
}

.skip-link:focus {
  position: fixed;
  transform: translateY(0);
  box-shadow: var(--shadow-soft);
}

/*
  Smooth in-page navigation for users who have not requested reduced motion.
*/
html:focus-within {
  scroll-behavior: smooth;
}

/*
  Respect reduced-motion preferences.
  The !important flags are intentional because this rule should override
  component-level animations and transitions.
*/
@media (prefers-reduced-motion: reduce) {
  html:focus-within {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
    scroll-behavior: auto !important;
  }
}
/* ==========================================================================
    layout/main.scss
    Shared page-level layout.
    CS50W concept:
    - base.html provides the document skeleton.
    - .site-main controls the shared main content area.
   ========================================================================== */
/*
  Provide consistent vertical spacing around the main content area.
  The default spacing is mobile-first. Larger screens get more breathing
  room when there is enough viewport space.
*/
.site-main {
  width: min(100% - var(--space-4) * 2, var(--container-width));
  margin-inline: auto;
  padding-block: var(--space-6);
}

/*
  Hide the main landmark outline for pointer/programmatic focus only.
  Keyboard-visible focus remains protected by :focus-visible from the global
  accessibility styles.
*/
.site-main:focus:not(:focus-visible) {
  outline: none;
}

@media (min-width: 48rem) {
  .site-main {
    padding-block: var(--space-7);
  }
}
@media (min-width: 64rem) {
  .site-main {
    padding-block: var(--space-8);
  }
}
/* ==========================================================================
    layout/main.scss
    Shared page-level layout.
    CS50W concept:
    - base.html provides the document skeleton.
    - .site-main controls the shared main content area.
   ========================================================================== */
/* ==========================================================================
  pages/_page.scss
  Shared page wrapper and article spacing for static content pages.

  This file owns simple page styles and the temporary v0.2 homepage styles.
  It stays intentionally small until the homepage grows enough to justify
  separate section partials or config-driven rendering.
  ========================================================================== */
/* ==========================================================================
    layout/main.scss
    Shared page-level layout.
    CS50W concept:
    - base.html provides the document skeleton.
    - .site-main controls the shared main content area.
   ========================================================================== */
/* ==========================================================================
  pages/_project-detail.scss
  Project detail case-study page.

  This uses the existing Project model fields while giving real project content
  a more intentional reading structure than the generic static page wrapper.
  ========================================================================== */
.project-detail {
  display: grid;
  gap: var(--space-6);
}

.project-detail__hero {
  display: grid;
  gap: var(--space-5);
  min-width: 0;
}

.project-detail__intro {
  display: grid;
  gap: var(--space-3);
  max-width: var(--measure);
}

.project-detail__eyebrow {
  margin: 0;
  color: var(--color-muted);
  font-size: var(--text-sm);
  font-weight: var(--font-weight-medium);
  line-height: var(--leading-tight);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.project-detail__title {
  max-width: min(100%, 24ch);
  margin: 0;
  font-size: var(--text-3xl);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
}

.project-detail__summary {
  max-width: var(--measure);
  margin: 0;
  color: var(--color-muted);
  font-size: var(--text-lg);
  line-height: var(--leading-relaxed);
}

.project-detail__media {
  aspect-ratio: 16/9;
  overflow: hidden;
  width: 100%;
  margin: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-raised);
  box-shadow: var(--shadow-soft);
}

.project-detail__image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.project-detail__media-placeholder {
  width: 100%;
  height: 100%;
  background: linear-gradient(135deg, transparent 0 48%, var(--color-border) 48% 52%, transparent 52%), var(--color-surface-raised);
}

.project-detail__media-wrapper {
  display: grid;
  gap: var(--space-3);
  min-width: 0;
}

.project-detail__media-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.project-detail__media-action {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-link);
  font-size: var(--text-sm);
  font-weight: var(--font-weight-medium);
  text-decoration: none;
}

.project-detail__media-action:hover,
.project-detail__media-action:focus-visible {
  color: var(--color-link-hover);
  text-decoration: underline;
  text-underline-offset: 0.18em;
}

.project-detail__layout {
  display: grid;
  gap: var(--space-6);
  min-width: 0;
}

.project-detail__meta {
  display: grid;
  gap: var(--space-4);
  min-width: 0;
  padding: var(--space-5);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}

.project-detail__meta-title {
  margin: 0;
  font-size: var(--text-xl);
  line-height: var(--leading-tight);
}

.project-detail__meta-list {
  display: grid;
  gap: var(--space-4);
  margin: 0;
}

.project-detail__meta-item {
  display: grid;
  gap: var(--space-2);
  min-width: 0;
}

.project-detail__meta-label {
  color: var(--color-muted);
  font-size: var(--text-xs);
  font-weight: var(--font-weight-medium);
  line-height: var(--leading-tight);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.project-detail__meta-value {
  min-width: 0;
  margin: 0;
  color: var(--color-muted);
  line-height: var(--leading-relaxed);
}

.project-detail__technologies {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.project-detail__technology {
  max-width: 100%;
  overflow-wrap: anywhere;
  padding: var(--space-1) var(--space-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  background: var(--color-surface-raised);
  font-size: var(--text-sm);
  line-height: var(--leading-normal);
}

.project-detail__narrative {
  display: grid;
  gap: var(--space-6);
  min-width: 0;
  max-width: var(--measure);
}

.project-detail__sections {
  display: grid;
  gap: var(--space-6);
  max-width: var(--measure);
}

.project-detail__section {
  display: grid;
  gap: var(--space-3);
  padding-block-start: var(--space-5);
  border-block-start: 1px solid var(--color-border);
}

.project-detail__section--overview {
  padding-block-start: var(--space-2);
}

.project-detail__section--outcome {
  padding: var(--space-5);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}

.project-detail__section--lessons {
  padding-block: var(--space-5);
  border-block: 1px solid var(--color-border);
}

.project-detail__section-title {
  margin: 0;
  font-size: var(--text-xl);
  line-height: var(--leading-tight);
}

.project-detail__section-text {
  display: grid;
  gap: var(--space-3);
  margin: 0;
  color: var(--color-muted);
  font-size: var(--text-base);
  line-height: var(--leading-relaxed);
}

.project-detail__section-text--lead {
  gap: var(--space-4);
  font-size: var(--text-lg);
}

.project-detail__section-text > p {
  margin: 0;
}

.project-detail__footer-nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3);
  padding-block-start: var(--space-5);
  border-block-start: 1px solid var(--color-border);
}

.project-detail__footer-nav > a {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 2.75rem;
  color: var(--color-link);
  font-weight: var(--font-weight-medium);
  text-decoration: none;
}

.project-detail__footer-nav > a:hover,
.project-detail__footer-nav > a:focus-visible {
  color: var(--color-link-hover);
  text-decoration: underline;
  text-underline-offset: 0.18em;
}

@media (min-width: 48rem) {
  .project-detail {
    gap: var(--space-7);
  }
  .project-detail__intro {
    max-width: none;
  }
  .project-detail__title {
    max-width: min(100%, 26ch);
  }
  .project-detail__meta-list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-6);
  }
  .project-detail__narrative {
    gap: var(--space-7);
  }
}
@media (min-width: 64rem) {
  .project-detail {
    gap: var(--space-8);
  }
  .project-detail__hero {
    gap: var(--space-6);
  }
  .project-detail__media-wrapper {
    max-width: min(100%, 64rem);
  }
  .project-detail__layout {
    grid-template-columns: minmax(0, var(--measure)) minmax(16rem, 20rem);
    column-gap: var(--space-8);
    align-items: start;
    justify-content: space-between;
  }
  .project-detail__meta {
    grid-column: 2;
    grid-row: 1;
  }
  .project-detail__meta-list {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-4);
  }
  .project-detail__narrative {
    grid-column: 1;
    grid-row: 1;
  }
}
/* Simple static pages: About, Contact, Privacy, Terms, Cookies. */
.page {
  --page-content-max-width: var(--measure);
  display: grid;
  gap: var(--space-5);
}

/*
  Keep long-form text readable.

  max-width uses the global reading measure so lines do not become too wide
  on large screens.
*/
.page__article {
  display: grid;
  gap: var(--space-4);
  max-width: var(--page-content-max-width);
}

/* Limit very short page titles so they feel intentional, not stretched. */
.page__article > h1 {
  max-width: 14ch;
  font-size: var(--text-3xl);
  line-height: var(--leading-tight);
  letter-spacing: 0;
}

/*
  Style only direct paragraphs.

  This avoids accidentally restyling paragraphs inside future nested
  components such as cards, alerts, forms, or rich content blocks.
*/
.page__article > p {
  margin: 0;
  font-size: var(--text-lg);
  line-height: var(--leading-relaxed);
  color: var(--color-muted);
}

/*
  Contact form workflow.

  Source order stays introductory context, inquiry guidance, then the form.
  Larger viewports use that same order in a restrained two-column composition.
*/
.contact-page {
  display: grid;
  max-width: var(--container-width);
}

.contact-page__layout,
.contact-page__context,
.contact-page__intro,
.contact-page__inquiries,
.contact-page__form-panel {
  display: grid;
}

.contact-page__layout {
  gap: var(--space-7);
}

.contact-page__context {
  align-content: start;
  gap: var(--space-6);
  max-width: var(--measure);
}

.contact-page__intro {
  display: grid;
  gap: var(--space-3);
}

.contact-page__eyebrow {
  margin: 0;
  color: var(--color-muted);
  font-size: var(--text-sm);
  font-weight: var(--font-weight-medium);
  line-height: var(--leading-tight);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.contact-page__title {
  max-width: 14ch;
  margin: 0;
  font-size: var(--text-3xl);
  line-height: var(--leading-tight);
  letter-spacing: 0;
}

.contact-page__lead {
  margin: 0;
  color: var(--color-muted);
  font-size: var(--text-lg);
  line-height: var(--leading-relaxed);
}

.contact-page__inquiries {
  gap: var(--space-3);
  padding-block-start: var(--space-4);
  border-block-start: 1px solid var(--color-border);
}

.contact-page__section-title {
  margin: 0;
  font-size: var(--text-xl);
  line-height: var(--leading-tight);
}

.contact-page__inquiry-list {
  display: grid;
  gap: var(--space-2);
  margin: 0;
  padding-inline-start: var(--space-5);
  color: var(--color-muted);
  line-height: var(--leading-relaxed);
}

.contact-page__inquiry-list > li {
  padding-inline-start: var(--space-1);
}

.contact-page__form-panel {
  gap: var(--space-5);
  min-width: 0;
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-raised);
  box-shadow: var(--shadow-soft);
}

.contact-form {
  display: grid;
  gap: var(--space-5);
  min-width: 0;
}

.contact-form__required-note,
.contact-form__privacy {
  margin: 0;
  color: var(--color-muted);
  font-size: var(--text-sm);
  line-height: var(--leading-normal);
}

.contact-form__field {
  display: grid;
  gap: var(--space-2);
}

.contact-form__label {
  font-weight: var(--font-weight-medium);
  line-height: var(--leading-tight);
}

.contact-form__required {
  color: var(--color-muted);
  font-size: var(--text-sm);
  font-weight: var(--font-weight-normal);
}

.contact-form__control {
  width: 100%;
  min-height: 2.75rem;
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  color: var(--color-text);
  background: var(--color-surface-raised);
  line-height: var(--leading-normal);
}

.contact-form__control--textarea {
  min-height: 12rem;
  resize: vertical;
}

.contact-form__control:hover {
  border-color: var(--color-muted);
}

.contact-form__control:focus-visible {
  outline: var(--ring-width) solid var(--ring-color);
  outline-offset: var(--ring-offset);
  border-color: var(--color-focus);
}

.contact-form__control[aria-invalid=true] {
  border-color: var(--color-error);
}

.contact-form__help,
.contact-form__errors {
  margin: 0;
  font-size: var(--text-sm);
  line-height: var(--leading-normal);
}

.contact-form__help {
  color: var(--color-muted);
}

.contact-form__errors {
  padding-inline-start: var(--space-5);
  color: var(--color-error);
}

.contact-form__error-summary {
  display: grid;
  gap: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--color-error);
  border-radius: var(--radius-sm);
  color: var(--color-text);
  background: var(--color-error-surface);
}

.contact-form__error-summary > h3,
.contact-form__error-summary > ul {
  margin: 0;
}

.contact-form__error-summary > h3 {
  font-size: var(--text-lg);
  line-height: var(--leading-tight);
}

.contact-form__error-summary a {
  color: var(--color-error);
}

.contact-form__actions,
.contact-page__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

.contact-form__submit {
  cursor: pointer;
}

/*
  Project list page.

  The list page uses project-specific composition while each project summary
  remains an ordinary reusable card.
*/
.projects-page {
  display: grid;
  gap: var(--space-7);
}
.projects-page__header {
  display: grid;
  gap: var(--space-3);
  max-width: var(--measure);
}
.projects-page__eyebrow, .projects-page__empty-kicker {
  margin: 0;
  color: var(--color-muted);
  font-size: var(--text-sm);
  font-weight: var(--font-weight-medium);
  line-height: var(--leading-tight);
  text-transform: uppercase;
  letter-spacing: 0;
}
.projects-page__title {
  max-width: 13ch;
  margin: 0;
  font-size: var(--text-3xl);
  line-height: var(--leading-tight);
  letter-spacing: 0;
}
.projects-page__lead {
  max-width: var(--measure);
  margin: 0;
  color: var(--color-muted);
  font-size: var(--text-lg);
  line-height: var(--leading-relaxed);
}
.projects-page {
  /* One-column grid by default; larger screens add columns only when useful. */
}
.projects-page__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));
  gap: var(--space-5);
}
.projects-page__card {
  grid-template-rows: auto 1fr;
  gap: 0;
  align-content: start;
  min-width: 0;
  overflow: hidden;
  padding: 0;
  border-radius: var(--radius-md);
  background: var(--color-surface-raised);
  box-shadow: var(--shadow-soft);
}
.projects-page__card-media {
  aspect-ratio: 16/9;
  overflow: hidden;
  border-block-end: 1px solid var(--color-border);
  background: var(--color-surface);
}
.projects-page__card-image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.projects-page__card-media-placeholder {
  width: 100%;
  height: 100%;
  background: linear-gradient(135deg, transparent 0 48%, var(--color-border) 48% 52%, transparent 52%), var(--color-surface-raised);
}
.projects-page__card-body {
  display: grid;
  grid-template-rows: auto auto 1fr auto;
  gap: var(--space-3);
  min-width: 0;
  padding: var(--space-5);
}
.projects-page__card-meta {
  margin: 0;
  color: var(--color-muted);
  font-size: var(--text-xs);
  font-weight: var(--font-weight-medium);
  line-height: var(--leading-tight);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.projects-page__card-title {
  font-size: var(--text-xl);
  letter-spacing: var(--tracking-tight);
}
.projects-page__card-title > a {
  color: inherit;
  text-decoration: none;
}
.projects-page__card-title > a:hover, .projects-page__card-title > a:focus-visible {
  color: var(--color-link-hover);
  text-decoration: underline;
  text-underline-offset: 0.18em;
}
.projects-page__card-summary {
  align-self: start;
}
.projects-page__card-action {
  align-self: end;
  margin: 0;
  padding-block-start: var(--space-2);
  font-weight: var(--font-weight-medium);
}
.projects-page__card-action > a {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 2.75rem;
  color: var(--color-link);
  text-decoration: none;
}
.projects-page__card-action > a:hover, .projects-page__card-action > a:focus-visible {
  color: var(--color-link-hover);
  text-decoration: underline;
  text-underline-offset: 0.18em;
}
.projects-page__empty {
  display: grid;
  gap: var(--space-3);
  max-width: var(--measure);
  padding: var(--space-5);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
}
.projects-page__empty-title {
  margin: 0;
  font-size: var(--text-xl);
  line-height: var(--leading-tight);
}
.projects-page__empty-text {
  margin: 0;
  color: var(--color-muted);
  font-size: var(--text-base);
  line-height: var(--leading-relaxed);
}
.projects-page__empty-actions {
  display: grid;
  gap: var(--space-3);
  margin-block-start: var(--space-2);
}

/*
  Progressive Project Explorer.

  These styles preserve the existing Projects-page visual language without
  changing the server-rendered fallback. The fallback remains visible until the
  JavaScript enhancement completes successfully.
*/
.project-explorer-status {
  margin: 0;
  color: var(--color-muted);
  line-height: var(--leading-relaxed);
}

.project-explorer-status[data-project-explorer-state=error] {
  color: var(--color-error);
}

[data-project-explorer-root][hidden],
[data-project-explorer-status][hidden],
[data-project-explorer-fallback][hidden] {
  display: none !important;
}

.project-explorer {
  display: grid;
  gap: var(--space-5);
}
.project-explorer > h2 {
  margin: 0;
  font-size: var(--text-2xl);
  line-height: var(--leading-tight);
}
.project-explorer__controls {
  display: grid;
  gap: var(--space-4);
  padding: var(--space-5);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
}
.project-explorer__control {
  display: grid;
  gap: var(--space-2);
}
.project-explorer__control > label {
  font-size: var(--text-sm);
  font-weight: var(--font-weight-medium);
}
.project-explorer__control > input,
.project-explorer__control > select {
  width: 100%;
  min-height: 2.75rem;
  padding: var(--space-2) var(--space-3);
  color: var(--color-text);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface-raised);
}
.project-explorer__controls > button {
  justify-self: start;
  min-height: 2.75rem;
  padding: var(--space-2) var(--space-4);
  color: var(--color-text);
  font: inherit;
  font-weight: var(--font-weight-medium);
  cursor: pointer;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface-raised);
}
.project-explorer__controls > button:disabled {
  cursor: not-allowed;
  opacity: 0.6;
}
.project-explorer__results {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));
  gap: var(--space-5);
  margin: 0;
  padding: 0;
  list-style: none;
}
.project-explorer__item {
  min-width: 0;
}
.project-explorer__card {
  grid-template-rows: auto 1fr;
  gap: 0;
  height: 100%;
  min-width: 0;
  overflow: hidden;
  padding: 0;
  border-radius: var(--radius-md);
  background: var(--color-surface-raised);
  box-shadow: var(--shadow-soft);
}
.project-explorer__media {
  aspect-ratio: 16/9;
  overflow: hidden;
  border-block-end: 1px solid var(--color-border);
  background: var(--color-surface);
}
.project-explorer__image, .project-explorer__image-placeholder {
  display: block;
  width: 100%;
  height: 100%;
}
.project-explorer__image {
  object-fit: cover;
}
.project-explorer__image-placeholder {
  background: linear-gradient(135deg, transparent 0 48%, var(--color-border) 48% 52%, transparent 52%), var(--color-surface-raised);
}
.project-explorer__card-body {
  display: grid;
  grid-template-rows: auto auto auto 1fr auto;
  gap: var(--space-3);
  min-width: 0;
  padding: var(--space-5);
}
.project-explorer__role, .project-explorer__summary {
  margin: 0;
  color: var(--color-muted);
}
.project-explorer__role {
  font-size: var(--text-xs);
  font-weight: var(--font-weight-medium);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.project-explorer__card-title {
  margin: 0;
  font-size: var(--text-xl);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
}
.project-explorer__summary {
  line-height: var(--leading-relaxed);
}
.project-explorer__technologies {
  display: flex;
  flex-wrap: wrap;
  align-content: start;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  color: var(--color-muted);
  font-size: var(--text-sm);
  list-style: none;
}
.project-explorer__technologies > li {
  padding: var(--space-1) var(--space-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  background: var(--color-surface);
}
.project-explorer__card-body > a {
  align-self: end;
  color: var(--color-link);
  font-weight: var(--font-weight-medium);
  text-decoration: none;
}
.project-explorer__card-body > a:hover, .project-explorer__card-body > a:focus-visible {
  color: var(--color-link-hover);
  text-decoration: underline;
  text-underline-offset: 0.18em;
}
.project-explorer__no-match {
  margin: 0;
  color: var(--color-muted);
}

@media (min-width: 48rem) {
  .contact-page__layout {
    gap: var(--space-8);
  }
  .contact-page__form-panel {
    padding: var(--space-6);
  }
  .projects-page {
    gap: var(--space-7);
  }
  .projects-page__empty-actions {
    display: flex;
    flex-wrap: wrap;
  }
  .project-explorer__controls {
    grid-template-columns: repeat(3, minmax(0, 1fr)) auto;
    align-items: end;
  }
}
@media (min-width: 64rem) {
  .contact-page__layout {
    grid-template-columns: minmax(18rem, 0.8fr) minmax(0, 1.2fr);
    align-items: start;
    column-gap: var(--space-8);
  }
}
/* ==========================================================================
    layout/main.scss
    Shared page-level layout.
    CS50W concept:
    - base.html provides the document skeleton.
    - .site-main controls the shared main content area.
   ========================================================================== */
/* ==========================================================================
  pages/_home.scss
  Homepage identity, featured evidence, and routing sections.
  ========================================================================== */
.home {
  display: grid;
  gap: var(--space-8);
}

.home__hero {
  display: grid;
  gap: var(--space-3);
  width: 100%;
  max-width: var(--container-narrow);
  margin-inline: auto;
  padding-block: var(--space-5) var(--space-6);
}

.home__eyebrow,
.home__title,
.home__positioning,
.home__lead,
.home__section-title,
.home__section-text,
.home__section-action,
.home__project-meta,
.home__project-title,
.home__project-summary,
.home__project-action {
  margin: 0;
}

.home__eyebrow {
  color: var(--color-muted);
  font-size: var(--text-sm);
  font-weight: var(--font-weight-medium);
  line-height: var(--leading-tight);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.home__title {
  max-width: 20ch;
  font-size: clamp(2rem, 8vw, 4.5rem);
  line-height: 1.05;
  letter-spacing: var(--tracking-tight);
}

.home__positioning {
  max-width: 38ch;
  font-size: clamp(var(--text-xl), 3.5vw, 1.75rem);
  font-weight: var(--font-weight-medium);
  line-height: 1.4;
  text-wrap: balance;
}

.home__lead {
  max-width: 60ch;
  color: var(--color-muted);
  font-size: var(--text-lg);
  line-height: var(--leading-relaxed);
}

.home__actions {
  display: grid;
  gap: var(--space-3);
  align-items: start;
  margin-block-start: var(--space-5);
}

.home__section {
  display: grid;
  gap: var(--space-5);
  min-width: 0;
}

.home__section--featured {
  position: relative;
  isolation: isolate;
}

.home__section--featured::before {
  position: absolute;
  z-index: -1;
  inset-block: calc(var(--space-5) * -1);
  inset-inline: calc(50% - 50vw);
  background: var(--color-surface);
  content: "";
}

.home__section-header {
  display: grid;
  gap: var(--space-3);
  align-content: start;
}

.home__section-title {
  font-size: clamp(var(--text-2xl), 4vw, 2rem);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
}

.home__section-text,
.home__project-summary {
  color: var(--color-muted);
  line-height: var(--leading-relaxed);
}

.home__section--editorial {
  padding-block: var(--space-6);
  border-block: 1px solid var(--color-border);
}

.home__section-action {
  align-self: end;
  font-weight: var(--font-weight-medium);
}

.home__section-action > a,
.home__project-action > a {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 2.75rem;
  text-decoration: none;
  transition: color 150ms ease;
}

.home__section-action > a:hover,
.home__section-action > a:focus-visible,
.home__project-action > a:hover,
.home__project-action > a:focus-visible {
  text-decoration: underline;
  text-underline-offset: 0.18em;
}

.home__projects,
.home__routes {
  display: grid;
  gap: var(--space-5);
  min-width: 0;
}

.home__project {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-width: 0;
  overflow: hidden;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-raised);
  box-shadow: var(--shadow-soft);
}

.home__project-media {
  flex: 0 0 auto;
  aspect-ratio: 16/9;
  overflow: hidden;
  border-block-end: 1px solid var(--color-border);
  background: var(--color-surface);
}

.home__project-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.home__project-body {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-5);
}

.home__project-meta {
  color: var(--color-muted);
  font-size: var(--text-xs);
  font-weight: var(--font-weight-medium);
  line-height: var(--leading-tight);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.home__project-title {
  font-size: var(--text-xl);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
}

.home__project-action {
  margin-block-start: auto;
  padding-block-start: var(--space-2);
  font-weight: var(--font-weight-medium);
}

.home__section--route {
  grid-template-rows: auto 1fr auto;
  padding-block-start: var(--space-5);
  border-block-start: 1px solid var(--color-border);
}

@media (min-width: 30rem) {
  .home__actions {
    display: flex;
    flex-wrap: wrap;
  }
}
@media (min-width: 48rem) {
  .home__hero {
    padding-block: var(--space-7);
  }
  .home__section--editorial {
    grid-template-columns: minmax(12rem, 0.7fr) minmax(0, 1.5fr);
    column-gap: var(--space-8);
    align-items: start;
    padding-block: var(--space-7);
  }
  .home__routes {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-8);
  }
  .home__section--route {
    padding-block-start: var(--space-6);
  }
}
@media (min-width: 64rem) {
  .home__hero {
    padding-block-end: var(--space-8);
  }
  /*
    The homepage is a curated set capped at three projects. Keep one column
    until all three cards fit as a complete row.
  */
  .home__projects {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
/* ==========================================================================
    layout/main.scss
    Shared page-level layout.
    CS50W concept:
    - base.html provides the document skeleton.
    - .site-main controls the shared main content area.
   ========================================================================== */
/* ==========================================================================
  pages/_about.scss
  Editorial About-page background and current work.
  ========================================================================== */
.about-page {
  display: grid;
  gap: var(--space-7);
  width: 100%;
  max-width: var(--container-narrow);
  margin-inline: auto;
}

.about-page__intro,
.about-page__journey,
.about-page__direction,
.about-page__evidence,
.about-page__section-header,
.about-page__introduction,
.about-page__section-copy,
.about-page__evidence-intro {
  display: grid;
}

.about-page__intro {
  gap: var(--space-4);
  padding-block: var(--space-4) 0;
}

.about-page__editorial-label {
  display: none;
  margin: 0;
}

.about-page__eyebrow,
.about-page__title,
.about-page__positioning,
.about-page__section-title,
.about-page__journey-marker,
.about-page__journey-title,
.about-page__introduction > p,
.about-page__section-header > p,
.about-page__journey-content > p,
.about-page__section-copy > p,
.about-page__evidence-intro > p {
  margin: 0;
}

.about-page__eyebrow {
  color: var(--color-muted);
  font-size: var(--text-xs);
  font-weight: var(--font-weight-medium);
  line-height: var(--leading-tight);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  white-space: nowrap;
}

.about-page__title {
  max-width: 14ch;
  font-size: var(--text-3xl);
}

.about-page__positioning {
  max-width: 34ch;
  font-size: clamp(var(--text-xl), 4vw, 1.75rem);
  font-weight: var(--font-weight-medium);
  line-height: 1.4;
  text-wrap: balance;
}

.about-page__introduction,
.about-page__section-copy {
  gap: var(--space-3);
  max-width: var(--measure);
}

.about-page__introduction {
  margin-block-start: var(--space-2);
}

.about-page__introduction > p,
.about-page__journey-content > p,
.about-page__section-copy > p {
  color: var(--color-text);
  line-height: var(--leading-relaxed);
}

.about-page__evidence-intro > p {
  color: var(--color-muted);
  line-height: var(--leading-relaxed);
}

.about-page__introduction > p {
  font-size: var(--text-lg);
}

.about-page__journey {
  gap: var(--space-5);
}

.about-page__section-header,
.about-page__direction,
.about-page__evidence-intro {
  gap: var(--space-3);
}

.about-page__section-header,
.about-page__direction {
  max-width: var(--measure);
}

.about-page__section-title {
  font-size: var(--text-2xl);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
}

.about-page__journey-stages {
  display: grid;
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

.about-page__journey-stage {
  min-width: 0;
  padding-block-end: var(--space-5);
}

.about-page__journey-stage:last-child {
  padding-block-end: 0;
}

.about-page__journey-stage > article {
  display: grid;
  grid-template-columns: 2rem minmax(0, 1fr);
  gap: var(--space-3);
  align-items: start;
  max-width: var(--measure);
}

.about-page__journey-marker {
  padding-block-start: 0.15rem;
  color: var(--color-muted);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-weight: var(--font-weight-medium);
  line-height: var(--leading-tight);
}

.about-page__journey-content {
  display: grid;
  gap: var(--space-2);
  min-width: 0;
}

.about-page__journey-title {
  font-size: var(--text-xl);
  line-height: var(--leading-tight);
}

.about-page__direction {
  gap: var(--space-3);
}

.about-page__evidence {
  gap: var(--space-4);
}

.about-page__evidence-links {
  display: flex;
  flex-wrap: wrap;
  row-gap: 0;
  column-gap: var(--space-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.about-page__evidence-links > li {
  display: flex;
  align-items: center;
}

.about-page__evidence-links > li:first-child {
  flex-basis: 100%;
  margin-block-end: var(--space-2);
}

.about-page__evidence-links > li:not(:first-child) {
  flex: 0 0 auto;
}

.about-page__evidence-links > li:nth-child(n+3)::before {
  margin-inline-end: var(--space-3);
  color: var(--color-muted);
  content: "·";
}

.about-page__evidence-link {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  font-weight: var(--font-weight-medium);
}

@media (min-width: 48rem) {
  .about-page {
    max-width: 66rem;
  }
  .about-page__intro,
  .about-page__direction {
    width: min(100%, var(--container-narrow));
  }
  .about-page__journey-stage {
    padding-block-end: var(--space-6);
  }
  .about-page__journey-marker {
    font-size: var(--text-sm);
  }
}
@media (min-width: 64rem) {
  .about-page {
    --about-editorial-rail: 8rem;
    --about-editorial-gutter: var(--space-7);
    max-width: 66rem;
  }
  .about-page__intro {
    width: min(100% - var(--about-editorial-rail) - var(--about-editorial-gutter), var(--container-narrow));
    margin-inline-start: calc(var(--about-editorial-rail) + var(--about-editorial-gutter));
  }
  .about-page__journey,
  .about-page__direction,
  .about-page__evidence {
    grid-template-columns: var(--about-editorial-rail) minmax(0, 1fr);
    column-gap: var(--about-editorial-gutter);
    width: 100%;
    max-width: none;
  }
  .about-page__editorial-label {
    display: block;
    grid-column: 1;
    grid-row: 1;
    padding-block-start: 0.25rem;
    color: var(--color-muted);
    font-size: var(--text-xs);
    font-weight: var(--font-weight-medium);
    line-height: var(--leading-tight);
    text-transform: uppercase;
    letter-spacing: 0.06em;
  }
  .about-page__section-header,
  .about-page__journey-stages,
  .about-page__direction > .about-page__section-title,
  .about-page__direction > .about-page__section-copy,
  .about-page__evidence-intro,
  .about-page__evidence-links {
    grid-column: 2;
  }
  .about-page__section-header,
  .about-page__direction > .about-page__section-title,
  .about-page__evidence-intro {
    grid-row: 1;
  }
  .about-page__journey-stages,
  .about-page__direction > .about-page__section-copy,
  .about-page__evidence-links {
    grid-row: 2;
  }
}
.site-main:has(.about-page) + .site-footer {
  margin-block-start: var(--space-7);
}

/* ==========================================================================
   components/_action.scss
   Reusable button-like action links.

   Use this for links that should look and behave like actions, such as
   homepage CTAs or future project/contact prompts.

   Do not use this for normal text links, header navigation, footer navigation,
   brand links, or skip links.
   ========================================================================== */
.action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 2.75rem;
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  color: var(--color-text);
  background: var(--color-surface-raised);
  font-weight: var(--font-weight-medium);
  text-decoration: none;
  transition: border-color 150ms ease, color 150ms ease, background-color 150ms ease;
}

/* Shared interaction state for action links. */
.action:hover,
.action:focus-visible {
  color: var(--color-link-hover);
  border-color: currentColor;
  background: var(--color-surface);
}

/* Primary action keeps strong visual weight during interaction. */
.action--primary {
  color: var(--color-surface-raised);
  border-color: var(--color-primary);
  background: var(--color-primary);
}

.action--primary:hover,
.action--primary:focus-visible {
  color: var(--color-surface-raised);
  border-color: var(--color-primary-hover);
  background: var(--color-primary-hover);
}

/* Secondary action stays quiet but still button-like. */
.action--secondary {
  background: var(--color-surface);
}

/* ==========================================================================
   components/_card.scss
   Reusable content card styles.

   Use this for small grouped content blocks such as homepage focus cards,
   future project summaries, or research note previews.

   Do not use this for full page sections, navigation, or layout grids.
   ========================================================================== */
.card {
  display: grid;
  gap: var(--space-2);
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
}

.card__title {
  margin: 0;
  font-size: var(--text-base);
  font-weight: var(--font-weight-bold);
  line-height: var(--leading-tight);
}

.card__text {
  margin: 0;
  color: var(--color-muted);
  line-height: var(--leading-relaxed);
}

/* ==========================================================================
    layout/main.scss
    Shared page-level layout.
    CS50W concept:
    - base.html provides the document skeleton.
    - .site-main controls the shared main content area.
   ========================================================================== */
/* ==========================================================================
   Site header component
   ========================================================================== */
/* Header shell
   ========================================================================== */
.site-header {
  position: relative;
  z-index: 10;
  border-bottom: 1px solid var(--color-border);
  background: var(--color-bg);
}

.site-header__inner {
  padding-block: var(--space-3);
}

/*
  Arrange the brand and mobile menu button on one row.

  The row spans the available width on small screens so the brand stays left
  and the menu button stays right. Brand truncation is handled by the brand
  component instead of allowing this row to wrap.
*/
.site-header__bar {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  width: 100%;
}

/* Brand
   ========================================================================== */
.site-brand {
  --site-brand-font-size: var(--text-base);
  --site-brand-letter-spacing: var(--tracking-tight);
  display: inline-flex;
  flex-direction: row;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
  max-width: 100%;
  color: var(--color-text);
  font-weight: var(--font-weight-bold);
  text-decoration: none;
}

/*
  Give the brand link visual feedback for pointer and keyboard users.
  The global focus outline is handled in base/accessibility.scss.
*/
.site-brand:hover,
.site-brand:focus-visible {
  color: var(--color-link-hover);
}

/*
  Keep the logo proportional and prevent oversized image files from
  increasing the header height.
*/
.site-brand__logo {
  width: auto;
  max-width: 100%;
  max-height: var(--site-logo-max-height);
}

/*
  Keep the brand name on one line.
  If the available space becomes narrow, the text truncates with an ellipsis
  instead of pushing the menu button or navigation out of place.
*/
.site-brand__name {
  display: block;
  overflow: hidden;
  font-size: var(--site-brand-font-size);
  letter-spacing: var(--site-brand-letter-spacing);
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Mobile navigation toggle
   ========================================================================== */
/*
  Purpose: Style the mobile menu button and keep it hidden by default.
  Learning: A hidden toggle avoids presenting a control when navigation works
  as an always-visible no-JavaScript fallback.
*/
.site-nav-toggle {
  --site-nav-toggle-size: 2.75rem;
  --site-nav-toggle-gap: 0.25rem;
  --site-nav-toggle-bar-width: 1.125rem;
  --site-nav-toggle-bar-height: 2px;
  display: none;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  flex-direction: column;
  gap: var(--site-nav-toggle-gap);
  width: var(--site-nav-toggle-size);
  height: var(--site-nav-toggle-size);
  padding: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  appearance: none;
  color: var(--color-text);
  background: var(--color-surface-raised);
  cursor: pointer;
}

/*
  Purpose: Show the toggle after this header menu initializes successfully.
  Learning: `data-menu-enhanced` confirms the control has working JavaScript;
  `:where()` keeps specificity low so desktop styles can override this rule.
*/
:where(.site-header[data-menu-enhanced=true]) .site-nav-toggle {
  display: inline-flex;
}

/* Purpose: Give pointer and keyboard users clear interaction feedback. */
.site-nav-toggle:hover,
.site-nav-toggle:focus-visible {
  background: var(--color-surface);
}

/*
  Purpose: Draw each bar in the menu icon.
  Learning: `currentColor` keeps the icon synchronized with the button color.
*/
.site-nav-toggle__bar {
  display: block;
  width: var(--site-nav-toggle-bar-width);
  height: var(--site-nav-toggle-bar-height);
  border-radius: var(--radius-full);
  background: currentColor;
}

/*
  Purpose: Hide the mobile toggle from the medium breakpoint upward.
  Learning: The desktop navigation is visible directly, so no disclosure button
  is needed on wider screens.
*/
@media (min-width: 48rem) {
  .site-nav-toggle {
    display: none;
  }
}
/* Primary navigation
   ========================================================================== */
/*
  Purpose: Add spacing around the primary navigation.
  Learning: Keep it visible by default so navigation works without JavaScript.
*/
.site-nav {
  --site-nav-link-min-height: 2.75rem;
  --site-nav-link-min-height-expanded: 2.5rem;
  display: block;
  padding-block-start: var(--space-3);
}

/*
  Purpose: Stack navigation items with consistent spacing on small screens.
  Learning: The list owns the layout of its navigation items.
*/
.site-nav__list {
  display: grid;
  gap: var(--space-1);
  padding: 0;
  margin: 0;
  list-style: none;
}

/* Purpose: Prevent long item content from forcing layout overflow. */
.site-nav__item {
  min-width: 0;
}

/*
  Purpose: Create comfortable, consistent link targets.
  Learning: Flex aligns content inside each link; it does not lay out nav items.
*/
.site-nav__link {
  display: flex;
  align-items: center;
  min-height: var(--site-nav-link-min-height);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--color-muted);
  font-weight: var(--font-weight-medium);
  text-decoration: none;
}

/* Purpose: Give pointer and keyboard users clear interaction feedback. */
.site-nav__link:hover,
.site-nav__link:focus-visible {
  color: var(--color-text);
  background: var(--color-surface);
}

/*
  Purpose: Show which navigation link represents the current page.
  Learning: `aria-current` carries meaning; `.is-active` remains a styling hook.
*/
.site-nav__link[aria-current=page],
.site-nav__link.is-active {
  color: var(--color-text);
  background: var(--color-surface);
}

/*
  Purpose: Arrange navigation items horizontally from the medium breakpoint.
  Learning: Desktop styles override only changes from the mobile-first baseline;
  flex belongs on the list because the list owns the nav items.
*/
@media (min-width: 48rem) {
  .site-nav {
    padding-block-start: 0;
  }
  .site-nav__list {
    display: flex;
    align-items: center;
    gap: var(--space-2);
  }
  .site-nav__link {
    min-height: var(--site-nav-link-min-height-expanded);
    padding: var(--space-3) var(--space-4);
  }
}
/* Responsive layout
   ========================================================================== */
@media (min-width: 48rem) {
  /*
    At wider viewports, the header becomes a single horizontal row:
    brand area on the left, primary navigation on the right.
  */
  .site-header__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-6);
    padding-block: var(--space-4);
  }
  /*
    On mobile, the bar spans the full row for brand + toggle.
    On desktop, it only needs to occupy the brand area.
  */
  .site-header__bar {
    flex: 0 1 auto;
    justify-content: flex-start;
    width: auto;
  }
  /*
    Hide the mobile menu button on wider screens, even when JavaScript
    has enabled the enhanced mobile navigation behavior.
  */
  .site-nav-toggle,
  .js .site-nav-toggle {
    display: none;
  }
  /*
    Keep the primary navigation visible on wider screens.
    This overrides the JavaScript-enhanced mobile collapsed state.
  */
  .site-nav,
  .js .site-nav {
    display: block;
    padding-block-start: 0;
  }
  .site-nav__list {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: var(--space-2);
  }
  .site-nav__link {
    min-height: var(--site-nav-link-min-height-expanded);
  }
}
@media (max-width: 47.999rem) {
  /*
    Purpose: Hide a successfully initialized mobile menu when its current state
    is closed.
    Learning: Keep this narrow-screen only so desktop navigation stays visible
    even when JavaScript records the mobile menu as closed.
  */
  .site-header[data-menu-enhanced=true][data-menu-open=false] .site-nav {
    display: none;
  }
  /*
    Purpose: Show a successfully initialized mobile menu when its current state
    is open.
    Learning: This is the matching open state for the closed-state rule above.
  */
  .site-header[data-menu-enhanced=true][data-menu-open=true] .site-nav {
    display: block;
  }
  /*
    Add separation only for the JavaScript-enhanced open mobile menu.
    Without JavaScript, the navigation remains visible as a fallback and keeps
    the simpler default spacing from the primary navigation rules.
  */
  .js .site-header[data-menu-open=true] .site-nav {
    margin-block-start: var(--space-3);
    border-top: 1px solid var(--color-border);
  }
}
/* ==========================================================================
    layout/main.scss
    Shared page-level layout.
    CS50W concept:
    - base.html provides the document skeleton.
    - .site-main controls the shared main content area.
   ========================================================================== */
/* ==========================================================================
  Site footer component
  ========================================================================== */
.site-footer {
  margin-block-start: var(--space-8);
  border-block-start: 1px solid var(--color-border);
  background: var(--color-surface);
}
.site-footer__inner {
  display: grid;
  gap: var(--space-6);
  padding-block: var(--space-6);
}
.site-footer__main {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  row-gap: var(--space-6);
  column-gap: var(--space-5);
  align-items: start;
}
.site-footer__identity {
  display: grid;
  grid-column: 1/-1;
  align-content: start;
  gap: var(--space-1);
  max-width: 28rem;
}
.site-footer__name, .site-footer__heading, .site-footer__descriptor, .site-footer__copyright {
  margin: 0;
}
.site-footer__name {
  font-size: var(--text-lg);
  line-height: var(--leading-tight);
}
.site-footer__brand-link {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  color: var(--color-text);
  text-decoration: none;
}
.site-footer__brand-link:hover, .site-footer__brand-link:focus-visible {
  color: var(--color-link-hover);
  text-decoration: underline;
  text-underline-offset: 0.18em;
}
.site-footer__descriptor, .site-footer__copyright {
  color: var(--color-muted);
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
}
.site-footer__heading {
  color: var(--color-muted);
  font-size: var(--text-xs);
  font-weight: var(--font-weight-medium);
  line-height: var(--leading-tight);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.site-footer__nav, .site-footer__legal {
  min-width: 0;
}
.site-footer__link-list, .site-footer__legal-list {
  display: grid;
  gap: 0;
  padding: 0;
  margin: var(--space-1) 0 0;
  list-style: none;
}
.site-footer__link {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  color: var(--color-muted);
  text-decoration: none;
}
.site-footer__link:hover, .site-footer__link:focus-visible, .site-footer__link[aria-current=page], .site-footer__link.is-active {
  color: var(--color-text);
  text-decoration: underline;
  text-underline-offset: 0.18em;
}
.site-footer__utility {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  row-gap: var(--space-2);
  column-gap: var(--space-5);
  padding-block-start: var(--space-4);
  border-block-start: 1px solid var(--color-border);
  color: var(--color-muted);
}
.site-footer__legal-list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: start;
  gap: 0;
  margin-block-start: 0;
}
.site-footer__legal-list > li {
  display: flex;
  align-items: center;
}
.site-footer__legal-separator {
  margin-inline: var(--space-2);
}
@media (min-width: 48rem) {
  .site-footer__main {
    column-gap: var(--space-7);
  }
}
@media (min-width: 64rem) {
  .site-footer__main {
    grid-template-columns: minmax(0, 2fr) repeat(2, minmax(10rem, 1fr));
    column-gap: var(--space-8);
  }
  .site-footer__identity {
    grid-column: auto;
  }
}
