/* === Photography page === */

/* Wider margins than the other cards: photos want breathing room from the frame.
   The padding lives in variables so the album banner can cancel it and bleed to the card edge. */
.profile-card.photo-card {
  --pad-top: 32px;
  --pad-x: 24px;
  --pad-bottom: 36px;
  padding: var(--pad-top) var(--pad-x) var(--pad-bottom);
}

@media (min-width: 700px) {
  .profile-card.photo-card {
    --pad-top: 44px;
    --pad-x: 48px;
    --pad-bottom: 52px;
  }
}

.photo-header {
  margin-bottom: 4px;
}

.photo-header .bio {
  margin-top: 10px;
  max-width: 60ch;
}

/* --- Collection chips: same language as the nav tabs (text + orange underline) --- */
.photo-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 22px;
  margin: 0 0 22px;
}

.photo-chip {
  appearance: none;
  background: none;
  border: 0;
  padding: 4px 0;
  font-family: inherit;
  font-size: 0.875rem;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.6);
  border-bottom: 2px solid transparent;
  cursor: pointer;
  transition: color 150ms ease, border-color 150ms ease;
}

.photo-chip:hover {
  color: var(--text);
}

.photo-chip.active {
  color: var(--text);
  border-bottom-color: var(--accent);
}

.photo-chip:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

/* --- View area: the album list or an open album. Swaps with a short fade --- */
.photo-view {
  transition: opacity 150ms ease;
}

/* While the manifest is still loading, keep the card from collapsing to just the heading */
.photo-view:empty {
  min-height: 60vh;
}

.photo-view.is-switching {
  opacity: 0;
}

/* Inside an album the banner takes over the top of the card: no page header, divider, slider or chips */
.photo-card.in-album .photo-header,
.photo-card.in-album .divider,
.photo-card.in-album .photo-featured,
.photo-card.in-album .photo-filters {
  display: none;
}

/* --- Featured belt: a conveyor of hand-picked photos at their real aspect ratio --- */
.belt-section {
  margin: 0 0 26px;
}

@media (min-width: 700px) {
  .belt-section {
    margin-bottom: 32px;
  }
}

/* The strip: scrolls like any horizontal list; the scrollbar is hidden and the ends fade out */
.belt {
  --belt-h: 140px;
  position: relative;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  overscroll-behavior-x: contain;
  touch-action: pan-x pan-y; /* the page body allows vertical panning only; the strip also pans sideways */
  cursor: grab;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 5%, #000 95%, transparent);
  mask-image: linear-gradient(to right, transparent, #000 5%, #000 95%, transparent);
}

@media (min-width: 700px) {
  .belt {
    --belt-h: 230px;
  }
}

.belt::-webkit-scrollbar {
  display: none;
}

.belt.is-dragging {
  cursor: grabbing;
}

.belt-track {
  position: relative;
  height: var(--belt-h);
  /* width is set by js/photos.js: many viewports wide, re-centred as you scroll near an end */
}

/* Each item is placed by its own transform (js/photos.js), sized to its photo's aspect ratio
   at the strip height so nothing is cropped. Items are kept smaller than the viewport so the
   browser can run their drift on the compositor. */
.belt-item {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  height: var(--belt-h);
  will-change: transform;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.045);
  color: var(--text);
  text-decoration: none;
  -webkit-user-drag: none;
  user-select: none;
  -webkit-user-select: none;
}

.belt-item img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover; /* the box already matches the photo's ratio; this only hides rounding slivers */
  transition: filter 150ms ease;
  pointer-events: none;
}

.belt-caption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 26px 12px 10px;
  background: linear-gradient(to bottom, rgba(5, 5, 9, 0), rgba(5, 5, 9, 0.8));
  pointer-events: none;
}

.belt-title {
  font-family: 'Press Start 2P', monospace;
  font-size: 0.55rem;
  line-height: 1.5;
  letter-spacing: 0.04em;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.belt-album {
  font-size: 0.72rem;
  color: rgba(255, 255, 255, 0.8);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

@media (hover: hover) {
  .belt-item:hover img {
    filter: brightness(1.08);
  }
}

.belt-item:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

/* --- Album banners: cover image with the name on top --- */
.album-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
}

@media (min-width: 700px) {
  .album-list {
    grid-template-columns: 1fr 1fr;
    gap: 18px;
  }
}

/* Up to three albums across on wide screens */
@media (min-width: 1000px) {
  .album-list {
    grid-template-columns: repeat(3, 1fr);
  }
}

.album-card,
.album-banner {
  position: relative;
  display: block;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.045);
  color: var(--text);
  text-decoration: none;
}

.album-card {
  aspect-ratio: 16 / 9;
}

/* Hero banner: bleeds past the card padding to the card's own edges, with the name over a
   gradient at the bottom and the back link floating in the corner */
.album-banner {
  height: 220px;
  margin: calc(-1 * var(--pad-top)) calc(-1 * var(--pad-x)) 24px;
}

@media (min-width: 700px) {
  .album-banner {
    height: clamp(260px, 30vw, 360px);
    margin-bottom: 36px;
  }
}

/* Thin orange rule under the banner, like the card's divider */
.album-banner::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: linear-gradient(to right, transparent, rgba(255, 109, 0, 0.6), transparent);
  z-index: 2;
}

.album-banner .album-text {
  justify-content: flex-end;
  padding: 24px var(--pad-x) 26px;
  gap: 10px;
  background: linear-gradient(to bottom, rgba(13, 13, 21, 0.45) 0%, rgba(13, 13, 21, 0) 30%, rgba(13, 13, 21, 0) 45%, rgba(13, 13, 21, 0.72) 80%, rgba(13, 13, 21, 0.92) 100%);
}

.album-banner .album-name {
  font-size: 1rem;
  line-height: 1.6;
}

@media (min-width: 700px) {
  .album-banner .album-name {
    font-size: 1.35rem;
  }

  .album-banner .album-meta {
    font-size: 0.88rem;
  }
}

.album-cover {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 300ms ease, transform 400ms cubic-bezier(0.2, 0, 0, 1), filter 150ms ease;
}

.album-cover.is-loaded {
  opacity: 1;
}

/* Hero banner: the thumbnail shows as a blurred background while the full image loads */
.album-cover--full {
  opacity: 1;
  background-size: cover;
  background-position: center;
}

/* Darken the top so the name reads over any photo */
.album-text {
  position: absolute;
  inset: 0;
  padding: 18px 20px;
  background: linear-gradient(to bottom, rgba(5, 5, 9, 0.78) 0%, rgba(5, 5, 9, 0.35) 40%, rgba(5, 5, 9, 0) 70%);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  pointer-events: none;
}

/* Album list cards: text sits at the bottom, gradient darkens from the bottom */
.album-card .album-text {
  justify-content: flex-end;
  background: linear-gradient(to top, rgba(5, 5, 9, 0.78) 0%, rgba(5, 5, 9, 0.35) 40%, rgba(5, 5, 9, 0) 70%);
}


.album-name {
  font-family: 'Press Start 2P', monospace;
  font-size: 0.78rem;
  font-weight: 400;
  line-height: 1.5;
  letter-spacing: 0.04em;
  margin: 0;
  color: var(--text);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8), 0 0 12px rgba(0, 0, 0, 0.5);
}

.album-meta {
  margin: 0;
  font-size: 0.78rem;
  color: rgba(255, 255, 255, 0.78);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
}

@media (hover: hover) {
  .album-card:hover .album-cover {
    transform: scale(1.03);
    filter: brightness(1.08);
  }
}

.album-card:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Back link: plain text floating in the banner's top-left corner, same style as the chips */
.album-back {
  position: absolute;
  top: 20px;
  left: var(--pad-x);
  z-index: 3;
  display: inline-block;
  font-size: 0.875rem;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.8);
  text-decoration: none;
  padding: 4px 0;
  border-bottom: 2px solid transparent;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8), 0 0 10px rgba(0, 0, 0, 0.5);
  transition: color 150ms ease, border-color 150ms ease;
}

.album-back:hover {
  color: var(--text);
  border-bottom-color: var(--accent);
}

@media (max-width: 699px) {
  .album-back {
    top: 14px;
  }
}

.album-back:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

/* --- Days within an album: newest first, each under a date that stays pinned while you scroll it.
   The title borrows the Character Ref page's section-title type. --- */
.album-day + .album-day {
  margin-top: 40px;
}

.album-day-title {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 14px;
  row-gap: 4px;
  margin: 0 0 12px;
  padding: 14px 0 10px;
  background: #0d0d15; /* the card's colour, so photos scroll away under it */
  font-family: 'Press Start 2P', monospace;
  font-size: 0.66rem;
  font-weight: 400;
  line-height: 1.5;
  letter-spacing: 0.05em;
  color: var(--accent);
}

/* The date links to that day; it copies the link when clicked */
.album-day-link {
  color: inherit;
  text-decoration: none;
  border-bottom: 2px solid transparent;
  transition: border-color 150ms ease;
}

.album-day-link:hover {
  border-bottom-color: currentColor;
}

.album-day-link:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

.album-day-count {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  font-size: 0.8rem;
  letter-spacing: 0;
  color: rgba(255, 255, 255, 0.55);
}

@media (max-width: 699px) {
  .album-day + .album-day {
    margin-top: 28px;
  }

  .album-day-title {
    font-size: 0.58rem;
    padding: 12px 0 8px;
  }
}

/* --- Justified grid: js/photos.js sets each tile's width/height so rows fill the card exactly --- */
.photo-grid {
  --gap: 8px;
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap);
}

.photo-tile {
  display: block;
  position: relative;
  flex: 0 0 auto;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.045); /* shown until the thumbnail arrives */
}

.photo-tile img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 300ms ease, filter 150ms ease;
}

.photo-tile img.is-loaded {
  opacity: 1;
}

@media (hover: hover) {
  .photo-tile:hover img {
    filter: brightness(1.08);
  }
}

.photo-tile:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* While the page scrolls, tiles sliding under the cursor shouldn't react */
.is-scrolling .photo-grid {
  pointer-events: none;
}

/* === Photo viewer === */
html.pv-open {
  overflow: hidden;
}

.pv {
  --pv-top: 56px;      /* top bar */
  --pv-bottom: 96px;   /* filmstrip */
  --pv-right: 0px;     /* details panel, desktop */
  --pv-thumb: 64px;
  --pv-interval: 4000ms;
  position: fixed;
  inset: 0;
  z-index: 3000;
  background: #050509;
  color: var(--text);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 240ms ease, visibility 0s linear 240ms;
  user-select: none;
  -webkit-user-select: none;
}

.pv.visible {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity 240ms ease;
}

.pv.immersive {
  --pv-top: 0px;
  --pv-bottom: 0px;
}

/* Stage: the photo is fitted inside whatever the chrome leaves free. Hiding the chrome lets it grow. */
.pv-stage {
  position: absolute;
  top: var(--pv-top);
  right: var(--pv-right);
  bottom: var(--pv-bottom);
  left: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 12px;
  overflow: hidden;
  touch-action: none;
  transition: top 320ms cubic-bezier(0.2, 0, 0, 1), bottom 320ms cubic-bezier(0.2, 0, 0, 1), right 320ms cubic-bezier(0.2, 0, 0, 1), padding 320ms cubic-bezier(0.2, 0, 0, 1);
}

.pv.immersive .pv-stage {
  padding: 0;
}

.pv-img {
  display: block;
  max-width: 100%;
  max-height: 100%;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6);
  cursor: zoom-in;
  transform-origin: center;
  transition: transform 320ms cubic-bezier(0.2, 0, 0, 1), opacity 200ms ease;
  will-change: transform;
}

.pv.zoomed .pv-img {
  cursor: grab;
}

.pv.zoomed .pv-img.is-dragging {
  cursor: grabbing;
  transition: none;
}

.pv-img.is-pinching {
  transition: none;
}

.pv.loading .pv-img {
  opacity: 0.35;
}

/* Photo change: fade, with a short slide in the direction of travel */
@keyframes pv-from-right { from { opacity: 0; transform: translateX(14px); } }
@keyframes pv-from-left  { from { opacity: 0; transform: translateX(-14px); } }
@keyframes pv-fade       { from { opacity: 0; } }

.pv-img.swap-right { animation: pv-from-right 240ms ease-out both; }
.pv-img.swap-left  { animation: pv-from-left 240ms ease-out both; }
.pv-img.swap-fade  { animation: pv-fade 240ms ease-out both; }

/* Spinner: only shows if a photo takes a moment */
.pv-spinner {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 28px;
  height: 28px;
  margin: -14px 0 0 -14px;
  border: 2px solid rgba(255, 255, 255, 0.15);
  border-top-color: var(--accent);
  border-radius: 50%;
  opacity: 0;
  pointer-events: none;
  animation: pv-spin 800ms linear infinite;
  transition: opacity 200ms ease;
}

.pv.loading .pv-spinner {
  opacity: 1;
  transition-delay: 250ms;
}

@keyframes pv-spin { to { transform: rotate(360deg); } }

/* --- Chrome: top bar, arrows, filmstrip. All fade out together in immersive mode --- */
.pv-top,
.pv-arrow,
.pv-film {
  transition: opacity 260ms ease, transform 260ms ease, visibility 0s linear 0s;
}

.pv.immersive .pv-top,
.pv.immersive .pv-arrow,
.pv.immersive .pv-film {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 260ms ease, transform 260ms ease, visibility 0s linear 260ms;
}

.pv.immersive .pv-top  { transform: translateY(-8px); }
.pv.immersive .pv-film { transform: translateY(8px); }

.pv-top {
  position: absolute;
  top: 0;
  left: 0;
  right: var(--pv-right);
  height: 56px;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 0 10px 0 20px;
}

.pv-counter {
  font-family: monospace;
  font-size: 0.8rem;
  color: rgba(255, 255, 255, 0.55);
  letter-spacing: 0.04em;
  flex-shrink: 0;
}

.pv-title {
  font-size: 0.9rem;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.85);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
  min-width: 0;
}

.pv-actions {
  display: flex;
  align-items: center;
  gap: 2px;
  margin-left: auto;
  flex-shrink: 0;
}

.pv-btn {
  appearance: none;
  background: none;
  border: 0;
  width: 40px;
  height: 40px;
  border-radius: 6px;
  color: rgba(255, 255, 255, 0.7);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: color 150ms ease, background 150ms ease;
}

.pv-btn svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.pv-btn:hover {
  color: var(--text);
  background: rgba(255, 255, 255, 0.08);
}

.pv-btn[hidden] {
  display: none;
}

.pv-btn[aria-busy="true"] {
  color: var(--accent);
  opacity: 0.6;
  cursor: progress;
}

.pv-btn[aria-pressed="true"] {
  color: var(--accent);
}

.pv-btn:focus-visible,
.pv-arrow:focus-visible,
.pv-thumb:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Icon pairs: show one or the other depending on state */
.pv .icon-pause, .pv .icon-zoom-out { display: none; }
.pv.playing .icon-play, .pv.zoomed .icon-zoom-in { display: none; }
.pv.playing .icon-pause, .pv.zoomed .icon-zoom-out { display: block; }

/* Slideshow progress: a thin line at the top */
.pv-progress {
  position: absolute;
  top: 0;
  left: 0;
  height: 2px;
  width: 0;
  background: var(--accent);
  z-index: 5;
  pointer-events: none;
}

.pv.playing .pv-progress {
  animation: pv-progress var(--pv-interval) linear forwards;
}

@keyframes pv-progress { from { width: 0; } to { width: 100%; } }

/* Arrows: round, like the ref-sheet lightbox */
.pv-arrow {
  position: absolute;
  top: 50%;
  margin-top: -22px;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.18);
  color: #fff;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0.65;
  z-index: 4;
}

.pv-arrow svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.pv-arrow:hover {
  background: rgba(0, 0, 0, 0.82);
  opacity: 1;
}

.pv-prev { left: 20px; }
.pv-next { right: calc(var(--pv-right) + 20px); transition: right 320ms cubic-bezier(0.2, 0, 0, 1), opacity 260ms ease, transform 260ms ease; }

@media (hover: none) and (pointer: coarse) {
  .pv-arrow { display: none; }
}

/* Filmstrip */
.pv-film {
  position: absolute;
  left: 0;
  right: var(--pv-right);
  bottom: 0;
  height: 96px;
  display: flex;
  align-items: center;
  justify-content: safe center;
  gap: 6px;
  padding: 16px 20px;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  touch-action: pan-x;
}

.pv-film::-webkit-scrollbar {
  display: none;
}

.pv-thumb {
  appearance: none;
  flex: 0 0 auto;
  height: var(--pv-thumb);
  aspect-ratio: 3 / 2; /* overridden per thumb */
  padding: 0;
  border: 0;
  border-bottom: 2px solid transparent;
  background: rgba(255, 255, 255, 0.05);
  cursor: pointer;
  opacity: 0.45;
  box-sizing: content-box;
  transition: opacity 150ms ease, border-color 150ms ease;
}

.pv-thumb img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.pv-thumb:hover {
  opacity: 0.8;
}

.pv-thumb.active {
  opacity: 1;
  border-bottom-color: var(--accent);
}

/* --- Details panel --- */
.pv-info {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 320px;
  background: rgba(13, 13, 21, 0.97);
  border-left: 1px solid var(--card-border);
  padding: 20px 22px 28px;
  overflow-y: auto;
  transform: translateX(100%);
  visibility: hidden;
  transition: transform 320ms cubic-bezier(0.2, 0, 0, 1), visibility 0s linear 320ms;
  z-index: 6;
}

.pv.info-open {
  --pv-right: 320px;
}

.pv.info-open .pv-info {
  transform: none;
  visibility: visible;
  transition: transform 320ms cubic-bezier(0.2, 0, 0, 1);
}

.pv-info-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 18px;
}

.pv-info-label {
  font-family: 'Press Start 2P', monospace;
  font-size: 0.65rem;
  color: var(--accent);
  letter-spacing: 0.05em;
}

.pv-info-close {
  width: 32px;
  height: 32px;
  margin-right: -8px;
  font-size: 1.1rem;
  line-height: 1;
}

.pv-info-title {
  font-size: 1rem;
  font-weight: 600;
  margin: 0 0 8px;
  color: var(--text);
}

.pv-info-caption {
  font-size: 0.88rem;
  line-height: 1.6;
  color: var(--text-muted);
  margin: 0 0 20px;
}

.pv-meta {
  margin: 0 0 22px;
  font-size: 0.85rem;
}

.pv-meta-row {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 8px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.07);
}

.pv-meta-row:first-child {
  border-top: 1px solid rgba(255, 255, 255, 0.07);
}

.pv-meta dt {
  color: var(--text-muted);
  font-weight: 700;
  flex-shrink: 0;
}

.pv-meta dd {
  margin: 0;
  text-align: right;
  color: var(--text);
}

/* --- Phones: details become a bottom sheet, chrome gets shorter --- */
@media (max-width: 699px) {
  .pv {
    --pv-top: 52px;
    --pv-bottom: 76px;
    --pv-thumb: 48px;
  }

  .pv.info-open {
    --pv-right: 0px;
  }

  .pv-top {
    padding-left: 16px;
  }

  .pv-title {
    display: none;
  }

  .pv-film {
    height: 76px;
    padding: 12px 16px;
  }

  .pv-info {
    top: auto;
    left: 0;
    right: 0;
    width: auto;
    max-height: 62%;
    border-left: 0;
    border-top: 1px solid var(--card-border);
    border-radius: 12px 12px 0 0;
    transform: translateY(100%);
  }
}

/* --- Reduced motion --- */
@media (prefers-reduced-motion: reduce) {
  .pv,
  .pv-stage,
  .pv-img,
  .pv-top,
  .pv-arrow,
  .pv-film,
  .pv-info,
  .photo-tile img {
    transition: none;
  }

  .pv-img.swap-right,
  .pv-img.swap-left,
  .pv-img.swap-fade {
    animation: none;
  }

  .photo-view,
  .album-cover {
    transition: none;
  }
}
