/* =====================================================================
/* Scholarly slideshow viewer © 2026 Michael Bycroft. Written with help from Claude (Anthropic).
   Free to reuse for non-commercial purposes provided this notice is kept. If you use this,
   I'd love to hear about it! Contact: m.bycroft@warwick.ac.uk*/

/* =====================================================================
   slideshow.css - all the slideshow's styling
   Loaded by the head box on Sitebuilder (a single <link> line) and by
   slideshow_test.html when you preview on your own computer.
   ===================================================================== */

  /* Colours used throughout (search for these to restyle):
     #2d2d2d dark panel background | #9a9a9a button grey | #fcfbfb button hover
     #e5e4e4 / #d2d1d1 text on the dark panel | #818181 thin border lines */

  * {
    box-sizing: border-box;
  }
  
  /* ===== FEATURE BLOCK: large image + title at the top of the page.
     Stacks vertically on narrow screens (see the max-width: 600px rule just below). ===== */
  
  .feature {
    width: 100%;
    display: flex;
    align-items: center;
  }
  
  .image-box img {
    display: block;
    max-width: 300px;
    width: 100%;
    height: auto;
  }
  
  .title-box {
    flex: 1;
    padding-left: 30px;
    text-align: left;
    margin-top: 0;
  }
  
  .title-box h2 {
      margin: 0 !important;
    margin-bottom: 10px !important;
  }
  
    .title-box p {
  }
  
  
  /* ===== GALLERY: one thumbnail per series.
     .thumb width sets the thumbnail size; gap (above) sets the spacing. ===== */
  
  .gallery {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 30px;
    padding: 20px 0 0 0;
  }
  
  .thumb {
    width: 200px;
    margin-bottom: 20px;
  }
  
  .thumb h4 {
    margin: 15px 0 0 0 !important;
    text-align: center !important;
  }
  
  .thumb img {
    width: 200px;
    display: block;
  }

  .thumb-week {
    margin: 8px 0 0 0;        /* gap between the title and the week text */
    text-align: center !important;
    font-size: 11pt;
  }


    
  /* Stack below image once container gets too narrow */
  @media (max-width: 600px) {
    .feature {
      flex-direction: column;
      align-items: flex-start;
      padding-bottom: 20px;
    }
  
    .title-box {
      margin-left: 0px;
      padding-top: 10px;
      text-align: left;
      width: 300px;
    }

    .thumb {self-align: left}
    .thumb img {self-align: left}
    .thumb-week, .thumb h4 {text-align: left !important; padding-left: 15px !important}
  }
  
  
  /* ===== MODAL: the full-screen slideshow overlay =====
     Hidden until JS sets display:block. JS then adds the class .modal-visible,
     and the transition below fades it in. (Fade length: 0.25s here, and 250 in closeModal() in the script.) */
  
  .modal {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    bottom: 0;       /* height = top to bottom of what is actually visible. NOT 100vh/100dvh: on real phones those
                        units can be wrong (taller than the visible area, especially around fullscreen), which
                        made the slide too tall: photo cut off, caption squashed, nav row pushed off screen.
                        In true fullscreen the browser sizes this element to the screen itself. */
    z-index: 1000;
    overflow: hidden;
    opacity: 0;
    transform: scale(0.96);
    transition: opacity 0.25s ease, transform 0.25s ease;
}

  .modal.modal-visible {
    opacity: 1;
    transform: scale(1);
  }
  
  /* ===== SLIDES =====
     Each slide is a row: [image] [caption panel], plus the nav panel pinned to the slide's right edge.
     JS shows one slide at a time (display: flex) and hides the rest (display: none). */
  .mySlides {
      position: relative;               /* nav panel is positioned against the slide */
      --nav-w: 40px;                    /* width of the nav panel */
      padding-right: var(--nav-w);      /* reserves the strip the nav panel sits in */
      display: flex;
      justify-content: center;  /* centers the image+caption pair as a
                                     unit, so leftover space from a
                                     narrow/portrait image splits evenly
                                     on both sides instead of only on
                                     the right */
      width: 100%;
      height: 100%;    /* exactly as tall as the modal (see .modal above), whatever the phone says 100vh is */
      overflow: hidden;
      background-color: #2d2d2d;  /* matches .caption-container's own
                                       background, so any leftover space
                                       next to a narrow/portrait image
                                       blends in rather than showing as
                                       a blank gap */
  }
  
  /* The image "window". It clips the photo when zoomed in; the zoom script moves and scales
     the <img> inside it, so nothing here needs changing for zoom to work. */
  .image-container {
          height: 100%;
          flex-shrink: 0;
          transform: translateX(-1px);
          position: relative;
          overflow: hidden;          /* clips the zoomed image */
          user-select: none;
          -webkit-user-select: none;
          -webkit-user-drag: none;
          }

  /* The grey side borders now live on an overlay, because borders on the
     <img> itself would be scaled up along with the zoom. */
  .image-container::after {
          content: '';
          position: absolute;
          inset: 0;
          border-left: 1px solid #818181;
          border-right: 1px solid #818181;
          pointer-events: none;
          }
  
  .image-container img {
          display: block;
          height: 100%;
          width: auto;
          max-width: 100%;
          object-fit: contain;
          transform-origin: 0 0;
          pointer-events: none;      /* drags register on the container, not the <img> */
          user-select: none;
          -webkit-user-select: none;
          }

  .image-container.zoomable           { touch-action: none;     /* lets us handle pinch ourselves */
                                        cursor: zoom-in; }      /* magnifying glass: click to zoom to the clicked spot */
  .image-container.can-pan            { cursor: grab; touch-action: none; }   /* once zoomed in: open hand (this rule overrides zoom-in) */
  .image-container.can-pan.dragging   { cursor: grabbing; }

  .image-container > img:not(.loaded) { opacity: 0; }  /* fade in the image once it's loaded (JS adds .loaded) in case of slow load so doesn't 'paint down'*/
  .image-container > img { transition: opacity 0.3s ease; }

    /* ===== LAYERS: overlay images on top of the photo =====
     .layers is exactly the size of the fitted photo and gets the same zoom transform as the photo (set in render()).
     The long selector beats the general '.image-container img' rules above and in the portrait block. */
     .layers {
      position: absolute;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
      transform-origin: 0 0;
      pointer-events: none;
      }
.image-container .layers .layer {
      position: absolute;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
      max-width: none !important;
      object-fit: fill;
      opacity: 0;                         /* JS sets the sheet's opacity when the layer is switched on */
      transition: opacity 0.4s ease;      /* fade in/out time */
      pointer-events: none;
      }
  
         /* ===== CAPTION PANEL =====
            Right of the image in landscape, below it in portrait. Holds the scrolling text (.info)
            and the nav panel (.nav-container). In landscape the nav panel is pulled out of the flow
            and pinned to the slide's right edge; in portrait it sits below the text. */
  .caption-container {
          flex: 1;
          min-width: 0;
          max-width: 500px;  /* caption's own 400px + its 20px left/right
                                 padding — keeps the dark panel itself from
                                 ballooning out when a narrow/portrait
                                 image leaves lots of leftover width */
          padding: 20px 3px 0px 20px;
  
          display: flex;
          align-items: flex-start;
          justify-content: left;
          overflow: hidden;      /* the panel itself no longer scrolls: only .info does */
          background-color: #2d2d2d;

          font-family: Garamond, "EB Garamond", "Adobe Garamond Pro", "Noto Serif", "Roboto Slab", -apple-system, BlinkMacSystemFont, serif;
          }

  /* Portrait phones: stack image above caption instead of side-by-side.
     No orientation-forcing here — the layout simply follows whichever
     way the phone is actually held, so a rare portrait-shaped image
     would still display correctly if one's ever added. */
  @media (orientation: portrait) {
    .mySlides {
      flex-direction: column;
      padding-right: 0;
    }

    .image-container {
      width: 100%;
      height: auto;
      flex-shrink: 0;
    }

    .image-container img {
      width: 100%;
      height: auto;
      max-width: none;
    }

    .caption-container {
      flex: 1;
      min-height: 0;   /* lets this flex item's own overflow-y:auto scroll
                           within its share of the remaining vertical
                           space, instead of being pushed taller than it */
      width: 100%;
      border-top: 1px solid #818181;
      overflow-x: hidden;  /* caption text should only ever scroll
                               vertically, never sideways */
    }
  }

  /* The scrolling text area: the only part of the panel that scrolls.
     Inside are .maintext (the caption) and .list (the series menu); JS toggles which one shows. */
  .info {
    display: block;
    flex: 1 1 auto;
    min-height: 0;           /* lets it shrink and scroll instead of growing past the panel */
    overflow-y: auto;        /* menu or main text scrolls here */
    overflow-x: hidden;
    margin-bottom: 0px; 
    scrollbar-gutter: stable; /*so scrollbar doesn't change text width*/
    padding-right: 10px;
  }

  /* Slim light-grey scrollbar: just a thumb, no track and no arrows */
  .info::-webkit-scrollbar          { width: 7px; }
  .info::-webkit-scrollbar-track    { background: transparent; }
  .info::-webkit-scrollbar-button   { display: none; }
  .info::-webkit-scrollbar-thumb    { background: #464646; border-radius: 0px; transition: background 0.3s ease;}
  .info::-webkit-scrollbar-thumb:hover { background: #4d4d4d; }

  /* Firefox ignores the rules above, and Chrome would ignore them if it saw the rule below,
     so this is fenced off for browsers that lack ::-webkit-scrollbar */
  @supports not selector(::-webkit-scrollbar) {
    .info { scrollbar-width: thin; scrollbar-color: #4a4949 transparent; }
  }

  .list {
    display: none;
    line-height: 1.6;
    margin-top: -10px;
  }

  .listitem {
    color: #e5e4e4;
    font-size: 17pt;
    text-decoration: none;
    cursor: pointer;
    transition: 0.3s ease;
    user-select: none;
    -webkit-user-select: none;
  }

  
  /* 'All weeks' heading at the top of the menu: same look as the items below it, but bold.
     (Not clickable, so no hover colour or pointer cursor.) */
     .listhead {
      color: #fcfbfb;
      font-size: 17pt;
      font-weight: bold;
      margin-bottom: 10px;
      letter-spacing: 0.06em;
      user-select: none;
      -webkit-user-select: none;
    }

  /* Column: scrolling text, with the nav panel pinned beside it (landscape) or below it (portrait) */
  .caption {
      max-width: 600px;
      width: 100%;
      align-self: stretch;     /* fill the panel's full height */
      min-height: 0;
      display: flex;
      flex-direction: column;
          }

  .maintext {
    color: #d2d1d1;
    font-size: 13pt;
    line-height: 1.4;
    margin-top: -10px;
        }

        
  .title {
    display: inline;          /* so the slide number can sit on the same line */
    color: #e5e4e4;
    font-size: 17pt;
    margin-top: 50px;
    line-height: 1.6;
    }

.numbertext {
  display: inline;            /* follows straight on from the title */
  margin-left: 8px;           /* gap between the title and the number */
  font-size: 11pt;
  color: #afaeae;
  margin-top: 0px;
}

.layerhint {
    font-size: 12pt;
    color: #afaeae;
    font-style: italic;
    margin-bottom: 20px;
  }
  
  .cursor {
    cursor: pointer;
  }

    /* Gallery images light up slightly on hover (replaces the old shadow) */
    .image-box img,
    .thumb img {
      transition: filter 0.25s ease;
    }
    .image-box img:hover,
    .thumb img:hover {
      filter: brightness(1.10);       /* 1 = unchanged; try 1.08 for subtler, 1.2 for stronger */
    }
  
  /* ===== SOURCES: sits under the caption text, same look but 1pt smaller =====
     The block is only built when the sheet's 'sources' cell has text (see buildSlideshow in the script). */
     .sources {
      color: #a3a2a2;           /* dimmer grey than the caption (#d2d1d1) but still easy to read on #2d2d2d */
      font-size: 11pt;          /* one point below .maintext (14pt; the small-screen sizes are in the mobile block) */
      line-height: 1.25;        /* tighter lines, like footnotes (was 1.6) */
      margin-top: 30px;         /* gap between the last line of the caption and the 'Sources' heading */
      margin-bottom: 10px;
    }
  .sources-line { width: 30px; height: 20px; border-top: solid 1px #a3a2a2 }
  .sources-text  { white-space: pre-line; }   /* keep line breaks typed into the spreadsheet cell */

    /* Tagged words in the caption that switch a layer on/off */
    .layer-link {
      cursor: pointer;
      text-decoration: none;
      border-bottom: 1px dotted #f3f3f3;   /* a border draws on every browser; iPhone Safari wasn't drawing the dotted text-decoration */
      padding-bottom: 1px;                 /* gap between the text and the dots: raise to move the dots down */
      border-radius: 3px;
      transition: color 0.3s ease, background-color 0.3s ease;
      user-select: none;
      -webkit-user-select: none;
    }
    .layer-link:hover { color: #fcfbfb; }
    .layer-link.layer-on {
      color: #fcfbfb;
      background-color: rgba(255, 255, 255, 0.16);
      border-bottom-style: solid;
    }
    .layer-link:focus-visible { outline: 1px solid #9a9a9a; outline-offset: 2px; }

  
  /* ===== PANNER: small map of the zoomed photo, with a green window showing the visible area =====
     Sits at the bottom of .caption, as a sibling of .info and .nav-container, so it ignores .info's
     show/hide and scrolling. Hidden unless JS adds .panner-on (only while the photo is zoomed in).
     JS sets the size of .panner-img (as large as fits: full width of this box's content area, max
     300px tall including the border) and the size/position of .panner-window. Fades in and out rather than
     appearing/disappearing abruptly*/
     .panner-container {
      display: none;
      flex: 0 0 auto;           /* never shrinks: .info gives up space instead */
      margin-top: auto;         /* stays at the bottom even when .info is hidden */
      padding: 20px 25px 0px 0px;
      opacity: 0;
      pointer-events: none;     /* a faded-out panner can't be grabbed */
      transition: opacity 0.3s ease;   /* keep the same as PANNER_FADE_MS in the script */
    }
    .panner-container.panner-on  { display: block; }      /* takes its place in the layout */
    .panner-container.panner-vis { opacity: 1; pointer-events: auto; }   /* and is visible */

  /* The frame carries the thin grey border (same grey as the main image's side borders).
     The window is positioned against the frame's padding edge, so it sits just inside the border. */
  .panner-frame {
    position: relative;
    display: block;
    width: fit-content;
    border: 1px solid #818181;
    line-height: 0;
    user-select: none;
    -webkit-user-select: none;
  }
  .panner-img {
    display: block;
    pointer-events: none;     /* drags register on the window, never on the <img> */
    user-select: none;
    -webkit-user-select: none;
    -webkit-user-drag: none;
  }
  .panner-window {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;              /* JS overrides all four once the photo is zoomed */
    height: 100%;
    border: 3px solid lightgreen;
    cursor: grab;             /* open hand on hover, closed hand while dragging (as on the main photo) */
    touch-action: none;
  }
  .panner-window.dragging { cursor: grabbing; }

  /* No panner on phones or in portrait layouts (same breakpoint as the mobile tweaks further down;
     keep the JS constant PANNER_OFF_QUERY in step with this) */
  @media (max-width: 600px), (max-height: 600px), (orientation: portrait) {
    .panner-container { display: none !important; }
  }

  /* ===== NAV PANEL: buttons + zoombar, pinned to the right edge of the slide ===== */
  .nav-container {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: var(--nav-w);
    z-index: 5;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 7px 5px 5px 0;
  }

  .buttonx {
    --close-gap: 60px;
    flex-shrink: 0;
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 5px;
  }

    
  
  /* Nav buttons */
  .prevx, .nextx, .info_button, .menu, .closex {
    color: #9a9a9a;                 /* the icons draw themselves in this colour (see NAV ICONS at the end of the file) */
    text-decoration: none;
    cursor: pointer;
    transition: 0.3s ease;
    user-select: none;
    -webkit-user-select: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    margin-right: 8px;
  }

  .closex {
    margin-right: 7px;
  }

  /* (the .menu and .info_button font-size and nudge rules are gone: icon sizes are set under NAV ICONS) */

  
  .closex:hover,
  .closex:focus,
  .prevx:hover,
  .nextx:hover,
  .info_button:hover,
  .menu:hover,
  .nextweek:hover, 
  .listitem:hover {
    color: #fcfbfb;
    text-decoration: none;
    cursor: pointer;
  }


/* ===== ZOOMBAR (vertical):   +  /  slider  /  −   =====
   Sits below the buttons in the nav panel. JS moves the thumb and the white filled line
   (via the --fill variable) and hides the whole bar for photos too low-res to be worth zooming.
   The mobile button sizes are in the "Mobile text-size tweaks" block further down. */
  .zoombar {
    --zl: 150px;             /* visual length of the vertical slider */
    display: flex;
    flex-direction: column;  /* + at top, slider, - at bottom */
    flex-shrink: 0;
    align-items: center;
    gap: 4px;
    width: 100%;
    margin-top: 50px;        /* 10px below the last button */
  }
  .zbtn {
    color: #9a9a9a;
    text-decoration: none;
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: 0.3s ease;
    user-select: none;
    -webkit-user-select: none;
    margin-right: 8px;
  }
  .zoom.zoom {
    -webkit-appearance: none;
    appearance: none;
    outline: none;
    flex: none;
    /* Laid out horizontally, then rotated -90deg so min is at the bottom (next to the - button).
       The margins reserve the rotated footprint: ~zero width, --zl of height. */
    width: var(--zl);
    max-width: none !important; 
    height: 16px;            /* the grab area; the visible line is the 1px drawn below */
    margin: calc((var(--zl) - 16px) / 2) calc(var(--zl) / -2);
    transform: rotate(-90deg);
    background: linear-gradient(to right, white var(--fill, 2px), #9a9a9a var(--fill, 2px)) center / 100% 1.5px no-repeat;
  }
  
  .zoom::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 4px;
    height: 16px;
    background: #9a9a9a;
    cursor: pointer;
  }
  .zoom::-moz-range-thumb {
    width: 4px;
    height: 16px;
    border: none;
    background: #9a9a9a;
    cursor: pointer;
  }

  /* Hover: the − and + buttons and the slider's thumb (the little dash) go white, like the other
     buttons. The thumb also stays white while being dragged (:active), and hovering anywhere on
     the slider counts, since the thumb itself is only 4px wide. The -webkit and -moz versions must
     be separate rules: browsers throw away a whole rule if any selector in it is unrecognised. */
  .zbtn:hover {
    color: #fcfbfb;
  }
  .zoom::-webkit-slider-thumb { transition: background 0.3s ease; }
  .zoom::-moz-range-thumb     { transition: background 0.3s ease; }
  .zoom:hover::-webkit-slider-thumb,
  .zoom:active::-webkit-slider-thumb {
    background: #fcfbfb;
  }
  .zoom:hover::-moz-range-thumb,
  .zoom:active::-moz-range-thumb {
    background: #fcfbfb;
  }

  /* Mobile text-size tweaks: bump the button row up, bring the reading
     text down. Checks BOTH width and height (not just width) so it also
     catches a phone actually held sideways in real landscape, where
     width is large but height is small. */
@media (max-width: 600px), (max-height: 600px) {

    .mySlides { --nav-w: 30px; }

    .buttonx {
      gap: 0px;
      width: 25px;
      --close-gap: 30px;     /* + the 7px gap = 20px */
    }

    .prevx, .nextx, .menu, .closex, .info_button {
    }

    /* Reading text: 1pt smaller than before, because phones don't have Garamond and show a
       larger fallback serif. If Garamond ever does load on phones, add the 1pt back. */
    .title { font-size: 15pt; }
    .numbertext { font-size: 10pt; }
    .layerhint { font-size: 10pt; }
    .maintext { font-size: 11pt; margin-top: 0; }   /* margin 0: the old -10px pushed the top of the title out of the scrolling box and clipped it */
    .sources  { font-size: 11pt; }     /* same as .maintext on phones */
    .listitem, .listhead { font-size: 14pt; }

    .list { margin-top: 0; }           /* same clipping fix for the menu's first line */
    .caption-container { padding-top: 10px; padding-left: 15px}   /* was 20px: the 10px lost from the margin above is given back here, so the text sits where it did */

    .zoom { display: none !important; }   /* no slider on phones: just the + and - buttons */
  }

  /* Phone held sideways: the buttons form a tall column and the screen is short, so the - button
     was running off the bottom. Slightly tighter spacing (3px less between buttons; the close
     button keeps its 20px gap) and a smaller zoom block get everything on screen. If a very short
     screen still can't fit it all, the nav column can scroll (scrollbar hidden). */
  @media (orientation: landscape) and (max-height: 600px) {
    .mySlides { --nav-w: 35px; }                      /* strip reserved for the nav: 5px wider, because the nav moves 5px left... */
    .nav-container { right: 5px; width: 30px; }       /* ...nudged 5px left, keeping its own width */
    .buttonx { gap: 5px; --close-gap: 30px; }         /* gap 3px smaller than before (4px -> 1px); the close button keeps its 20px separation */
    .zoombar { margin-top: 4px; gap: 0; }
    .zbtn { height: 36px; }
    .nav-container { overflow-y: auto; scrollbar-width: none; }
    .nav-container::-webkit-scrollbar { display: none; }
    .caption-container {padding-top: 10px;}
  }

  /* Touch devices held upright always get just the + and - buttons, whatever width the browser reports */
  @media (orientation: portrait) and (hover: none) and (pointer: coarse) {
    .zoom { display: none !important; }
  }
  
  
  /* Hover tooltips (desktop only) — a small CSS-only popup built from
     the data-tooltip attribute, with a delay before it appears.
     In landscape the popup opens to the LEFT of its button (the nav panel is on the right edge).
     The popups sit 5px further right than the original 4px gap, hence the -1px below. */
  [data-tooltip] {
    position: relative;
  }

  [data-tooltip]::after {
    content: attr(data-tooltip);
    position: absolute;
    top: 50%;
    right: calc(100% - 1px);     /* was calc(100% + 4px): moved 5px to the right */
    transform: translateY(-50%);
    background: white;
    color: black;
    border: solid 1px black;
    padding: 4px 10px;
    border-radius: 4px;
    font-size: 11pt;
    font-family: Arial, sans-serif;
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease;
    transition-delay: 0s;
    z-index: 10;
  }

  [data-tooltip]:hover::after {
    opacity: 1;
    transition-delay: 1s;   /* hover must linger this long before it appears */
  }

  /* Never show tooltips on touch devices, regardless of screen size —
     (hover: none)/(pointer: coarse) catches genuine touchscreens (a large
     tablet included), since a touch interface can't "hover" at all. Also
     disabled under the project's existing smartphone-mode breakpoint, for
     consistency with the font-size rules above. */
  @media (hover: none), (pointer: coarse), (max-width: 600px), (max-height: 600px) {
    [data-tooltip]::after {
      display: none !important;
    }
  }

  /* Captions: keep line breaks typed into the spreadsheet cell */
  .caption-text { white-space: pre-line; margin-top: 10px;}

  /* ===== LOADING SPINNER + FADE-IN (JS adds/removes these; see startLoader() and revealContent()) =====
     While loading, #feature, #gallery and the acknowledgment carry .ss-pending (invisible but still
     laid out, so lazy images and measurements keep working). When the key images are ready the spinner
     fades out (LOADER_FADE_MS in the script, keep equal to the .ss-loader transition) and the content fades in. */
  .feature, .gallery, .acknowledgment { transition: opacity 0.6s ease; }
  .ss-pending { opacity: 0; }
  .ss-loader { display: flex; justify-content: left; padding: 40px 0 0 200px; transition: opacity 0.3s ease; }
  .ss-loader.ss-fade { opacity: 0; }
  .ss-loader img { width: 100px; height: 100px; object-fit: contain; opacity: 0; transition: opacity 0.3s ease;
                   animation: ss-spin 4s linear infinite; }        /* 4s per turn: raise for slower */
  .ss-loader img.ss-ready { opacity: 1; }
  .ss-ring { width: 50px; height: 50px; border: 4px solid #ccc; border-top-color: #555; border-radius: 50%;
             animation: ss-spin 1.2s linear infinite; }           /* fallback if there is no loading image */
  @keyframes ss-spin { to { transform: rotate(360deg); } }

  /* Loading / error message */
  .loadmsg { font-family: Arial, sans-serif; color: #555; display: flex; align-items: center; gap: 20px; }
  .loadpreview { display: block; max-width: 100px; max-height: 100px; width: auto; height: auto; }

  /* Acknowledgment under the gallery */
  .acknowledgment { margin: 70px 0 0 0; font-size: 11pt; text-align: left; }

/* ===== PORTRAIT: nav panel drops below the info text, left-justified, as a horizontal row =====
   Keep this block LAST in the file so it overrides the landscape rules above. */
@media (orientation: portrait) {
  .nav-container {
    position: static;
    width: auto;
    margin-top: auto;          /* stays at the bottom even if the text is hidden */
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    padding: 0;
    flex-shrink: 0;
  }
  .buttonx {
    flex-direction: row;
    width: auto;
  }
  .prevx, .nextx, .info_button, .menu, .closex { width: auto; }

  .prevx {margin-right: 5px;}

  .nextx {margin-right: 5px;}

  .menu {margin-right: 6px;}

  .zoombar {
    flex-direction: row-reverse;   /* shows as  -  slider  +  */
    width: auto;
    margin: 0 0 0 10px;
  }
  .zbtn { width: 36px; }
  .zoom {                          /* un-rotate the slider (hidden on phones anyway) */
    transform: none;
    width: 120px;
    margin: 0;
  }

  [data-tooltip]::after {          /* tooltips go above the buttons in the row */
    top: auto;
    bottom: 125%;
    right: auto;
    left: 50%;
    transform: translateX(calc(-50% + 5px));   /* centred on the button, then 5px to the right */
  }
}

/* ===== PORTRAIT PHONES: nav row centred on the screen =====
   The caption panel has 20px padding on the left and 3px on the right, so the row is pulled 17px
   left (margin) to put its centre on the middle of the screen rather than the middle of the text. */
@media (orientation: portrait) and (max-width: 600px) {
  .nav-container {
    justify-content: center;
    margin-left: -17px;
  }
}


/* ===== NAV ICONS (all devices) =====
   The nav buttons are SVG line icons (their shapes live in NAV_ICONS in the JS). They are drawn in the
   button's own colour, so the hover colour change works unchanged.
   --ico-stroke   line thickness in screen pixels, the same at every icon size
   --ico-xxx      the icon's box size in px (each icon is drawn on a 24-unit grid, so e.g. 24px = 1px per unit;
                  the visible shape is smaller than the box, as the shapes keep some margin)
   Computers use the first set of sizes; phones and short screens (the same query as the phone
   text sizes above) use the second. The button's tap area is set separately (its height/width above). */
.mySlides {
  --ico-stroke: 1.5px;
  --ico-close: 30px;
  --ico-prev: 30px;
  --ico-next: 30px;
  --ico-menu: 30px;
  --ico-info: 30px;
  --ico-zoom: 30px;
  --ico-corner: 30px;       /* the exit cross in the text panel's corner (upright phones) */
}
@media (max-width: 600px), (max-height: 600px) {
  .mySlides {
    --ico-stroke: 1.5px;
    --ico-close: 32px;
    --ico-prev: 32px;
    --ico-next: 32px;
    --ico-menu: 32px;
    --ico-info: 32px;
    --ico-zoom: 32px;
    --ico-corner: 28px;
  }
}
.ico {
  display: block;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: var(--ico-stroke);
  stroke-linecap: butt;
  stroke-linejoin: miter;
  overflow: visible;
  pointer-events: none;     /* clicks and long-presses go to the button itself */
}
.ico * { vector-effect: non-scaling-stroke; }     /* the line stays --ico-stroke thick however big the icon is */
.closex .ico       { width: var(--ico-close);  height: var(--ico-close); }
.prevx .ico        { width: var(--ico-prev);   height: var(--ico-prev); }
.nextx .ico        { width: var(--ico-next);   height: var(--ico-next); }
.menu .ico         { width: var(--ico-menu);   height: var(--ico-menu); }
.info_button .ico  { width: var(--ico-info);   height: var(--ico-info); }
.zbtn .ico         { width: var(--ico-zoom);   height: var(--ico-zoom); }
.closex-corner .ico { width: var(--ico-corner); height: var(--ico-corner); }

/* Upright screens lay the buttons out in a row with automatic widths, so give each a touch-sized minimum */
@media (orientation: portrait) {
  .prevx, .nextx, .info_button, .menu, .closex { min-width: 30px; }
}
.prevx, .nextx, .info_button, .menu, .closex, .closex-corner, .zbtn { -webkit-touch-callout: none; }

/* ===== EXIT CROSS IN THE TEXT PANEL'S CORNER (portrait phones only; hidden everywhere else) ===== */
.closex-corner { display: none; }

@media (orientation: portrait) {
  .caption-container { position: relative; }     /* the corner cross is positioned against the text panel (the nav is static in portrait, so unaffected) */
}

/* ===== PORTRAIT PHONES: extra changes ===== */
@media (orientation: portrait) and (max-width: 600px) {
  .closex { display: none; }                     /* the nav row's own cross is replaced by the corner one */
  .closex-corner {
    display: flex;
    position: absolute;
    top: 5px;
    right: 10px;
    z-index: 6;
    width: 36px;
    height: 36px;
    align-items: center;
    justify-content: center;
    line-height: 1;
    color: #9a9a9a;
    background: #2d2d2d;                         /* same as the panel, so text scrolling underneath doesn't show through */
    border-radius: 4px;
    text-decoration: none;
    cursor: pointer;
    user-select: none;
    -webkit-user-select: none;
    transition: 0.3s ease;
  }
  .closex-corner:hover { color: #fcfbfb; }
  .info::before {                                /* keeps the first lines of text clear of the corner cross */
    content: "";
    float: right;
    width: 40px;
    height: 34px;
  }

  /* prev on the left, next on the right (the DOM order is for the sideways layout) */
  .prevx        { order: 1; }
  .nextx        { order: 2; }
  .menu         { order: 3; }
  .info_button  { order: 4; }

  .zoomOut {margin-bottom: -12px;}

  .nav-container { margin-bottom: 10px; }         /* nav row nudged 5px up */
  .caption-container { padding-top: 10px; }      /* title nudged 5px down (was 10px) */
}

/* ===== PORTRAIT PHONES: spinner in the middle of the screen =====
   (the base rule above offsets it for the desktop page layout) */
@media (orientation: portrait) and (max-width: 600px) {
  .ss-loader { justify-content: center; padding-left: 0; }
}


/* ===== v12 ADDITIONS ===== */

/* Zoom bar (the + / slider / - buttons): invisible until the zoomable original has loaded, then fades in.
   The script adds .zoombar-on; while 'pending' the bar keeps its space but can't be seen or touched. */
/* Off = instant (no transition on the base state, so it vanishes with the other nav buttons). On = fades in
   over 1.2s: the transition that runs is the one belonging to the state being entered. */
.zoombar { opacity: 0; visibility: hidden; transition: none; }
.zoombar.zoombar-on { opacity: 1; visibility: visible; transition: opacity 1.2s ease, visibility 0s; }

/* The slide's layers, drawn small on top of the panner image (under the green window) */
.panner-layers { position: absolute; left: 0; top: 0; width: 100%; height: 100%; pointer-events: none; }
.panner-layers .panner-layer {
  position: absolute; left: 0; top: 0; width: 100%; height: 100%;
  max-width: none !important; object-fit: fill;
  opacity: 0;                         /* JS sets the layer's opacity when it is switched on */
  transition: opacity 0.4s ease;
  pointer-events: none;
}

/* Touch tooltips: the script adds .tip-on to a button held down for a moment. This beats the rule that
   hides tooltips on touch screens, and the tooltip then sits where the hover tooltips do. */
.closex-corner::after {             /* the corner cross's tooltip opens to its left, inside the panel */
  top: 50%; bottom: auto; left: auto; right: calc(100% + 4px); transform: translateY(-50%);
}

/* One-time "touch and hold" hint */
.touch-hint {
  position: fixed; left: 50%; bottom: 84px; transform: translateX(-50%);
  max-width: 80%; text-align: center;
  background: rgba(255, 255, 255, 0.93); color: #000;
  padding: 7px 14px; border-radius: 4px;
  font: 13pt Arial, sans-serif;
  z-index: 100000; pointer-events: none;
  opacity: 0; transition: opacity 0.6s ease;
}
.touch-hint.touch-hint-on { opacity: 1; }
@media (orientation: landscape) { .touch-hint { bottom: 24px; } }

/* Portrait: tooltips sit centred ABOVE their buttons (see the portrait rule above). The two end buttons of the
   row get tooltips aligned to their own edge instead, so a long tooltip can't be cut off by the screen edge. */
@media (orientation: portrait) {
  .prevx[data-tooltip]::after { left: 0; transform: none; }
  .zoombar .zbtn:first-child[data-tooltip]::after { left: auto; right: 0; transform: none; }
}

/* ===== TOUCH TOOLTIP BUBBLE and NO-SELECT WHILE A BUTTON IS HELD (phones) =====
   The bubble is added to the slideshow by the script (same look as the hover tooltips). While a nav button is
   held the script puts .no-select on the slideshow so Chrome doesn't start highlighting nearby text. */
.touch-tip {
  position: absolute;
  z-index: 100001;
  background: white;
  color: black;
  border: solid 1px black;
  padding: 4px 10px;
  border-radius: 4px;
  font-size: 11pt;
  font-family: Arial, sans-serif;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.15s ease;
}
.touch-tip.touch-tip-on { opacity: 1; }
.no-select, .no-select * {
  -webkit-user-select: none !important;
  user-select: none !important;
  -webkit-touch-callout: none;
}
.nav-container, .nav-container * { -webkit-user-select: none; user-select: none; }
