/* ============================================================
   Colour scheme
   --bg:   page and nav background
   --text: all text and outlines
   ============================================================ */

:root {
  --bg: #ffffff;
  --text: #000000;
  --name-color: #c800da; /* 4.70:1 on white — passes AA (and AAA large text if ≥1.167rem bold) */

  /* Vertical rhythm for project pages. The project title sits at --title-top;
     body text in every column, and every stacked image, starts at --text-top.
     --text-top must clear the title: 5.4rem + one 0.9rem/1.2 line + 1.5rem. */
  --title-top: 5.4rem;
  --text-top: 8rem;
}

/* ============================================================
   Base reset
   ============================================================ */

*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  font-size: 15px;
}

body {
  font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  color: var(--text);
  background-color: var(--bg);
}

/* ============================================================
   Skip link (must be the first focusable element on every page)
   ============================================================ */

.skip-link {
  position: absolute;
  top: -9999px;
  left: -9999px;
  padding: 0.5rem 1rem;
  background: var(--text);
  color: var(--bg);
  font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 1rem;
  text-decoration: none;
  z-index: 200;
}

.skip-link:focus {
  top: 1rem;
  left: 1rem;
}

/* ============================================================
   Visually hidden (accessible but not visible)
   ============================================================ */

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ============================================================
   Focus indicators
   Applied globally so nothing is missed.
   Never remove or override these.
   ============================================================ */

:focus-visible {
  outline: 2px solid var(--text);
  outline-offset: 3px;
}

/* ============================================================
   Side navigation
   ============================================================ */

.sidenav {
  position: fixed;
  top: 0;
  left: 0;
  width: 200px;
  height: 100vh;
  padding: 2rem 1.5rem;
  overflow-y: auto;
  background-color: var(--bg);
}

.nav-home {
  display: block;
  font-size: 1rem;
  font-weight: bold;
  font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  color: var(--name-color);
  text-decoration: underline;
  margin-bottom: 2rem;
  line-height: 1.4;
}

.nav-home:hover {
  text-decoration: none;
}

.nav-list {
  list-style: none;
}

.nav-list > li {
  margin-bottom: 0.75rem;
}

.nav-list > li > a {
  font-size: 0.9rem;
  color: var(--text);
  text-decoration: none;
}

.nav-list > li > a:hover {
  text-decoration: underline;
}

.nav-section {
  margin-bottom: 1rem;
}

.nav-category {
  display: block;
  font-size: 0.9rem;
  margin-bottom: 0.2rem;
  /* Reset button defaults */
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  font-family: inherit;
  color: var(--text);
  text-align: left;
  text-decoration: none;
}

.nav-category:hover {
  text-decoration: underline;
}

.nav-category[aria-pressed="true"] {
  text-decoration: underline;
}

.nav-sub-list {
  list-style: none;
  padding-left: 0.75rem;
}

.nav-sub-list li {
  margin-bottom: 0.2rem;
}

.nav-sub-list a {
  font-size: 0.9rem;
  color: var(--text);
  text-decoration: none;
}

.nav-sub-list a:hover {
  text-decoration: underline;
}

.nav-sub-list a[aria-current="page"] {
  text-decoration: underline;
}

/* ============================================================
   Main content area (homepage)
   ============================================================ */

.main {
  margin-left: 200px;
  padding: 5rem 2.5rem 2.5rem 2.5rem;
}

/* ============================================================
   Project card grid (homepage)
   Grid with align-items: start so tops are aligned per row,
   and the row height is set by the tallest card.
   ============================================================ */

.card-grid {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  column-gap: 3rem;
  row-gap: 2.5rem;
  align-items: start;
}

.card {
  display: block;
  color: var(--text);
  text-decoration: none;
}

.card img {
  display: block;
  width: 100%;
  height: auto;
}

/* ============================================================
   Project pages — horizontal scroll layout
   ============================================================ */

.project-page {
  overflow: hidden;
  height: 100vh;
}

.project-page .main {
  padding: 0;
  height: 100vh;
  overflow: hidden;
}

.project-scroll {
  display: block;
  white-space: nowrap;
  font-size: 0; /* suppress inline-block whitespace gap */
  overflow-x: auto;
  overflow-y: hidden;
  height: 100%;
  width: 100%;
}

.project-scroll:focus-visible {
  outline: 2px solid var(--text);
  outline-offset: -2px;
}

/* ============================================================
   Newspaper-style text flow (project pages)
   ============================================================ */

.project-text-flow {
  position: relative;
  display: inline-block;
  white-space: normal;
  vertical-align: top;
  height: 100%;
  columns: 300px;
  column-fill: auto;
  column-gap: 2rem;
  padding: var(--text-top) 3rem 3rem;
  overflow: hidden;
}

.project-text-flow p {
  font-size: 0.9rem;
  line-height: 1.7;
  margin-bottom: 1rem;
}

.project-text-flow h1 {
  break-after: avoid;
}

.project-text-flow blockquote,
.project-text-flow .project-meta {
  break-inside: avoid;
}

.project-text-flow blockquote {
  margin-left: 1.5rem;
  font-style: italic;
}

.project-text-flow a {
  color: var(--text);
  text-decoration: underline;
}

.project-text-flow a:hover {
  text-decoration: none;
}

.project-panel {
  flex-shrink: 0;
  width: 100%;
  height: 100%;
  scroll-snap-align: start;
  overflow-y: auto;
  padding: 3rem;
}

.project-panel--intro {
  width: 380px;
  min-width: 300px;
  padding-top: 5.4rem;
}

.project-panel:focus-visible {
  outline: 2px solid var(--text);
  outline-offset: -4px;
}

.project-title {
  font-size: 0.9rem;
  font-weight: bold;
  margin-bottom: 1.5rem;
  line-height: 1.2;
}

/* Taken out of the column flow so the title doesn't occupy space in the first
   column. Every column then starts at --text-top, instead of the second column
   running up level with the title while the first starts below it. */
.project-text-flow .project-title {
  position: absolute;
  top: var(--title-top);
  left: 3rem;
  max-width: 300px; /* one column */
  margin-bottom: 0;
}

.project-intro {
  font-size: 0.9rem;
  line-height: 1.6;
  max-width: 60ch;
  margin-bottom: 2rem;
}

.project-meta {
  font-size: 0.9rem;
  line-height: 1.8;
}

.project-meta dt {
  font-style: italic;
  display: inline;
}

.project-meta dt::after {
  content: ': ';
}

.project-meta dd {
  display: inline;
  margin: 0;
}

.project-meta dd::after {
  content: '';
  display: block;
}

.project-panel--image {
  display: inline-flex;
  white-space: normal;
  vertical-align: top;
  width: calc(100vw - 200px); /* provisional — JS sets the real width */
  height: 100%;
  /* Starts on the same line as the body text, and the deeper bottom padding
     keeps the image clear of filling the whole window height. */
  padding: var(--text-top) 3rem 6rem 0;
  align-items: flex-start;
  justify-content: flex-start;
  background-color: var(--bg);
}

.project-panel--image figure {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  min-width: 220px; /* keeps captions from wrapping into a ribbon when short */
}

.project-panel--image img,
.project-panel--image .pdf-embed {
  width: 100%;
  height: 100%;
  display: block;
}

.project-panel--image img {
  object-fit: contain;
  object-position: left center;
}

/* Stacked image panel — two or more images sharing one column. It uses exactly
   the same vertical envelope as .project-panel--image, and the items divide that
   height equally, so a stack of two lines up top and bottom with the single
   images either side of it. Width is set in JS from the widest item. */
.project-panel--stack {
  display: inline-flex;
  flex-direction: column;
  white-space: normal;
  vertical-align: top;
  width: calc(100vw - 200px); /* provisional — JS sets the real width */
  height: 100%;
  padding: var(--text-top) 3rem 6rem 0;
  row-gap: 0.75rem;
  background-color: var(--bg);
}

.stack-item {
  display: flex;
  flex-direction: column;
  flex: 1; /* equal share of the panel height */
  min-height: 0;
  min-width: 220px; /* keeps captions from wrapping into a ribbon when short */
  margin: 0;
}

.project-panel--stack .image-zoom-trigger {
  flex: 1;
  min-height: 0;
  width: 100%;
}

.project-panel--stack img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: left center;
}

.project-panel--stack figcaption {
  font-size: 0.85rem;
  line-height: 1.4;
  text-align: left;
  padding: 0.5rem 2rem 0 0;
  min-height: 3rem; /* matches .project-panel--image, so rows stay even */
  flex-shrink: 0;
}

/* Video panel — contains an embedded video iframe.
   Width is derived from the available panel height at a 16∶9 ratio,
   matching the vertical envelope of the image panels. */
.project-panel--video {
  display: inline-flex;
  flex-direction: column;
  white-space: normal;
  vertical-align: top;
  height: 100%;
  padding: var(--text-top) 3rem 6rem 0;
  background-color: var(--bg);
}

.project-panel--video iframe {
  display: block;
  height: calc(100vh - var(--text-top) - 6rem);
  width: calc((100vh - var(--text-top) - 6rem) * (16 / 9));
  border: 0;
}

.project-panel--video figcaption {
  font-size: 0.85rem;
  line-height: 1.4;
  text-align: left;
  padding: 0.5rem 2rem 0 0;
  flex-shrink: 0;
}

/* Zoom trigger — wraps the image in a panel */
.image-zoom-trigger {
  display: block;
  background: none;
  border: none;
  padding: 0;
  cursor: zoom-in;
  flex: 1;
  min-height: 0;
  width: 100%;
}

/* Modal image viewer */
.modal {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: flex;
  align-items: center;
  justify-content: center;
}

.modal[hidden] {
  display: none;
}

.modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.9);
}

.modal-content {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  width: 92vw;
  height: 92vh;
}

.modal-close {
  background: none;
  border: none;
  color: #fff;
  font-size: 2rem;
  line-height: 1;
  cursor: pointer;
  padding: 0.1rem 0.4rem;
  font-family: inherit;
}

.modal-close:hover {
  opacity: 0.7;
}

.modal-close:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 3px;
}

.modal-figure {
  margin: 0;
}

#modal-img {
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  max-width: none;
  max-height: none;
  transform-origin: 0 0;
}

#modal-caption {
  color: #fff;
  font-size: 0.85rem;
  text-align: center;
  padding: 0.5rem 0 0;
  flex-shrink: 0;
  margin: 0;
}

.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-shrink: 0;
  padding-bottom: 0.5rem;
}

.modal-zoom-controls {
  display: flex;
  gap: 0.5rem;
}

.modal-zoom-btn {
  background: none;
  border: 1px solid rgba(255, 255, 255, 0.5);
  color: #fff;
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  padding: 0.3rem 0.65rem;
  font-family: inherit;
  min-width: 2.2rem;
}

.modal-zoom-btn:hover {
  background: rgba(255, 255, 255, 0.15);
}

.modal-zoom-btn:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 3px;
}

.modal-viewport {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  position: relative;
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
  touch-action: none;
}

.modal-viewport.is-dragging {
  cursor: grabbing;
}

.modal-hint {
  color: #fff;
  font-size: 0.75rem;
  font-style: italic;
  text-align: center;
  padding: 0.3rem 0 0;
  flex-shrink: 0;
  margin: 0;
  opacity: 0.7;
}

.project-panel--image figcaption {
  font-size: 0.85rem;
  line-height: 1.4;
  text-align: left;
  padding: 0.5rem 2rem 0 0; /* the panel's own bottom padding sits below this */
  /* Reserves two lines whether or not the caption needs them, so a caption that
     wraps doesn't steal height from its image and leave the panels uneven. */
  min-height: 3rem;
  flex-shrink: 0;
}

.project-panel h2 {
  font-size: 1.1rem;
  font-weight: bold;
  margin-bottom: 0.75rem;
}

.project-panel p {
  font-size: 1rem;
  line-height: 1.7;
  max-width: 60ch;
  margin-bottom: 1rem;
}

/* ============================================================
   Login page
   ============================================================ */

.login-page {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}

.login-main {
  width: 18rem;
}

.login-title {
  font-size: 1rem;
  font-weight: normal;
  margin-bottom: 2rem;
}

.login-form {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.75rem;
}

.login-form label {
  font-size: 0.9rem;
}

.login-form input[type="password"] {
  font-family: inherit;
  font-size: 1rem;
  border: 1px solid var(--text);
  padding: 0.4rem 0.5rem;
  background: var(--bg);
  color: var(--text);
  width: 100%;
}

.login-form button[type="submit"] {
  font-family: inherit;
  font-size: 0.9rem;
  background: var(--text);
  color: var(--bg);
  border: none;
  padding: 0.4rem 1rem;
  cursor: pointer;
}

.login-form button[type="submit"]:hover {
  opacity: 0.75;
}

/* ============================================================
   Mobile layout (≤ 768px)
   Nav collapses to a full-screen overlay toggled by a button.
   Project pages revert from horizontal to vertical scroll.
   ============================================================ */

/* Hidden on desktop; shown only in the media query below. */
.nav-toggle {
  display: none;
}

@media (max-width: 768px) {

  /* ── Nav toggle button ── */
  .nav-toggle {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    position: fixed;
    top: 1rem;
    right: 1rem;
    z-index: 200;
    background: var(--bg);
    border: 1px solid var(--text);
    padding: 0.5rem 0.75rem;
    font-family: inherit;
    font-size: 0.9rem;
    color: var(--text);
    cursor: pointer;
  }

  /* ── Side nav — full-screen overlay ── */
  .sidenav {
    width: 100%;
    height: 100%;
    transform: translateX(-100%);
    transition: transform 0.2s ease;
    z-index: 150;
    overflow-y: auto;
    padding: 4.5rem 2rem 2rem;
  }

  .sidenav.is-open {
    transform: translateX(0);
  }

  /* ── Homepage — remove desktop left offset ── */
  .main {
    margin-left: 0;
    padding: 4.5rem 1.5rem 2rem;
  }

  /* ── Project pages — switch to vertical scroll ── */
  .project-page {
    overflow: visible;
    height: auto;
  }

  .project-page .main {
    height: auto;
    overflow: visible;
    padding: 3.5rem 0 0;
  }

  .project-scroll {
    display: block;
    white-space: normal;
    overflow-x: visible;
    overflow-y: visible;
    height: auto;
    font-size: 1rem; /* undo the 0 that suppresses inline-block gaps */
  }

  /* Text flow — single column, normal block flow.
     The JS sizer clears the inline width on mobile. */
  .project-text-flow {
    display: block;
    height: auto;
    columns: unset;
    padding: 1.5rem 1.5rem 0;
    overflow: visible;
  }

  /* Title back in normal document flow. */
  .project-text-flow .project-title {
    position: static;
    top: auto;
    left: auto;
    max-width: none;
    margin-bottom: 1rem;
  }

  /* Image panels — JS clears the inline width on mobile. */
  .project-panel--image {
    display: block;
    height: auto;
    padding: 1.5rem;
  }

  .project-panel--image figure {
    height: auto;
    min-width: 0;
  }

  .project-panel--image .image-zoom-trigger {
    flex: none;
    height: auto;
  }

  .project-panel--image img {
    height: auto;
    object-position: left top;
  }

  .project-panel--image figcaption {
    min-height: 0;
    padding: 0.5rem 0 0;
  }

  /* Stack panels — JS clears the inline width on mobile. */
  .project-panel--stack {
    display: block;
    height: auto;
    padding: 1.5rem;
    row-gap: 0;
  }

  .stack-item {
    flex: none;
    min-height: 0;
    min-width: 0;
    margin-bottom: 1.5rem;
  }

  .project-panel--stack .image-zoom-trigger {
    flex: none;
    height: auto;
  }

  .project-panel--stack img {
    height: auto;
    object-position: left top;
  }

  .project-panel--stack figcaption {
    min-height: 0;
    padding: 0.5rem 0 0;
  }

  /* Video panels */
  .project-panel--video {
    display: block;
    height: auto;
    padding: 1.5rem;
  }

  .project-panel--video iframe {
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 9;
  }

}
