/* Ensure the container of the image doesn't let the zoomed image overflow */
.zoom-wrapper {
  overflow: hidden;
  transition: overflow 0.5s;
}

.zoom {
  transition: transform 0.5s ease;
}

.zoom:hover {
  transform: scale(1.05);
  /* Slightly enlarge the image on hover */
}

.info {
  max-width: 800px;
  margin: 0 auto;
  float: none !important;
  text-align: justify;
  /* text-justify: inter-word; */
}

.grid+.info {
  margin-top: 2em;
}

img {
  width: 100%;
  display: inline-block;
  border-radius: 15px;
}

.video {
  width: 100%;
  height: 100%;
  border-radius: 15px;
}

/* the page grows and the footer follows it. A short page leaves the footer at
   the bottom of the window rather than 46px above it, which is what the old
   `min-height: calc(100vh - 70px)` did: 70px was a guess at the footer's height
   and the footer is 48px, so the difference showed as a gap. Nothing here is
   pinned - on a long gallery the footer is below the fold, as before. */
.wrapper {
  flex: 1;
  padding-bottom: 2.5rem;
}

footer p {
  margin: 0;
}

footer>p:first-child {
  display: inline-flex;
  flex-grow: 1;
}

footer {
  display: flex;
  /* the row holds a control now, and its paragraphs' default 16px margins were
     being stretched by flex until their content boxes were 8px and the text
     was spilling out of them */
  align-items: center;
  gap: 1em;
  height: 2.5rem;
  padding: 0 1em 0.5em;
  text-align: right;
  /* no width: the footer is a flex item in the body's column and stretches on
     its own. Asking for 100% under content-box makes that the *content* width
     and adds the padding outside it, which is 2em of horizontal scroll on every
     page */
  box-sizing: border-box;
}

body {
  background-color: black;
  text-align: center;
  /* font-family: Georgia, serif; */
  position: relative;
  /* a column the height of the window at minimum, so .wrapper can take up the
     slack and leave the footer sitting on the bottom edge */
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  /* the space above the header belongs to the header, not to the page; see
     .title, which sticks to the viewport and would otherwise leave it behind */
  margin-top: 0;
  /* and the space below belongs to the footer, which carries its own padding.
     Left in place, the default 8px sits outside a body that is already the
     height of the window, and shows as 8px of scroll on a page with nothing
     to scroll */
  margin-bottom: 0;
}

figcaption,
h1,
h2,
h3,
h4,
p {
  color: white;
}

.label-row {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  margin-top: 0px;
  margin-bottom: 0.5em;
}

.center {
  text-align: center;
  margin-top: 0px;
  margin-bottom: 0.5em;
}

.similar {
  margin-top: 0.5em;
  margin-bottom: 0.5em;
}

.nav-pill {
  display: inline-block;
  border: 1px solid white;
  padding: 0.1em 0.5em;
  border-radius: 2em;
  margin-block-end: 0em;
  margin-block-start: 0em;
  margin-bottom: 0.2em;
}

.site-pill {
  display: inline-block;
  border: 1px solid white;
  padding: 0.1em 0.5em;
  border-radius: 5em;
  margin-block-end: 0em;
}

.nav-pill:hover,
.site-pill:hover {
  border: 1px solid white;
}

.nolink,
.nolink:hover,
.buffer:hover {
  border: 1px solid black;
}

.scientific {
  margin-top: 0.67em;
  margin-bottom: 0.67em;
  font-style: italic;
}

.search {
  position: relative;
  display: flex;
  justify-content: center;
  max-width: 600px;
  margin: 0.67em auto;
}

.search-random {
  display: inline-flex;
}

.search-text {
  display: inline-flex;
  flex-grow: 1;
}

#search-bar {
  margin: 0 1em;
  flex-grow: 1;
}

/* the panel floats over the page so opening it never moves the grid */
.search-panel {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 1;

  margin-top: 0.4em;
  background-color: black;
  border: 1px solid #555;
  border-radius: 1em;
  overflow: hidden;
  text-align: left;
}

.search-panel[hidden] {
  display: none;
}

/* the section colour marks the active row, so the frame stays neutral. these
   are scoped names because a bare .gallery would repaint the panel border */
.search-gallery {
  --accent: green;
}

.search-taxonomy {
  --accent: yellow;
}

.search-sites {
  --accent: #fe5a1d;
}

.search-rows {
  max-height: 40vh;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.search-row {
  display: block;
  padding: 0.3em 1em;
  border-left: 3px solid transparent;
  color: #aaa;
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.search-row.active {
  background-color: #161616;
  border-left-color: var(--accent, white);
}

.search-row mark {
  background-color: transparent;
  color: white;
  font-weight: bold;
}

.search-row .search-context {
  color: #777;
  font-style: italic;
}

.search-empty {
  padding: 0.3em 1em;
  color: #888;
}

.search-footer {
  display: flex;
  justify-content: space-between;
  padding: 0.25em 1em;
  border-top: 1px solid #333;
  font-size: 0.8em;
  color: #888;
  user-select: none;
  -webkit-user-select: none;
}

.crosslink {
  text-decoration: underline !important;
  display: block;
  color: white;
}

footer a,
.info a {
  text-decoration: underline !important;
  color: white;
}

.count {
  color: #808080;
  text-align: right;
}

.ref {
  text-align: right;
  font-style: italic;
}

.active {
  border-color: rgb(56, 19, 221);
}

.spacer,
.spacer:hover {
  border: 1px solid black;
}

a:link {
  text-decoration: none;
}

.card {
  border: 1px solid black;
  max-width: 350px;
}

.card:hover {
  border: 1px solid white;
}

#correct_outer > h2 {
  margin-bottom: 0;
}

.correct-name>.card:hover {
  border: 1px solid black;
}

.title {
  position: sticky;
  background-color: black;
  top: 0;
  left: 0;
  width: 100%;
  z-index: 999;
  /* the 8px is the body margin this replaces, carried here so that the gap
     above the pills is the same whether the header is resting or pinned */
  padding: calc(0.2em + 8px) 0em 0.2em;
}

.correct-name {
  justify-content: center;
  height: 100%;
}

#options {
  padding-top: 1em;
}

select {
  border-radius: 2em;
  color: white;
  background-color: black;
  text-align: center;
  height: 3em;
}

.scoring {
  display: flex;
  align-items: center;
  height: 100%;
}

.scoring h3 {
  margin-top: 0;
  margin-bottom: 0;
  margin-left: 1em;
  margin-right: 1em;
}

#control select {
  padding-left: 0.5em;
  padding-right: 0.5em;
}

#control {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(10ch, max-content));
  justify-content: center;
  margin-bottom: 1em;
  /* grid-gap: 0.75rem; */
}

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, max-content));
  justify-content: center;
  grid-gap: 0.75rem;
}

/* Compact grid for pages with few items - forces wrapping on wide screens */
.grid-compact {
  max-width: 1200px;
  margin-left: auto;
  margin-right: auto;
}

.gallery {
  border-color: green;
}

.taxonomy {
  border-color: yellow;
}

.timeline {
  border-color: rgb(56, 19, 221);
}

.stats {
  border-color: rgb(153 19 221);
}

.sites {
  border-color: #fe5a1d;
}

.detective {
  border-color: red;
}

div.skip {
  border-color: gray;
  display: table;
  overflow: hidden;
}

.card img {
  /* Need space for the label */
  height: 86%;
}

#options .card img {
  /* but not on detective */
  height: 100%;
}

.pad-down {
  margin-bottom: 0.5em;
}

@media (max-width: 650px) {

  /* phones and small tablets */
  html {
    font-size: 12px;
  }

  h1 {
    font-size: 1.75em;
  }

  .buffer {
    border: 1px solid black;
  }

  .correct-name {
    justify-content: center;
    height: 100%;
  }

  .grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(48%, max-content));
    justify-content: center;
    grid-gap: 0.75rem;
  }

  /* Don't apply compact layout on mobile - already constrained */
  .grid-compact {
    max-width: none;
  }

  select {
    height: 2em;
  }

  /* switcher pills stretch to fill the width, current page pill grows most */
  .switcher {
    display: flex;
    align-items: center;
    gap: 0.3em;
    padding: 0 0.4em;
  }

  .switcher a {
    flex: 1 1 0;
    min-width: 0;
  }

  .switcher a[aria-current] {
    flex: 2 1 auto;
  }

  .switcher .nav-pill {
    display: block;
    font-size: 1.75em;
    padding-left: 0.2em;
    padding-right: 0.2em;
  }

  .switcher .spacer {
    display: none;
  }
}

@media (max-width: 350px) {

  /* very narrow screens: smaller icons so they stay inside their pills */
  .switcher .nav-pill {
    font-size: 1.4em;
  }
}

@media (max-width: 380px) {

  /* iphones have tiny width */
  h1 {
    font-size: 1.40em;
  }

  h2 {
    font-size: 1em;
  }

  .buffer {
    border: 1px solid black;
  }
}

@media (min-width: 480px) {
  html {
    font-size: 13px;
  }
}

@media (min-width: 768px) {
  html {
    font-size: 14px;
  }
}

@media (min-width: 992px) {
  html {
    font-size: 15px;
  }
}

@media (min-width: 1200px) {
  html {
    font-size: 16px;
  }
}

/* Thumbnail container - 350px preferred but shrinks with grid */
.thumb {
  display: block;
  width: 350px;
  max-width: 100%;
  position: relative;
  padding-top: 75%;
  border-radius: 15px;
  overflow: hidden;
}

.thumb img,
.thumb video {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* a clip lives in /clips/, which the offline bundle never holds, so with the
   radio off it has no frame to paint and the box comes out as a hole in the
   grid. This is the same flat grey the worker serves in place of a thumbnail it
   does not have (PLACEHOLDER in sw.js - keep the two colors together), so a
   video the reader cannot have looks like an image they cannot have. Online it
   is only what shows while the clip is still arriving */
.thumb video {
  background-color: #222;
}

/* Fancybox caption - larger text, better spacing, prevent clipping */
.fancybox-caption {
  font-size: 1.2em;
  overflow: visible !important;
  padding-top: 1em !important;
  padding-bottom: 1em !important;
}

.fancybox-caption__body {
  overflow: visible !important;
  line-height: 2.5;
}

/* Caption items - black background, inline on desktop, block on mobile */
.fancybox-caption a,
.fancybox-caption span {
  display: inline-block;
  padding: 0.3em 0.6em;
  margin: 0.2em;
  border-radius: 0.3em;
  background-color: black;
}

/* Gallery link styling */
.fancybox-caption .caption-gallery {
  color: #90EE90;
  border: 1px solid green;
  text-decoration: none;
}

.fancybox-caption .caption-gallery:hover {
  background-color: rgba(0, 128, 0, 0.3);
  text-decoration: underline;
}

/* Site link styling */
.fancybox-caption .caption-site {
  color: #FFA07A;
  border: 1px solid #fe5a1d;
  text-decoration: none;
}

.fancybox-caption .caption-site:hover {
  background-color: rgba(254, 90, 29, 0.3);
  text-decoration: underline;
}

/* Name (non-link) styling - grey since not clickable */
.fancybox-caption .caption-name {
  color: #ccc;
  border: 1px solid #666;
}

/* Date styling */
.fancybox-caption .caption-date {
  color: #ccc;
  border: 1px solid #666;
}

/* Mobile: stack items vertically */
@media (max-width: 768px) {
  .fancybox-caption a,
  .fancybox-caption span {
    display: block;
    text-align: center;
    margin: 0.3em auto;
    max-width: 90%;
  }

  /* Make video content full-width on mobile (override fancybox inline styles) */
  .fancybox-slide--video .fancybox-content {
    width: 100% !important;
    height: auto !important;
  }

  .fancybox-slide {
    padding: 0 !important;
  }
}

/* Similar species section */
.similar-species {
  margin-top: 2em;
  max-width: 1000px;
  margin-left: auto;
  margin-right: auto;
}

.similar-header {
  color: white;
  margin-bottom: 0.5em;
  font-size: larger;
}

.similar-grid {
  grid-template-columns: repeat(auto-fit, minmax(150px, max-content));
}

.similar-grid .image {
  max-width: 200px;
}

.similar-grid .image img {
  height: auto;
}

/* Installed to a home screen: iOS draws a translucent status bar over the page,
   so the top of the document has to move down out from under the clock. The
   footer and landscape notch need the same treatment. */
@media (display-mode: standalone) {
  body {
    padding-top: env(safe-area-inset-top);
    padding-left: env(safe-area-inset-left);
    padding-right: env(safe-area-inset-right);
  }

  /* stick below the status bar rather than under it, for the same reason the
     header carries its own padding: what is above it has to survive pinning */
  .title {
    top: env(safe-area-inset-top);
  }

  footer {
    padding-bottom: calc(0.5em + env(safe-area-inset-bottom));
  }
}


/* the offline bundle: the page that owns it, and the one mark it leaves on
   every other page.

   The footer indicator replaced a bar fixed over the page, so there is no
   .install-hint any more - installing is one of this indicator's states. */

/* the footer was sized for text and holds a control now. Its paragraphs carry
   the browser default 16px margins, and flex stretch sizes the margin box, so
   they were being squeezed to 8px content boxes with their own text spilling
   out of them - visible or not, that had to go before anything sat beside it */
footer {
  align-items: center;
}

footer p {
  margin: 0;
}

.offline-link {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  flex-shrink: 0;
  margin-left: 1em;
  padding: 0.3em 0.8em;
  border: 1px solid #4a4a4a;
  border-radius: 1em;
  color: white;
  font-size: 0.85rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  text-decoration: none !important;
  white-space: nowrap;
}

/* state in colour and in language both, so neither is load bearing alone */
.offline-link::before {
  content: "";
  flex: none;
  width: 0.5em;
  height: 0.5em;
  border-radius: 50%;
  background-color: currentColor;
}

.offline-link.offline-not-installed {
  border-color: #7a7a7a;
}

.offline-link.offline-not-saved {
  border-color: #3a3a3a;
  color: #9a9a9a;
}

.offline-link.offline-saved,
.offline-link.offline-saving {
  border-color: #2a5f66;
  color: #5fd0e0;
}

/* the only state that asks for anything */
.offline-link.offline-update {
  border-color: #6b4a12;
  color: #f0a830;
}

.offline-link.offline-unfinished {
  border-color: #5e3a2e;
  color: #e0917a;
}

.offline-panel {
  max-width: 34em;
  margin: 2em auto;
  padding: 0 1em;
}

/* the page hides and shows almost everything in here, and the blocks it hides
   are the ones that set display - a class selector beats the [hidden] rule in
   the browser's own stylesheet, so hiding has to be said louder than laying out */
.offline-panel [hidden] {
  display: none !important;
}

/* controls read as controls when their left edges line up, and the site centres
   everything by default */
.offline-card {
  display: flex;
  flex-direction: column;
  gap: 0.85em;
  padding: 1.1em 1.15em;
  /* the site paints its paragraphs white and leaves everything else at the
     default, which on this background is black on black */
  color: white;
  border: 1px solid #333;
  border-radius: 14px;
  text-align: left;
}

.offline-status {
  display: flex;
  align-items: center;
  gap: 0.5em;
  margin: 0;
  font-size: 0.85rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #9a9a9a;
}

.offline-status::before {
  content: "";
  flex: none;
  width: 0.5em;
  height: 0.5em;
  border-radius: 50%;
  background-color: currentColor;
}

.offline-controls.state-saved .offline-status,
.offline-controls.state-saving .offline-status {
  color: #5fd0e0;
}

.offline-controls.state-update .offline-status {
  color: #f0a830;
}

.offline-controls.state-unfinished .offline-status {
  color: #e0917a;
}

.offline-controls.state-error .offline-status {
  color: #e0655a;
}

.offline-controls,
.offline-steps {
  display: flex;
  flex-direction: column;
  gap: 0.85em;
}

.offline-figures {
  margin: 0;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.9rem;
  font-variant-numeric: tabular-nums;
  color: #ccc;
}

.offline-say {
  margin: 0;
  font-size: 1rem;
  line-height: 1.45;
}

.offline-muted {
  color: #ccc;
}

.offline-note {
  margin: 1.1em auto 0;
  font-size: 0.9rem;
  color: #ccc;
}

/* the one bar, and only while something is running */
.offline-bar {
  height: 4px;
  border-radius: 2px;
  background-color: #2a2a2a;
  overflow: hidden;
}

.offline-fill {
  height: 100%;
  width: 0;
  background-color: #5fd0e0;
  transition: width 0.2s linear;
}

.offline-button {
  width: 100%;
  padding: 0.6em 1em;
  border: 0;
  border-radius: 1.5em;
  background-color: white;
  color: black;
  font-family: inherit;
  font-size: 1rem;
  font-weight: 600;
}

.offline-button[disabled] {
  background-color: #2a2a2a;
  color: #6a6a6a;
}

/* removal is not what anyone came here to do */
.offline-quiet {
  align-self: flex-start;
  padding: 0;
  border: 0;
  background: none;
  color: #9a9a9a;
  font-family: inherit;
  font-size: 0.875rem;
  text-decoration: underline;
}

.offline-field {
  margin: 0;
  font-size: 0.8rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #8a8a8a;
}

/* a rule between where the reader stands and what they are choosing. Without
   it the status, the figures and the two tiers read as one undifferentiated
   column, and the choice looks like more status */
.offline-choices {
  display: flex;
  flex-direction: column;
  gap: 0.35em;
  padding-top: 0.9em;
  border-top: 1px solid #333;
}

/* both prices, always: the old checkbox named one tier and priced only that
   one, so the choice being offered was never actually visible */
.offline-choice {
  display: flex;
  align-items: center;
  gap: 0.6em;
  padding: 0.5em 0.7em;
  border: 1px solid #333;
  border-radius: 8px;
  font-size: 0.95rem;
}

.offline-choice:has(:checked) {
  border-color: #5fd0e0;
}

.offline-choice input {
  accent-color: #5fd0e0;
  margin: 0;
}

.offline-cost {
  margin-left: auto;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.9rem;
  color: #ccc;
}

/* installing first is not advice here, it is the order: a home screen app keeps
   its own storage container, so saving from a browser tab fetches it twice */
.offline-step {
  display: flex;
  flex-direction: column;
  gap: 0.55em;
}

.offline-step+.offline-step {
  padding-top: 0.9em;
  border-top: 1px solid #333;
}

.offline-step-head {
  display: flex;
  align-items: center;
  gap: 0.55em;
  margin: 0;
  font-size: 0.85rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.offline-step-head b {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 1.5em;
  height: 1.5em;
  border-radius: 50%;
  background-color: white;
  color: black;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.8rem;
  font-weight: normal;
}

.offline-locked {
  opacity: 0.45;
}

.offline-locked .offline-step-head b {
  background-color: #4a4a4a;
}

.offline-link:focus-visible,
.offline-button:focus-visible,
.offline-quiet:focus-visible,
.offline-choice:focus-within {
  outline: 2px solid #5fd0e0;
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .offline-fill {
    transition: none;
  }
}
