/* Shared PHP-rendered component hooks. */
[x-cloak],[hidden]{display:none!important}.download-error[hidden]{display:none!important}[data-primary-navigation][data-open]{display:flex}.download-spinner{display:inline-block;width:1em;height:1em;border:.14em solid currentColor;border-right-color:transparent;border-radius:50%;animation:snaptik-spin .7s linear infinite}@keyframes snaptik-spin{to{transform:rotate(1turn)}}

/* Submit status, slideshow archive and retry --------------------------------
   Ported from snaptik.monster. The behaviour is identical; the colours are this
   site's own, so nothing here changes how the page looks apart from adding the
   parts that were missing.

   Timed in CSS rather than JavaScript: a form POST leaves the document waiting
   to be replaced and browsers suspend timers in that state, so anything driven
   by setTimeout stops after the first step. */
.dl-progress{
  position:relative;overflow:hidden;
  height:3px;margin:.85rem 0 0;border-radius:999px;
  background:var(--color-border,rgba(0,0,0,.12))}
.dl-progress>span{
  display:block;height:100%;width:0;border-radius:inherit;
  background:linear-gradient(90deg,var(--color-primary,#2563eb),var(--color-accent,#7c3aed));
  animation:snaptik-progress 12s cubic-bezier(.25,.8,.35,1) forwards}
/* Stops short of the end on purpose: the bar cannot know when the server will
   answer, and a full bar that then sits still reads as a hang. */
@keyframes snaptik-progress{
  0%{width:6%} 10%{width:34%} 30%{width:58%} 60%{width:76%} 100%{width:93%}
}

.dl-status{
  position:relative;height:1.4rem;margin:.55rem 0 0;
  font-size:.9rem;line-height:1.4;text-align:center;color:var(--color-page-muted,#5b6472)}
/* One animation per message, all four handovers inside the first six seconds.
   The final message has no successor, so it fades in and holds. */
.dl-status>span{
  position:absolute;inset-inline:0;top:0;opacity:0;
  animation-name:snaptik-status-step;animation-timing-function:linear;
  animation-fill-mode:forwards}
.dl-status>span:nth-child(1){animation-delay:0s;animation-duration:1s}
.dl-status>span:nth-child(2){animation-delay:.8s;animation-duration:1.2s}
.dl-status>span:nth-child(3){animation-delay:1.8s;animation-duration:1.6s}
.dl-status>span:nth-child(4){animation-delay:3.2s;animation-duration:2.5s}
.dl-status>span:nth-child(5){animation-delay:5.5s;animation-duration:.4s;
  animation-name:snaptik-status-last}
@keyframes snaptik-status-step{0%{opacity:0}18%{opacity:1}82%{opacity:1}100%{opacity:0}}
@keyframes snaptik-status-last{from{opacity:0}to{opacity:1}}

@media(prefers-reduced-motion:reduce){
  .dl-progress>span{animation:none;width:45%}
  .dl-status>span{animation:none;opacity:0}
  .dl-status>span:nth-child(1){opacity:1}
}

/* The retry button is a plain submit tied to the form by its id, so it repeats
   the request exactly and still works with JavaScript disabled. */
/* The error notice above is fit-content and centred, so the button matches
   its width rather than spanning the whole column. */
.err-retry{margin:.75rem auto 0;max-width:22rem;text-align:center}
.err-retry button{cursor:pointer}

/* Sits with the image grid it belongs to. */
.zip-btn{grid-column:1/-1;width:100%;margin:.25rem 0 .5rem;cursor:pointer}
.zip-btn[disabled]{opacity:.65;cursor:progress}

/* In-page anchors on iOS ---------------------------------------------------
   The theme sets overflow-x:hidden on both html and body. On iOS Safari that
   pair moves the scrolling element, and href="#id" quietly stops working — the
   "back to form" button did nothing.

   overflow-x:clip prevents the same horizontal overflow without creating a
   scroll container, so anchors keep working. Loaded after main.css, so this
   wins; a browser that does not know `clip` drops the declaration and keeps the
   original `hidden`, where the script below takes over. */
.site-body{overflow-x:clip}
