/* The site's own styles, on top of Bootstrap. Kept small on purpose. */

/* Dark mode a little darker than Bootstrap's own grey: a near-black page,
   with panels and binder pages a shade lighter. */
[data-bs-theme="dark"] {
  --bs-body-bg: #111315;
  --bs-body-bg-rgb: 17, 19, 21;
  --bs-secondary-bg: #1b1e21;
  --bs-secondary-bg-rgb: 27, 30, 33;
  --bs-tertiary-bg: #16191b;
  --bs-tertiary-bg-rgb: 22, 25, 27;
  --bs-border-color: #2f3439;
}

/* Always keep room for the scrollbar, so the page never shifts sideways
   when one appears or disappears (e.g. during a page turn). */
html {
  scrollbar-gutter: stable;
}

/* Card images: rounded corners like a real card, and a light shadow.
   Scryfall's images are rectangles whose corners show a bit of background;
   rounding hides only that, never the art, artist or copyright line, and is
   what Scryfall's own site does. The radius is a share of the width and of
   the height, so it fits the card at any size. */
.card-image {
  border-radius: 4.75% / 3.5%;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}

/* Flip between the two faces of a double-faced card (Bootstrap's carousel,
   in its fade mode). Bootstrap's 0.6 s feels slow for a flip; both rules
   below are needed, as Bootstrap times the fade-in and the fade-out apart. */
.card-faces .carousel-item {
  transition-duration: 0.2s;
}
.card-faces .active.carousel-item-start,
.card-faces .active.carousel-item-end {
  transition: opacity 0s 0.2s;
}
/* Bootstrap clips what sticks out of a carousel, which would cut off the
   shadow. A fade never moves the faces sideways, so nothing needs clipping. */
.card-faces .carousel-inner {
  overflow: visible;
}

/* Card page on a phone: at full width the image is about 500 px tall and
   pushes the details and prices off the first screen. 16rem (256 px) keeps
   the card readable and leaves room below it. From tablet width (Bootstrap's
   md, 768 px) the image sits beside the details and needs no limit. */
@media (max-width: 767.98px) {
  .card-page-image {
    max-width: 16rem;
    margin-inline: auto;
  }
}

/* The kind dropdown in the search box (Cards / Tokens / Art cards).
   Bootstrap's select is as wide as its container and generously padded;
   this keeps it just wide enough for its longest option, so the text field
   next to it gets the rest of the width. ".input-group >" is needed to
   outrank Bootstrap's own rule, which makes every select in an input group
   grow. */
.input-group > .search-kind {
  flex: 0 0 auto;
  width: auto;
  padding-left: 0.5rem;
  padding-right: 1.75rem;
  background-position: right 0.5rem center;
}

/* Binder pages (member page): an open binder with two pages side by side
   on a computer, one under the other on a phone. Each page is a grid of
   pockets whose number of columns comes from the page layout (--columns,
   set in the template). */
.binder-spread {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
}
@media (min-width: 992px) {
  .binder-spread {
    grid-template-columns: 1fr 1fr;
  }
}
.binder-page {
  border: 1px solid var(--bs-border-color);
  border-radius: 0.5rem;
  background: var(--bs-tertiary-bg);
  padding: 0.75rem;
}
.binder-pockets {
  display: grid;
  grid-template-columns: repeat(var(--columns), 1fr);
  gap: 0.5rem;
}
/* An empty pocket keeps a card's shape (63 × 88 mm). */
.pocket-empty {
  aspect-ratio: 63 / 88;
  border: 1px dashed var(--bs-border-color);
  border-radius: 4.75% / 3.5%;
}

/* The owner's editor (my_binder.html). The card selects it (its tick box
   is hidden from view); a selected card gets a frame, a light blue veil
   and a check mark badge at its top, drawn like the other badges. Reaching
   the hidden tick box with the keyboard shows a focus ring around the card. */
.pocket-hit {
  cursor: pointer;
}
.editor-pocket:has(.pocket-select:checked) {
  outline: 3px solid var(--bs-primary);
  outline-offset: 2px;
  border-radius: 4.75% / 3.5%;
}
.editor-pocket:has(.pocket-select:checked) .pocket-hit::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 4.75% / 3.5%;
  background: rgb(13 110 253 / 0.15);
}
.editor-pocket:has(.pocket-select:checked) .pocket-hit::after {
  content: "✓";
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  margin: 0.25rem 0;
  border-radius: 0.25rem;
  padding: 0.05rem 0.4rem;
  background: var(--bs-primary);
  color: #fff;
  font-size: 0.7rem;
  font-weight: 700;
  line-height: 1.4;
  box-shadow: 0 1px 2px rgb(0 0 0 / 0.4);
}
.editor-pocket:has(.pocket-select:focus-visible) {
  outline: 3px solid var(--bs-focus-ring-color, rgb(13 110 253 / 0.5));
  outline-offset: 2px;
}
/* The Edit button: a dark badge like the quantity badge, low on the card,
   just clearing the bottom badges (condition, price) so it never covers
   them.
   With a mouse it shows when the card is pointed at (or reached with
   Tab); on touch screens it is always there. */
.pocket-edit {
  position: absolute;
  bottom: 1.3rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  border-radius: 0.25rem;
  padding: 0.15rem 0.6rem;
  background: rgb(33 37 41 / 0.9);
  color: #fff;
  font-size: 0.75rem;
  font-weight: 700;
  line-height: 1.4;
  text-decoration: none;
  box-shadow: 0 1px 2px rgb(0 0 0 / 0.4);
}
.pocket-edit:hover,
.pocket-edit:focus-visible {
  background: var(--bs-primary);
  color: #fff;
}
@media (hover: hover) {
  .pocket-edit {
    opacity: 0;
    transition: opacity 0.1s;
  }
  .editor-pocket:hover .pocket-edit,
  .editor-pocket:focus-within .pocket-edit {
    opacity: 1;
  }
  /* Not while dragging: the card being dragged is no place to edit. */
  .is-dragging .pocket-edit {
    opacity: 0;
  }
}
/* An empty pocket in the editor opens "Add a card" for it: a "+" and
   "Add card" in its middle, shown when the pocket is pointed at (or
   reached with Tab); faint but always there on touch screens, where
   nothing can be pointed at. */
.pocket-add {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--bs-secondary-color);
  text-decoration: none;
}
.pocket-add:hover,
.pocket-add:focus-visible {
  border-color: var(--bs-primary);
  background: var(--bs-primary-bg-subtle);
  color: var(--bs-primary);
}
.pocket-add-label {
  display: flex;
  flex-direction: column;
  align-items: center;
  font-size: 0.8rem;
  font-weight: 600;
  text-align: center;
  opacity: 0.6;
}
.pocket-add-plus {
  font-size: 2rem;
  line-height: 1;
}
@media (hover: hover) {
  .pocket-add-label {
    opacity: 0;
    transition: opacity 0.1s;
  }
  .pocket-add:hover .pocket-add-label,
  .pocket-add:focus-visible .pocket-add-label {
    opacity: 1;
  }
}
/* Not while dragging: the pocket is a place to drop a card then. */
.is-dragging .pocket-add-label {
  opacity: 0;
}
/* List rows: a selected row is tinted (Bootstrap's table cells read this
   variable); rows are moved by their grip. */
.entry-row {
  cursor: pointer;
  user-select: none;
}
.entry-row:has(input[name="entries"]:checked) > td {
  --bs-table-bg-state: var(--bs-primary-bg-subtle);
}
.drag-handle {
  cursor: grab;
  color: var(--bs-secondary-color);
  font-size: 1.2rem;
  width: 1.5rem;
  text-align: center;
}
/* Cards are selected by clicking and dragging, so the editor's pages and
   list never select text. */
.editor-run,
.editor-list tbody {
  user-select: none;
}
/* The selection rectangle (static/js/select.js). */
.select-band {
  position: absolute;
  z-index: 1000;
  border: 1px solid var(--bs-primary);
  background: rgb(13 110 253 / 0.12);
  pointer-events: none;
}

/* Dragging (static/js/editor.js). The pocket a card would land in gets a
   frame; the cards being moved fade where they are; the copy following
   the pointer shows how many cards go along. */
.editor-pocket {
  /* Not Bootstrap's position-relative class: its !important would keep the
     copy following the pointer from floating (SortableJS sets it fixed). */
  position: relative;
  cursor: grab;
  /* No text selection or phone callout while picking a card up. */
  user-select: none;
  -webkit-touch-callout: none;
}
.drop-target {
  outline: 3px dashed var(--bs-primary);
  outline-offset: 2px;
  border-radius: 4.75% / 3.5%;
}
.is-dragging .editor-pocket.sortable-ghost,
.is-dragging .editor-pocket:has(.pocket-select:checked),
.is-dragging .entry-row:has(input[name="entries"]:checked) {
  opacity: 0.35;
}
/* In the list, the dragged row's place shows where the rows will land. */
.entry-row.sortable-ghost {
  outline: 2px dashed var(--bs-primary);
}
.sortable-fallback {
  cursor: grabbing;
  box-shadow: 0 0.5rem 1.5rem rgb(0 0 0 / 0.35);
}
.sortable-fallback[data-count]::after {
  /* Drawn like the card badges, in the selection's blue. */
  content: attr(data-count);
  position: absolute;
  top: -0.5rem;
  right: -0.5rem;
  border-radius: 0.25rem;
  padding: 0.05rem 0.4rem;
  background: var(--bs-primary);
  color: #fff;
  font-size: 0.75rem;
  font-weight: 700;
  line-height: 1.4;
  box-shadow: 0 1px 2px rgb(0 0 0 / 0.4);
}
/* The preview while dragging on the pages (static/js/editor.js): a pocket
   the drop would change hides what it holds now and shows, see-through,
   the card it would hold. Written after the rules above (and with
   .binder-pockets) so it wins over the fading of the cards being moved. */
.pocket-empty {
  position: relative;
}
.is-dragging .binder-pockets .pocket.previewing {
  opacity: 1;
  outline: none;
  border-radius: 4.75% / 3.5%;
}
.is-dragging .binder-pockets .pocket.previewing > :not(.move-preview) {
  visibility: hidden;
}
.move-preview {
  position: absolute;
  inset: 0;
  opacity: 0.55;
  pointer-events: none; /* the pocket under the pointer stays findable */
}
.is-dragging .binder-pockets .pocket.previewing.drop-target {
  outline: 3px dashed var(--bs-primary);
  outline-offset: 2px;
}
.is-dragging .binder-pockets .pocket.previewing.preview-pushed {
  outline: 2px dashed var(--bs-secondary-color);
  outline-offset: 2px;
}
/* Left empty: drawn like an empty pocket. */
.is-dragging .binder-pockets .pocket.previewing.preview-emptied {
  outline: 1px dashed var(--bs-border-color);
  outline-offset: -1px;
}
/* Two stickers stacked in the bottom corner (language above price): the
   button moves up to clear both. */
.editor-pocket:has(.language-badge + .price-sticker) .pocket-edit {
  bottom: 2.75rem;
}

/* Jumping to a section leaves the top of its heading in view. */
.editor-run {
  scroll-margin-top: 1rem;
}

/* Badges on a card in a binder pocket, like stickers on a sleeve. The
   card image underneath is never altered (Scryfall's terms). */
.pocket-badge {
  position: absolute;
  margin: 0.25rem;
  border-radius: 0.25rem;
  padding: 0.05rem 0.35rem;
  font-size: 0.7rem;
  font-weight: 700;
  line-height: 1.4;
  box-shadow: 0 1px 2px rgb(0 0 0 / 0.4);
}
.quantity-badge {
  background: #212529;
  color: #fff;
}
/* The asking price, like a price sticker. */
.price-sticker {
  background: #fff3b0;
  color: #212529;
}
/* Foil shimmers; etched foil is metallic. */
.finish-foil {
  background: linear-gradient(135deg, #ffd1dc, #fff6b7, #b9f3ff, #d9c2ff);
  color: #212529;
}
.finish-etched {
  background: linear-gradient(135deg, #e9ecef, #adb5bd, #f8f9fa);
  color: #212529;
}
/* Condition, from green (as new) to red (heavily played). */
.condition-MT,
.condition-NM { background: #198754; color: #fff; }
.condition-EX { background: #5b9f2c; color: #fff; }
.condition-GD { background: #a3b81e; color: #212529; }
.condition-LP { background: #ffc107; color: #212529; }
.condition-PL { background: #fd7e14; color: #212529; }
.condition-PO { background: #dc3545; color: #fff; }
/* A card not in English: two letters and a little flag, on white like a
   label. */
.language-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
  background: #fff;
  color: #212529;
}
.language-flag {
  width: auto;
  height: 0.6rem;
  box-shadow: 0 0 0 1px rgb(0 0 0 / 0.25);
}
/* Badges stacked in one corner (language above price), so that on a
   small card they never run into the condition in the other corner. */
.pocket-stack {
  position: absolute;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.15rem;
  margin: 0.25rem;
}
.pocket-stack .pocket-badge {
  position: static;
  margin: 0;
}

/* Small cards (four in a row on a phone, say): the stickers would cover
   each other, so they shrink and the price drops its currency. A container
   query looks at the card's own width, so this works for every layout and
   screen. */
.pocket {
  container-type: inline-size;
}
.price-short {
  display: none;
}
@container (max-width: 140px) {
  .pocket-badge {
    margin: 0.15rem;
    padding: 0 0.25rem;
    font-size: 0.6rem;
  }
  .pocket-stack {
    margin: 0.15rem;
    gap: 0.1rem;
  }
  .language-flag {
    height: 0.5rem;
  }
  .price-full {
    display: none;
  }
  .price-short {
    display: inline;
  }
}

/* Details over the card on hover, only where a mouse can hover; phones
   open the card's page instead. :focus-visible shows them to keyboard
   users too. */
.pocket-info {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 0.5rem;
  border-radius: 4.75% / 3.5%;
  background: rgb(0 0 0 / 0.8);
  color: #fff;
  font-size: 0.75rem;
  line-height: 1.3;
  overflow: hidden;
  opacity: 0;
  transition: opacity 0.15s;
  pointer-events: none;
}
@media (hover: hover) {
  .pocket:hover .pocket-info,
  .pocket-link:focus-visible .pocket-info {
    opacity: 1;
  }
}
@media (hover: none) {
  .pocket-info {
    display: none;
  }
}

/* The visitor's list of chosen cards (static/js/pick.js). Each card has a
   tick box in its top right corner, over the hover details; the label
   around it is a larger spot to tap. The quantity badge moves just left of
   it. Without JavaScript the boxes would do nothing, so they only show
   once pick.js has run (can-pick). A ticked card gets a frame, like a
   selected card in the owner's editor. */
.pocket-pick {
  display: none;
  position: absolute;
  top: 0;
  right: 0;
  z-index: 2;
  padding: 0.25rem;
  line-height: 0;
  cursor: pointer;
}
.can-pick .pocket-pick {
  display: block;
}
.pocket-pick .pick-box {
  width: 1.15rem;
  height: 1.15rem;
  margin: 0;
  cursor: pointer;
  box-shadow: 0 1px 2px rgb(0 0 0 / 0.4);
}
/* How many copies, under the box once ticked: as small as it can be while
   still readable. */
.pick-amount {
  position: absolute;
  top: 1.75rem;
  right: 0.25rem;
  z-index: 2;
  width: auto;
  min-height: 0;
  padding: 0 1.1rem 0 0.35rem;
  background-position: right 0.25rem center;
  background-size: 10px 8px;
  font-size: 0.75rem;
  box-shadow: 0 1px 2px rgb(0 0 0 / 0.4);
}
.can-pick .quantity-beside-pick {
  right: 1.6rem !important; /* outranks Bootstrap's end-0 */
}
.visitor-pocket:has(.pick-box:checked) {
  outline: 3px solid var(--bs-primary);
  outline-offset: 2px;
  border-radius: 4.75% / 3.5%;
}
/* The bar at the bottom of the screen, over the page; the page gets room
   at its end so the bar never hides the footer. */
.pick-bar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 1030; /* Bootstrap's level for fixed bars, under its windows */
  padding: 0.5rem 1rem;
  background: var(--bs-body-bg);
  border-top: 1px solid var(--bs-border-color);
}
.has-pick-bar {
  padding-bottom: 4rem;
}

/* Flipping (static/js/binder.js): after the new pages arrive, a "leaf" made
   of copies of the old and new pages turns over the spine, then disappears.
   Its front is the page being turned, its back the page that lands. The
   leaf is cut into narrow strips, each hinged on the one before it, which
   lag a little behind one another mid-turn: the page bends like paper
   instead of turning like a board. A light shadow darkens it as it stands
   up. Layout and view changes only fade; nothing moves for visitors whose
   system asks for reduced motion. */
.page-turn {
  position: absolute;
  inset: 0;
  perspective: 3200px;
  pointer-events: none;
  z-index: 2;
  /* The page lifting toward the viewer sticks out of the spread for a
     moment; clipping it (with a little room) keeps the page's size, and so
     its scrollbar and layout, unchanged during the turn. */
  overflow: clip;
  overflow-clip-margin: 1.5rem;
  --turn-time: 0.4s;
}
.page-turn-static,
.leaf,
.leaf-strip {
  position: absolute;
}
/* The old pages shown still are opaque, empty places included: going back
   from a last spread with a single page, the new page under its empty
   right side must not show before the turn lands it there. */
.page-turn-static {
  background: var(--bs-body-bg);
}
.leaf,
.leaf-strip {
  transform-style: preserve-3d;
}
.leaf {
  animation-duration: var(--turn-time);
  animation-timing-function: cubic-bezier(0.4, 0, 0.3, 1);
  animation-fill-mode: forwards;
}
.leaf-strip {
  top: 0;
  height: 100%;
  animation: leaf-bend var(--turn-time) ease-in-out;
}
/* Each strip hinges on the one before it. (The whole leaf hinges on the
   spine, set by binder.js from the gap between the pages.) */
.leaf-hinge-left .leaf-strip { transform-origin: left center; }
.leaf-hinge-right .leaf-strip { transform-origin: right center; }
/* How much each strip lags behind the one before it, mid-turn. Its sign
   is the opposite of the turn's direction. */
.leaf-next { --bend: 6deg; animation-name: leaf-turn-next; }
.leaf-prev { --bend: -6deg; animation-name: leaf-turn-prev; }
.leaf-land { --bend: -6deg; animation-name: leaf-land; }
/* One strip of a page: a window onto a full copy of the page, shifted so
   that the right part shows. */
.leaf-slice {
  position: absolute;
  inset: 0;
  overflow: hidden;
  backface-visibility: hidden;
  /* A hair in front of the strip's middle, so front and back never sit in
     exactly the same plane (which makes some browsers flicker). */
  transform: translateZ(0.5px);
}
.leaf-slice > * {
  position: absolute;
  top: 0;
  height: 100%;
}
.leaf-back {
  transform: rotateY(180deg) translateZ(0.5px);
}
/* Chrome draws the copies' layered pieces (tick box, number of copies)
   flat, where they will land, instead of turning them with their strip.
   Without a z-index they are drawn as part of the page, and turn with it;
   coming after the card in the page, they still show over it. */
.page-turn .pocket-pick,
.page-turn .pick-amount {
  z-index: auto;
}
/* The shadow on each strip, darkest when the page stands upright. */
.leaf-slice::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgb(0 0 0 / 0.12);
  opacity: 0;
  animation: leaf-shade var(--turn-time) ease-in-out;
}
@keyframes leaf-turn-next {
  from { transform: rotateY(0deg); }
  to { transform: rotateY(-180deg); }
}
@keyframes leaf-turn-prev {
  from { transform: rotateY(0deg); }
  to { transform: rotateY(180deg); }
}
@keyframes leaf-land {
  from { transform: rotateY(-180deg); }
  to { transform: rotateY(0deg); }
}
@keyframes leaf-bend {
  0%, 100% { transform: rotateY(0deg); }
  50% { transform: rotateY(var(--bend)); }
}
@keyframes leaf-shade {
  0%, 100% { opacity: 0; }
  50% { opacity: 1; }
}
@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
.binder-spread.turn-fade {
  animation: fade-in 0.2s ease-out;
}
@media (prefers-reduced-motion: reduce) {
  .binder-spread.turn-fade { animation: none; }
}

/* Flipping buttons: three fixed columns, so "Previous" and "Next" keep
   their place and size whatever the page numbers between them. */
.binder-nav {
  display: grid;
  grid-template-columns: 1fr 8.5rem 1fr;
  align-items: center;
  gap: 0.25rem;
}
.binder-nav > :first-child { justify-self: end; }
.binder-nav > :last-child { justify-self: start; }
.binder-nav-pages {
  text-align: center;
  white-space: nowrap;
}
.flip-button {
  min-width: 8rem;
}
/* The editor's Previous and Next: centred on the whole width, with "Go to
   page" in a column of its own at the right, so it does not push them
   off centre. On a phone, "Go to page" goes under them. */
.editor-page-nav {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 0.5rem;
}
.editor-page-nav .binder-nav {
  grid-column: 2;
}
.editor-go-to {
  justify-self: end;
}
/* While a card is dragged, Previous and Next take it to the pages before
   or after (static/js/editor.js): dashed like a place to drop, and filling
   up while the card rests on one, until the pages turn. */
.is-dragging .editor-page-nav a.flip-button {
  border-style: dashed;
  border-color: var(--bs-primary);
  color: var(--bs-primary);
  /* Not Bootstrap's grey for a pointed-at button, which would hide the
     fill below and the blue text. */
  background-color: transparent;
}
.editor-page-nav a.flip-button.flip-armed {
  background-image: linear-gradient(var(--bs-primary-bg-subtle), var(--bs-primary-bg-subtle));
  background-repeat: no-repeat;
  background-size: 0 100%;
  animation: flip-fill 0.6s linear forwards;
}
@keyframes flip-fill {
  to {
    background-size: 100% 100%;
  }
}
@media (prefers-reduced-motion: reduce) {
  .editor-page-nav a.flip-button.flip-armed {
    animation: none;
    background-size: 100% 100%;
  }
}
@media (max-width: 767.98px) {
  .editor-page-nav {
    grid-template-columns: 1fr;
  }
  .editor-page-nav .binder-nav {
    grid-column: 1;
  }
  /* Narrower buttons, so Previous, the page count and Next fit. */
  .editor-page-nav .flip-button {
    min-width: 0;
  }
  .editor-go-to {
    justify-self: center;
  }
}

/* The card panel: wide on a computer, but always leaving a strip of the
   binder visible to click back to. */
.card-panel.offcanvas-end {
  width: min(46rem, 88vw);
  /* Bootstrap slides it in over 0.3 s; this is quicker. */
  transition-duration: 0.15s;
}

/* The binder's view controls: small segmented buttons. A layout button
   shows its page as a tiny grid of squares. */
/* The "Search and sort" filters apply as soon as they change
   (static/js/filters.js), so their "Show" button is only there for
   visitors without JavaScript. */
.live-filters .filters-show {
  display: none;
}
/* The release-year slider in the "Search and sort" view: two of
   Bootstrap's range inputs laid over each other, so they look like one
   slider with two handles (static/js/filters.js). Only the handles take
   clicks, so either can be grabbed; the top input's track is see-through. */
.year-range {
  position: relative;
  height: 1.5rem;
}
.year-range .form-range {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.year-range .form-range::-webkit-slider-thumb {
  pointer-events: auto;
}
.year-range .form-range::-moz-range-thumb {
  pointer-events: auto;
}
.year-range .form-range + .form-range::-webkit-slider-runnable-track {
  background: transparent;
}
.year-range .form-range + .form-range::-moz-range-track {
  background: transparent;
}

.layout-icon {
  display: inline-grid;
  grid-template-columns: repeat(var(--columns), 3px);
  gap: 1px;
  vertical-align: middle;
}
.layout-icon > span {
  width: 3px;
  height: 4px;
  border-radius: 0.5px;
  background: currentColor;
}

/* The photo viewer (templates/photo_viewer.html, static/js/photo_viewer.js):
   the whole window, dark, the photo centred and as large as fits. */
.photo-viewer {
  width: 100vw;
  height: 100dvh;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: #fff;
  overflow: hidden;
}
.photo-viewer::backdrop {
  background: rgba(0, 0, 0, 0.88);
}
.photo-viewer-stage {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 3rem 4rem;
  /* Fingers drag and pinch the photo instead of scrolling the page. */
  touch-action: none;
}
.photo-viewer-image {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 0.5rem;
  cursor: zoom-in;
  user-select: none;
  transform-origin: center;
}
.photo-viewer-image.zoomed {
  cursor: grab;
}
.photo-viewer-close {
  position: absolute;
  top: 1rem;
  right: 1rem;
  z-index: 1;
}
.photo-viewer-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 1;
  width: 3rem;
  height: 3rem;
  border: 0;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.5);
  color: #fff;
  font-size: 2rem;
  line-height: 1;
}
.photo-viewer-arrow:hover,
.photo-viewer-arrow:focus-visible {
  background: rgba(255, 255, 255, 0.25);
}
.photo-viewer-prev {
  left: 0.5rem;
}
.photo-viewer-next {
  right: 0.5rem;
}
.photo-viewer-single .photo-viewer-arrow {
  display: none;
}
.photo-viewer-counter {
  position: absolute;
  bottom: 0.75rem;
  left: 0;
  right: 0;
  margin: 0;
  text-align: center;
  font-size: 0.9rem;
}
@media (max-width: 575.98px) {
  .photo-viewer-stage {
    padding: 3rem 0.5rem;
  }
}
