/* ==============================================
   NYU CONCRETE CANOE - HORIZONTAL TIMELINE
   Earliest on the left, most recent on the right.
   Scrolls by wheel, drag or keyboard; the scrollbar
   is hidden and a continuous line runs behind the
   stops to read as a timeline rather than a carousel.
   ============================================== */

/* The rail is the one thing on the site that wants the full screen width. On
   a 3440px display the shared 1100px content-wrapper would waste most of it,
   which matters when the page is projected in a classroom. */
.content-wrapper--wide {
  max-width: none;
  padding-inline: clamp(1rem, 4vw, 5rem);
}

.t-rail {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 2.5rem;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  /* Half the rail minus half a card, so the first and last years can be
     scrolled to the centre like every other one. Without this the newest canoe
     could only ever sit against the right edge. */
  padding: 3.5rem calc(50% - clamp(170px, 14vw, 330px)) 2.5rem;
  scrollbar-width: none;
  -ms-overflow-style: none;
  cursor: grab;
}

.t-rail::-webkit-scrollbar {
  display: none;
}

.t-rail.is-dragging {
  cursor: grabbing;
  scroll-behavior: auto;
  user-select: none;
}

.t-rail.is-dragging .t-card {
  transition: none;
}

.t-rail:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 6px;
  border-radius: 24px;
}

/* The line is drawn per stop rather than once across the rail. A single
   absolutely positioned element cannot work here: inside a scroll container
   width:100% is the visible width, not the scrollable width, so it only ever
   spanned one screen. Each segment overhangs by half the gap on both sides so
   they meet seamlessly, and the run stops at the first and last markers. */
.t-line {
  display: none;
}

.t-stop::before {
  content: "";
  position: absolute;
  top: -0.2rem;
  left: -1.25rem;
  right: -1.25rem;
  height: 2px;
  background: rgba(255, 255, 255, 0.28);
  pointer-events: none;
}

.t-stop:first-child::before {
  left: 2.3rem;
  background: linear-gradient(to right,
      rgba(255, 255, 255, 0),
      rgba(255, 255, 255, 0.28) 12px);
}

.t-stop:last-child::before {
  right: auto;
  width: calc(2.3rem + 11px);
  background: linear-gradient(to left,
      rgba(255, 255, 255, 0),
      rgba(255, 255, 255, 0.28) 12px);
}

.t-stop {
  position: relative;
  /* Grows with the screen so a projected timeline stays readable from the back
     of a room, and caps so it never becomes a single giant panel. */
  flex: 0 0 clamp(340px, 28vw, 660px);
  scroll-snap-align: center;
  display: flex;
  flex-direction: column;
  padding-top: 2.25rem;
}

/* The year itself sits on the line, so the rail reads as a real timeline
   rather than a row of anonymous dots. */
.t-marker {
  position: absolute;
  top: -1.15rem;
  left: 2rem;
  height: 1.9rem;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  /* Sits above the line segment that runs behind it. */
  z-index: 1;
}

.t-marker::after {
  content: "";
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 0 5px rgba(10, 10, 10, 0.9);
  order: -1;
}

.t-marker-year {
  padding: 0.3rem 0.85rem;
  font-size: clamp(0.95rem, 1vw, 1.4rem);
  border-radius: 100px;
  background: rgba(10, 10, 10, 0.9);
  border: 1px solid rgba(255, 255, 255, 0.25);
  font-weight: 800;
  letter-spacing: -0.01em;
  line-height: 1.3;
  white-space: nowrap;
}

/* Only the centred year is at full size. Everything either side sits back a
   little, so the eye lands on the current canoe. Scaling the card rather than
   the stop keeps the marker and the line unaffected. */
.t-stop .t-card {
  transform: scale(0.94);
  transform-origin: top center;
  opacity: 0.62;
  transition: transform 0.45s cubic-bezier(0.2, 0.8, 0.2, 1),
    opacity 0.45s ease, background 0.3s ease, border-color 0.3s ease;
}

.t-stop.is-current .t-card {
  transform: scale(1);
  opacity: 1;
}

.t-stop.is-current .t-marker-year {
  background: #fff;
  color: #000;
  border-color: #fff;
}

.t-card {
  display: flex;
  flex-direction: column;
  width: 100%;
  background: var(--glass-bg);
  backdrop-filter: saturate(180%) blur(var(--blur-amount));
  -webkit-backdrop-filter: saturate(180%) blur(var(--blur-amount));
  border: 1px solid var(--glass-border);
  border-radius: 20px;
  overflow: hidden;
  box-shadow: var(--shadow);
  transition: background 0.3s ease, border-color 0.3s ease;
}

@media (hover: hover) {
  .t-card:hover {
    background: var(--glass-bg-hover);
    border-color: rgba(255, 255, 255, 0.32);
  }
}

/* --- Media --- */

.t-media {
  position: relative;
  /* Taller than before, and it scales with viewport height so the photo stays
     the dominant element of the card at every screen size. */
  height: clamp(240px, 34vh, 520px);
  background: rgba(0, 0, 0, 0.35);
  transition: height 0.45s cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* The year in the centre of the rail gets a noticeably larger photo, so the
   current canoe reads as the headline and the neighbours as context. */
.t-stop.is-current .t-media {
  height: clamp(320px, 46vh, 660px);
}

.t-media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.5s ease;
  /* Prevents the browser's native image drag from fighting the rail drag */
  pointer-events: none;
  user-select: none;
}

.t-media img.is-active {
  opacity: 1;
}

/* Years with no photos yet show the year rather than an empty box. */
.t-media--empty {
  display: flex;
  align-items: center;
  justify-content: center;
}

.t-media--empty span {
  font-size: 1rem;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.4);
}

/* Photo controls */

.t-arrow,
.t-zoom {
  position: absolute;
  border: none;
  background: rgba(0, 0, 0, 0.6);
  color: #fff;
  cursor: pointer;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.25s, opacity 0.25s;
  opacity: 0;
}

.t-arrow {
  top: 50%;
  transform: translateY(-50%);
  width: 38px;
  height: 38px;
}

.t-arrow.prev { left: 0.65rem; }
.t-arrow.next { right: 0.65rem; }

.t-zoom {
  top: 0.65rem;
  right: 0.65rem;
  width: 34px;
  height: 34px;
  font-size: 0.85rem;
}

/* Controls stay out of the way until the card is hovered or focused. On
   touch, where hover never happens, they are always visible. */
.t-card:hover .t-arrow,
.t-card:hover .t-zoom,
.t-card:focus-within .t-arrow,
.t-card:focus-within .t-zoom {
  opacity: 1;
}

@media (hover: none) {
  .t-arrow,
  .t-zoom {
    opacity: 1;
  }
}

.t-arrow:hover,
.t-zoom:hover {
  background: rgba(0, 0, 0, 0.9);
}

.t-count {
  position: absolute;
  bottom: 0.7rem;
  right: 0.7rem;
  padding: 0.25rem 0.6rem;
  border-radius: 100px;
  background: rgba(0, 0, 0, 0.6);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.02em;
}

/* --- Text --- */

.t-text {
  display: flex;
  flex-direction: column;
  padding: 1.75rem;
}

.t-stop.is-current .t-text {
  padding-top: 1.5rem;
}

.t-name {
  font-size: clamp(1.35rem, 1.4vw, 2rem);
  text-align: left;
  margin-bottom: 0.75rem;
}

.t-desc {
  font-size: clamp(0.95rem, 0.95vw, 1.25rem);
  line-height: 1.65;
  text-align: left;
  color: var(--text-dim);
  margin-bottom: 0;
  flex: 1;
}

.t-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 1.25rem;
}

@media (max-width: 700px) {
  .t-stop {
    /* Leaves roughly 14% of the next card showing, which is what tells people
       the rail scrolls sideways. */
    flex: 0 0 86vw;
  }

  .t-rail {
    gap: 1.25rem;
    padding-top: 3rem;
  }

  .t-media {
    height: clamp(170px, 24vh, 240px);
  }

  .t-text {
    padding: 1.4rem;
  }

  .t-marker {
    left: 1.5rem;
  }
}

/* Very wide displays: widen the gap so the stops do not read as one solid
   band, and give the rail more breathing room. */
@media (min-width: 2000px) {
  .t-rail {
    gap: 3.5rem;
  }

  .t-text {
    padding: 2.25rem;
  }
}

/* ==============================================
   FULL SCREEN PHOTO VIEWER
   ============================================== */

.viewer {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Room for the pinned arrows either side. */
  padding: 2rem clamp(5rem, 9vw, 8rem);
  background: rgba(0, 0, 0, 0.94);
  backdrop-filter: blur(8px);
}

.viewer[hidden] {
  display: none;
}

/* Stops the page behind the viewer from scrolling. */
body.viewer-open {
  overflow: hidden;
}

.viewer-stage {
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  max-width: 100%;
  max-height: 100%;
}

.viewer-stage img {
  max-width: min(1400px, 88vw);
  max-height: 82vh;
  width: auto;
  height: auto;
  object-fit: contain;
  border-radius: 8px;
}

.viewer-stage figcaption {
  display: flex;
  align-items: center;
  gap: 1rem;
  font-size: 0.95rem;
  color: rgba(255, 255, 255, 0.85);
}

.viewer-count {
  padding: 0.25rem 0.7rem;
  border-radius: 100px;
  background: rgba(255, 255, 255, 0.12);
  font-size: 0.8rem;
  font-weight: 600;
}

.viewer-arrow,
.viewer-close {
  position: absolute;
  border: none;
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  cursor: pointer;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.25s;
}

/* Fixed to the viewport, not to the image. Photos vary between portrait and
   landscape, and as flex siblings the arrows jumped inward and outward on
   every step, which made them hard to click twice in a row. */
.viewer-arrow {
  top: 50%;
  transform: translateY(-50%);
  width: 54px;
  height: 54px;
  font-size: 1.2rem;
}

.viewer-arrow.prev {
  left: clamp(0.75rem, 2.5vw, 2.5rem);
}

.viewer-arrow.next {
  right: clamp(0.75rem, 2.5vw, 2.5rem);
}

.viewer-arrow:hover {
  transform: translateY(-50%) scale(1.06);
}

.viewer-close {
  position: absolute;
  top: 1.5rem;
  right: 1.5rem;
  width: 46px;
  height: 46px;
  font-size: 1.1rem;
}

.viewer-arrow:hover,
.viewer-close:hover {
  background: rgba(255, 255, 255, 0.28);
}

.viewer-arrow[hidden] {
  display: none;
}

@media (max-width: 700px) {
  .viewer {
    padding: 1rem 3.5rem;
  }

  .viewer-arrow {
    width: 42px;
    height: 42px;
  }

  .viewer-stage img {
    max-width: 92vw;
    max-height: 70vh;
  }
}

/* The whole card opens the viewer, so it should read as clickable. The rail
   itself uses grab/grabbing, which still wins while a drag is in progress. */
.t-card {
  cursor: zoom-in;
}

.t-rail.is-dragging .t-card {
  cursor: grabbing;
}

/* Media with no photos is not clickable. */
.t-media--empty,
.t-card:has(.t-media--empty) {
  cursor: default;
}

@media (prefers-reduced-motion: reduce) {

  .t-stop .t-card {
    transform: none;
    transition: none;
  }

  .t-stop.is-current .t-card {
    transform: none;
  }

  .t-media {
    transition: none;
  }
}
