.gallery-card {
  position: relative;
  display: inline-block;
  padding: 0;
  margin: 0.6vw;
  border-radius: 20px;
  width: 25vw;
  height: fit-content;
}

.gallery-card:hover {
  box-shadow: 0 4px 8px 0 rgb(0 0 0 / 10%), 0 6px 20px 0 rgb(0 0 0 / 5%);
}

.validate-agree {
  background-color: var(--color-pine-500);
}

.validate-disagree {
  background-color: #eb734d;
}

.validate-unsure {
  background-color: var(--color-asphalt-100);
}

/*
We make sure that the image holder is positioned relatively so that the validation menu can be positioned absolutely
with respect to the image holder. This allows the validation menu to be placed over the actual image (like an overlay).
*/
.image-holder {
  cursor: pointer;
  position: relative;
  overflow: hidden;
  aspect-ratio: 3 / 2; /* Match the Explore canvas ratio (720x480). */
  --gallery-marker-size: clamp(16px, 1.1vw, 22px);
}

.gallery-card:hover::after {
  opacity: 1;
}

.static-gallery-image {
  width: 100%;
  height: 100%;
  object-fit: cover; /* Fills 3:2 container; crops excess from Google's 4:3 images. */
  border-top-left-radius: 20px;
  border-top-right-radius: 20px;
}

#gallery-validation-button-holder {
  display: flex;
  flex-flow: row wrap;
  justify-content: center;
  position: absolute;
  bottom: 0;
  width: 100%;
  height: 14%;
  z-index: 2;
}

#gallery-card-agree-button {
  width: 33%;
  border-right: 1px solid #dcdbdb;
  background-color: var(--color-pine-500);
  color: var(--color-asphalt-500);
}

#gallery-card-disagree-button {
  width: 34%;
  background-color: #eb734d;
  color: var(--color-asphalt-500);
}

#gallery-card-unsure-button {
  border-left: 1px solid #dcdbdb;
  width: 33%;
  background-color: var(--color-asphalt-100);
  color: var(--color-asphalt-500);
}

.card-header {
  display: flex;

  /* Baseline, not centered: the two sit at different sizes, so lining up the text they sit on reads as one line. */
  align-items: baseline;
  justify-content: space-between;
  gap: 0.4vw;
  padding: 5px 5px 3px 7px;
  font: var(--text-body-bold);
  font-size: 1vw;
}

/* The label type is what the card is about, so it keeps its width and the neighborhood beside it gives way. */
.card-header__type {
  flex-shrink: 0;
  line-height: 1.2; /* Tokens carry a fixed line-height, which the vw font sizes here would otherwise pad out. */
}

/* The neighborhood a label sits in, opposite its type: quieter than the type, and cut off rather than wrapped so a
   long name can't push the type around or grow the card. */
.card-location {
  display: flex;

  /* The pin's bottom edge is its baseline, so baseline alignment stands it on the text's baseline. */
  align-items: baseline;
  gap: 0.2vw;
  font: var(--text-small-regular);
  font-size: 0.72vw;
  font-weight: 400;
  line-height: 1.2;
  color: var(--color-neutral-600);
  min-width: 0;
  text-decoration: none;
}

.card-location:hover,
.card-location:focus-visible {
  color: var(--color-asphalt-500);
  text-decoration: underline;
}

.card-location:focus-visible {
  outline: 2px solid var(--color-asphalt-400);
  outline-offset: 2px;
  border-radius: 2px;
}

/* Sized in em so the pin tracks the name's size, and near the name's cap height rather than its full em box —
   a glyph fills only ~0.7em of that box, so a 1em pin reads as oversized next to the text. */
.card-location__pin {
  width: 0.85em;
  height: 0.85em;
  flex-shrink: 0;
  opacity: 0.7;
}

/* A validated card takes the verdict's color across the whole info band, where the muted grey washes out. The line
   falls back to the same ink as the severity and tags beside it, which that band is already built to carry. */
.validate-agree .card-location,
.validate-disagree .card-location,
.validate-unsure .card-location {
  color: inherit;
}

.card-location__name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.card-info {
  padding-bottom: 0.5vw;
  padding-left: 0.5vw;
  padding-right: 0.5vw;
  color: var(--color-asphalt-500);
  border-width: 0 1px 1px;
  border-color: #dcdbdb;
  border-style: solid;
  border-bottom-left-radius: 20px;
  border-bottom-right-radius: 20px;
  cursor: default;
}

.gallery-card:hover > .card-info {
  border-width: 0; /* Using a drop shadow on hover, and we don't need both the border and shadow. */
}

.card-data {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: row;
  font: var(--text-small-regular);
  font-size: 0.6vw;
  height: 2.5vh;
}

.card-severity {
  display: flex;
  align-items: center;
  height: 100%;
  flex-direction: row;
  flex: 0 0 auto; /* Takes only the space needed for content */
  padding-left: 7px;
}

.label-severity-header {
  padding-right: .25vw;
}

.label-severity-content {
  display: flex;
  flex-direction: row;
}

.no-severity-header {
  opacity: 0.6;
}

.card-tags {
  display: flex;
  align-items: center;
  height: 100%;
  flex-direction: row;
  flex: 1; /* Takes all remaining space */
  right: 0;
  padding-left: 7px;
}

.label-tags-header {
  padding-right: .25vw;
}

.label-tags-holder {
  display: flex;
  align-items: center;
  overflow-y: auto;
  width: 100%;
  flex-flow: row wrap;
  flex: 1;
  min-width: 0;
}

.label-tags-content {
  text-overflow: ellipsis;
  width:fit-content;
  color: var(--color-neutral-black);
}

.gallery-marker-wrapper {
  position: absolute;
  width: var(--gallery-marker-size);
  height: var(--gallery-marker-size);
  pointer-events: none;
}

.gallery-marker-wrapper .label-icon-gallery {
  width: 100%;
  height: 100%;
  position: absolute;
  left: 0;
  top: 0;
  z-index: 1;
}

.gallery-marker-wrapper .ai-icon-marker {
  pointer-events: auto;
}


.card-validation-info {
  display: flex;
  align-items: center;
  height: 100%;
  flex-direction: row;
  flex: 0 0 19%; /* Replaces width: 19%; */
  padding-left: 7px;
}

.validation-info-content {
  display: flex;
  flex-direction: row;
  gap: 8px;
}

.validation-section-content {
  display: flex;
  width: 50%;
  height: 100%;
  flex-direction: column;
  cursor: pointer;

  /* Prevent text selection. */
  -webkit-user-select: none; /* Safari */
}

.validation-info-count-container {
  position: relative;
  display: flex;
  flex-direction: row;
  align-items: center;
  height: 100%;
  gap: 2px;
}

.validation-info-count {
  display: flex;
  flex: 1;
  height: 100%;
  flex-direction: column;
  justify-content: center;
}

/* The validation SVGs have ~30% internal whitespace in their viewBox, so size
   them to fill the section height rather than using the old PNG-based width %. */
.validation-info-image {
  height: 100%;
  width: auto;
  flex: 0 0 auto;
}

.validation-button, .validation-button-selected {
  opacity: 0;
  font: var(--text-body-bold);
  font-size: 0.75vw;
  background-color: var(--color-neutral-white);
  border-style: none;
  color: var(--color-asphalt-500);
  transition: opacity 120ms ease;
}

.gallery-card:hover .validation-button {
  opacity: 0.75;
}

.gallery-card:hover .validation-button:hover {
  opacity: 0.95;
}

.gallery-card:hover .validation-button-selected {
  opacity: 1;
  background-color: gray;
}

/* Read-only mode: the card shows the viewer's own label, so validating isn't allowed. The UI stays in place but
   appears disabled, matching the Gallery expanded view / LabelMap popup. */
.gallery-card--readonly #gallery-card-agree-button,
.gallery-card--readonly #gallery-card-disagree-button,
.gallery-card--readonly #gallery-card-unsure-button {
  background-color: #E2E2E2;
  color: rgb(0 0 0 / 40%);
  cursor: default;
}

.gallery-card--readonly .card-validation-info {
  opacity: 0.5;
}

.gallery-card--readonly:hover .validation-button:hover {
  opacity: 0.75; /* No hover bump in readonly: nothing to validate. */
}

.gallery-card--readonly .validation-section-content {
  cursor: default;
}

.gallery-card--readonly .validation-info-image {
  pointer-events: none;
}

.expanded-view-background-card {
  opacity: 0.5;
}

.severity-circle {
  color: var(--color-neutral-white);
  border: 1px solid var(--color-asphalt-500);
  width: 0.7vw;
  height: 0.7vw;
  border-radius: 50%;
  text-align: center;
  margin: 2px;
  font-size: 0.9vw;
}

.no-severity-circle {
  opacity: 0.4;
}

#current-severity {
  border: 2px solid var(--color-asphalt-500);
  background-color: var(--color-asphalt-500);
  color: var(--color-asphalt-500);
}
/* The Gallery's filter column. The controls themselves come from the shared sidebar (filter-sidebar.css, #4585);
   what's here is only the column that holds them, since the Gallery scrolls its sidebar with the page instead of
   floating it over a map. */

#card-filter {
  /* Fills the column its own padding included, so it still fits once the sidebar shows a scrollbar. */
  box-sizing: border-box;
  width: 100%;

  /* The 40px of headroom matches the map sidebar's, so the two panels start at the same distance from the navbar. */
  padding: 40px 5px 5px;
}

.gallery-filter-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin: 0 0 16px;
}

#filter-header {
  font: var(--text-subtitle-bold);
  color: var(--color-neutral-black);
  margin: 0;
}

#clear-filters {
  gap: 4px;
}

/* .button-ps sets `display: inline-flex`, which outranks the browser's `[hidden] { display: none }`, so the button
   would stay on screen while no filter is applied without this. */
#clear-filters[hidden] {
  display: none;
}
#gallery {
  display: flex;

  /* `clip`, not `hidden`: `hidden` would make this a scroll container, which disables the sidebar's sticky. */
  overflow-x: clip;
}

#labels-not-found {
  display: none;
}

.paging {
  display: inline-block;
  font-size: 30px;
  background-color: var(--color-neutral-white);
  border-radius: 5px;
  border-width: 1px;
  margin: 0 2px;
}

.paging:disabled {
  border-width: 0.2px;
  opacity: 0.5;
}

#horizontal-line {
  border-bottom: 1px solid gray;
}

/* Sticky, not fixed, so the column keeps its place in the flow: the page is then always at least as tall as the
   sidebar and the footer starts below it, even when the results fill less than one row of cards (#4778). Sticking
   ends at #gallery's bottom edge, so the sidebar never rides down over the paging controls or footer. */
.sidebar {
  position: sticky;
  top: calc(var(--navbar-height) + var(--test-banner-height, 0px));

  /* A stretched flex item is as tall as the row and so has nowhere to stick to; this keeps it its own height. */
  align-self: flex-start;
  flex: none;

  /* border-box so the padding comes out of the 275px the cards are laid out against, rather than widening the
     column past it. */
  box-sizing: border-box;
  width: 275px;
  padding-left: 10px;
}

#labels-not-found-text {
  position: absolute;
  width: 100%;
  text-align: center;
  padding-top: 20px;
}

.page-control {
  padding-bottom: 15px;
  display: flex;
  justify-content: center;
  margin: auto;
  width: 25%;
}

.gallery-footer {
  padding-top: 5px;
  padding-bottom: 10px;
  position: relative;
  width: 100%;
  min-height: 40px;
  text-align: center;
  color: #585c63;
  font-size: 12px;
  font-style: italic;
  line-height: 1.6em;
  font-family: raleway, sans-serif;
}

#footer-spacing {
  padding-top: 100px;
}

.grid-container {
  display: grid;
  grid-template-areas:
    "main"
    "paging";
  gap: 2px;
  padding: 0 10px 10px;
}

/* Takes the rest of the flex row beside the sidebar; min-width: 0 lets it shrink instead of forcing #gallery wider. */
#gallery-content {
  flex: 1;
  min-width: 0;
}

/* Gallery's inline expanded view — a fixed overlay floating over the card grid (the grid never reflows around it;
   cards to its left stay visible and clickable for browsing). The max caps keep the panel content-scaled on large
   monitors — uncapped, the viewport-derived sizing balloons the card (and its flex-grown pano) on ≥27" screens
   while laptops sit under the caps either way. */
.gallery-expanded-view {
  position: fixed;
  top: calc(var(--navbar-height) + 1vh);
  right: 3vw;
  z-index: 1000; /* Above the cards and sticky sidebar, below the navbar (--navbar-z-index: 1030). */

  /* Content-hugging height (the pano's fixed aspect ratio drives it), like the modal: no orphaned white space
     when sections collapse. Short viewports scroll inside the card instead of shrinking the pano. */
  height: auto;
  max-height: calc(100vh - var(--navbar-height) - 2vh);
  width: 52vw;
  max-width: 720px;
  border-radius: 12px;
  background: var(--color-neutral-white);
  box-shadow: 0 12px 40px rgb(0 0 0 / 35%);
  visibility: hidden;
}

.cards {
  display: flex;
  flex-flow: row wrap;
}

/* There is no specific intended function for hover/click on labels on the gallery page.
We should allow the pointer events to pass through and behave the same way as they do on the background. */
.label-icon-gallery, .icon-outline {
  pointer-events: none;
}

.ai-icon-marker {
  position: absolute;
  width: clamp(12px, 0.75vw, 16px);
  height: clamp(12px, 0.75vw, 16px);
  z-index: 3;
  pointer-events: auto;
  cursor: pointer;
}

.ai-icon-marker-card {
  top: -6px;
  left: -5px;
}
.gallery-tag {
  display: inline-block;
  margin: 2px;
  padding: 0 5px;
  border: 1px solid var(--color-neutral-black);
  border-radius: 10px;
  text-align: left;
  background-color: var(--color-neutral-white);
  color: var(--color-neutral-black);
  width: fit-content;
  white-space: nowrap;
  max-width: 98%;
  overflow: hidden;
  text-overflow: ellipsis;
}

.thumbnail-tag {
  cursor: default;
  font-weight: bold;
  padding: 1px 5px;
  color: var(--color-asphalt-500);
}

.not-added {
  background-color: var(--color-neutral-white);
  font-size: .6vw;
  margin: 1px;
}

.additional-count {
  margin: 3px -2px;
  border-style: none;
  font-weight: bold;
  cursor: pointer;
  background-color: inherit;
}

.additional-tag-popover {
  width: fit-content;
  max-width: 250px;
}

.additional-tag-popover-content {
  padding: 5px 10px;
}
