:root {
  --gutter: clamp(1rem, 4vw, 4rem);
  --table-width: 64rem;
  /* The length of the fades (see "Fading out" below) */
  --fade-duration: 0.3s;

  /* Icon buttons (below): the distance from the screen edge, the button size,
     and the size of the icon centered in the button */
  --icon-button-inset: 0.75rem;
  --icon-button-size: 2.75rem;
  --icon-size: 1.1rem;
  /* Distance from the screen edge to the visible icon */
  --icon-inset: calc(
    var(--icon-button-inset) + (var(--icon-button-size) - var(--icon-size)) / 2
  );
}

/* ---------- Page ---------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

/* The scrollbar is hidden with the standard scrollbar-width property, which
   Safari supports from version 18.2. Any ::-webkit-scrollbar style gives the
   page a custom scrollbar. Safari scrolls a page with a custom scrollbar on
   the main thread, so smooth scrolling drops frames. */
html {
  scrollbar-width: none;
}

/* No top padding beyond the safe area: the table starts at the top of the
   page, so the top of the page and the first row are the same position. The
   first row makes room for the top bar instead (see "Table" below). */
body {
  margin: 0;
  padding: env(safe-area-inset-top, 0px)
    max(var(--gutter), env(safe-area-inset-right, 0px))
    calc(6rem + env(safe-area-inset-bottom, 0px))
    max(var(--gutter), env(safe-area-inset-left, 0px));
}

/* ---------- Page title ----------
   At the top left of the page, level with the icon buttons. The title is
   positioned absolutely rather than fixed, so the title scrolls away with the
   page and never covers the table text on narrow screens. Absolute
   positioning also keeps the title out of the page flow, so the first row's
   top padding (see "Table" below) makes room for the title too. The title is
   as far from the left edge as the rightmost icon is from the right edge. The
   title is centered in a box as tall as an icon button, at the same top
   offset, so the title and the icons share a midline. */
.site-title {
  position: absolute;
  top: calc(var(--icon-button-inset) + env(safe-area-inset-top, 0px));
  z-index: 5;
  left: calc(var(--icon-inset) + env(safe-area-inset-left, 0px));
  display: flex;
  align-items: center;
  min-height: var(--icon-button-size);
  max-width: calc(
    100% - var(--icon-inset) - 10rem
  ); /* clear of the three icon buttons */
  margin: 0;
}

/* ---------- Theme change animation ----------
   Browsers with view transitions crossfade the whole page. */

@media (prefers-reduced-motion: no-preference) {
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation-duration: 0.4s;
    animation-timing-function: ease;
  }
}

/* Fallback: theme.js adds this class briefly when view transitions are
   unavailable, so colors fade instead of switching at once. */
:root.theme-transition,
:root.theme-transition *,
:root.theme-transition *::before,
:root.theme-transition *::after {
  transition:
    background-color 0.4s ease,
    color 0.4s ease,
    border-color 0.4s ease,
    box-shadow 0.4s ease !important;
}

/* ---------- Icon buttons ----------
   The theme toggle (theme.js), the search button (search.js) and the key hint
   toggle (hint-toggle.js), side by side at the top right. The icon is a mask
   filled with the button's text color. */

.icon-button {
  position: fixed;
  top: calc(var(--icon-button-inset) + env(safe-area-inset-top, 0px));
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--icon-button-size);
  height: var(--icon-button-size);
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

.icon-button::before {
  content: "";
  width: var(--icon-size);
  height: var(--icon-size);
  background: currentColor;
  -webkit-mask: var(--icon) center / contain no-repeat;
  mask: var(--icon) center / contain no-repeat;
}

.theme-toggle {
  --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 14.5A8 8 0 0 1 9.5 4a8 8 0 1 0 10.5 10.5z'/%3E%3C/svg%3E");
  right: calc(var(--icon-button-inset) + env(safe-area-inset-right, 0px));
}

/* In dark mode the button shows a sun, the mode it switches to */
.theme-toggle[data-mode="dark"] {
  --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='4'/%3E%3Cpath d='M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.3 5.3l1.4 1.4M17.3 17.3l1.4 1.4M5.3 18.7l1.4-1.4M17.3 6.7l1.4-1.4'/%3E%3C/svg%3E");
}

.search-toggle {
  --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='10.5' cy='10.5' r='6.5'/%3E%3Cpath d='M15.5 15.5 20 20' stroke-width='2.25'/%3E%3C/svg%3E");
  right: calc(
    var(--icon-button-inset) + var(--icon-button-size) +
      env(safe-area-inset-right, 0px)
  );
}

/* The key hint toggle (hint-toggle.js), left of the search button */
.hints-toggle {
  --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='2.5' y='6' width='19' height='12' rx='2.5'/%3E%3Cpath d='M6.5 10h.01M10 10h.01M14 10h.01M17.5 10h.01M8 14h8'/%3E%3C/svg%3E");
  right: calc(
    var(--icon-button-inset) + 2 * var(--icon-button-size) +
      env(safe-area-inset-right, 0px)
  );
}

/* ---------- Sort options ----------
   A small widget (sort.js) right above the table, aligned with the table's
   left edge and so with the artist column. Collapsed, the widget shows
   "Sorted by", the chosen option, and an order arrow; the menu of options
   opens below the chosen option (data-open). The top margin keeps the
   widget clear of the fixed top bar. The first row keeps its usual top
   padding, the same space as between rows, so the widget reads as its own
   control rather than as part of the first row. */

.sort-options {
  position: relative;
  z-index: 6;
  display: flex;
  align-items: baseline;
  gap: 0.15rem;
  width: fit-content;
  margin: calc(var(--icon-button-inset) + var(--icon-button-size) + 1.5rem) 0 0
    max(0px, (100% - var(--table-width)) / 2);
}

.sort-trigger,
.sort-direction {
  padding: 0.25rem 0.35rem;
  border: 0;
  border-radius: 6px;
  background: none;
  font: inherit;
  cursor: pointer;
}

/* The chosen option and the menu, so the menu hangs from the option */
.sort-choice {
  position: relative;
}

/* The menu: a column of options in a panel like the search bar. The menu's
   left edge lines up with the chosen option's left edge, and the menu is as
   wide as the longest option. Closed, the menu is invisible and sits
   slightly higher, so opening the menu fades the menu in and drops the menu
   into place. The options run edge to edge, and the menu clips the
   highlight to the menu's rounded corners. */
.sort-menu {
  position: absolute;
  top: calc(100% + 0.35rem);
  left: 0;
  display: flex;
  flex-direction: column;
  width: max-content;
  margin: 0;
  padding: 0;
  border: 0;
  overflow: hidden;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-0.25rem);
}

.sort-options[data-open] .sort-menu {
  opacity: 1;
  visibility: visible;
  transform: none;
}

.sort-menu label {
  position: relative;
  z-index: 1;
  padding: 0.4rem 0.6rem;
  white-space: nowrap;
  cursor: pointer;
}

/* The radio buttons are hidden, and the labels are drawn as the options; the
   radio buttons still take keyboard focus */
.sort-menu input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

/* The highlight behind an option. sort.js sets the position and the size
   from the option under the pointer, or else the chosen option, and the
   transition makes the highlight glide from one option to the next. */
.sort-highlight {
  position: absolute;
  top: 0;
  pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
  .sort-menu {
    transition:
      opacity 0.15s ease-out,
      transform 0.15s ease-out,
      visibility 0s linear 0.15s;
  }

  .sort-options[data-open] .sort-menu {
    transition:
      opacity 0.15s ease-out,
      transform 0.15s ease-out,
      visibility 0s linear 0s;
  }

  .sort-highlight {
    transition:
      transform 0.2s ease,
      height 0.2s ease;
  }
}

/* ---------- Tooltips ----------
   The icon buttons at the top right show the text of data-tooltip in a
   tooltip below the button, lined up with the button's right edge, so the
   tooltip of the rightmost button stays on screen. Like the rail labels, a
   tooltip shows as soon as the pointer is over the button. Touch screens
   have no hover, so they show no tooltips. */

.icon-button[data-tooltip]::after {
  content: attr(data-tooltip);
  top: calc(100% + 0.25rem);
  right: 0;
  transform: translateY(-0.25rem);
}

.icon-button[data-tooltip]:hover::after,
.icon-button[data-tooltip]:focus-visible::after {
  opacity: 1;
  transform: none;
}

/* The rail sits at the same level, and the tooltip of the rightmost button
   reaches over the rail, so a button with its tooltip showing comes first */
.icon-button[data-tooltip]:hover,
.icon-button[data-tooltip]:focus-visible {
  z-index: 7;
}

@media (hover: none) {
  .icon-button[data-tooltip]::after {
    display: none;
  }
}

/* ---------- Footer ---------- */

/* The footer uses the same columns as a table row (see "Table" below). The
   notice goes in the left column, which holds the artwork's description in a
   row. The sources go in the right columns, which hold the authenticity text
   in a row. The title spans both columns. Because the last table row has a
   rule along the bottom edge, the footer needs no border. */
.credit {
  display: grid;
  grid-template-columns: minmax(0, 2fr) 0 repeat(3, minmax(0, 1fr));
  column-gap: 2rem;
  row-gap: 0.75rem;
  max-width: var(--table-width);
  margin: 0 auto;
  padding-top: 3rem;
}

.credit h2 {
  grid-column: 1 / -1;
  margin: 0;
}

.credit p {
  margin: 0;
}

.credit p + p {
  margin-top: 0.75em;
}

.credit-notice {
  grid-column: 1;
}

.credit-sources {
  grid-column: 3 / -1;
}

/* On narrow screens, the table rows show a single column, so the footer
   shows a single column too */
@media (max-width: 900px) {
  .credit {
    grid-template-columns: minmax(0, 1fr);
  }

  .credit-notice,
  .credit-sources {
    grid-column: 1;
  }
}

/* ---------- Search bar ----------
   Fixed at the top of the screen, level with the icon buttons. Hidden until
   search.js adds .open. */

.search-bar {
  position: fixed;
  top: calc(0.75rem + env(safe-area-inset-top, 0px));
  left: 50%;
  z-index: 6;
  /* The bar is centered, so the room on each side is equal: 10rem clears the
     title on the left (about 7.4rem wide, from the screen edge) and the three
     icon buttons on the right (9rem). On phones the key hint toggle is
     hidden, and the phone rules below place the bar beside the other two
     buttons. */
  width: min(40rem, 100% - 20rem);
  transform: translate(-50%, -0.25rem);
  opacity: 0;
  visibility: hidden;
}

.search-bar.open {
  transform: translate(-50%, 0);
  opacity: 1;
  visibility: visible;
}

input[type="search"] {
  -webkit-appearance: none;
  appearance: none;
  display: block;
  width: 100%;
  height: 2.75rem;
  margin: 0;
  border: 0;
  /* The right padding makes room for the esc keycap */
  padding: 0 3.5rem 0 1rem;
  text-align: left;
}

/* No browser clear button (WebKit and Blink): Escape and the esc keycap
   clear the query instead */
input[type="search"]::-webkit-search-cancel-button {
  display: none;
}

/* The esc keycap at the right end of the field. Clicking the keycap closes
   the bar (search.js). */
.search-esc {
  position: absolute;
  top: 50%;
  right: 0.75rem;
  transform: translateY(-50%);
  cursor: pointer;
}

/* Keeps the vertical centering when .key.pressed (below) shifts the key */
.search-bar .search-esc.pressed {
  transform: translateY(calc(-50% + 2px));
}

/* Touch screens have no Escape key */
@media (hover: none), (pointer: coarse) {
  .search-esc {
    display: none;
  }

  input[type="search"] {
    padding-right: 1rem;
  }
}

/* While the bar is open, jumps to a row (rail.js) stop low enough that the
   bar doesn't cover the row's first line of text */
html:has(.search-bar.open) {
  scroll-padding-top: calc(1rem + env(safe-area-inset-top, 0px));
}

@media (prefers-reduced-motion: no-preference) {
  /* A short ease-out: fast at the start, settling gently */
  .search-bar {
    --ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
    transition:
      opacity 0.15s var(--ease-out),
      transform 0.15s var(--ease-out),
      visibility 0s linear 0.15s;
  }

  .search-bar.open {
    transition:
      opacity 0.15s var(--ease-out),
      transform 0.15s var(--ease-out),
      visibility 0s linear 0s;
  }
}

/* ---------- Keys ----------
   A keycap. Scripts add .pressed while the key is highlighted after a press,
   and data-off when its action is unavailable. */

.key {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 1.5rem;
  height: 1.5rem;
  padding: 0 0.35rem; /* for multi-letter keys like "esc" */
  border-width: 1px 1px 3px;
  border-style: solid;
  border-radius: 3px;
  font: inherit;
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1;
  user-select: none;
}

.key.pressed {
  border-bottom-width: 1px;
  transform: translateY(2px);
}

/* ---------- Key hints ----------
   A column of keycap groups, each with a label underneath. Built by hints.js
   for the main page (.page-hints, below) and the lightbox (.lightbox-hints,
   in lightbox.css). The keycaps are clickable. */

.key-hints {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  width: 3.5rem;
  pointer-events: none;
}

.hint-group {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
}

.hint-keys {
  display: flex;
  gap: 4px;
}

.hint-grid {
  display: grid;
  grid-template-columns: repeat(2, 1.5rem);
}

.key-hints .key {
  pointer-events: auto;
  cursor: pointer;
}

.key-hints .key[data-off] {
  cursor: default;
}

.hint-label {
  font-size: 0.6875rem;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0.01em;
  white-space: nowrap;
}

/* Main page hints: the page hints (.page-hints) and the row hints
   (.row-hints), fixed in the left margin with the right edge 2rem from the
   table. The hints are 3.5rem wide, hence 5.5rem. Fixed hints take no space
   in the page, so the table stays centered. */
.page-hints,
.row-hints {
  position: fixed;
  left: calc((100vw - var(--table-width)) / 2 - 5.5rem);
  z-index: 5;
}

/* Hidden on touch screens, and on screens where the left margin is too
   narrow to fit the hints */
@media (hover: none), (pointer: coarse), (max-width: 77rem) {
  .page-hints,
  .row-hints {
    display: none;
  }
}

/* The key hint toggle shows wherever any hints can show. The lightbox hints
   show on more screens than the main page's hints, so the toggle uses the
   same condition as the lightbox hints (the touch layout in lightbox.css). */
@media (max-width: 700px), (pointer: coarse) {
  .hints-toggle {
    display: none;
  }
}

.page-hints {
  top: 50%;
  transform: translateY(-50%);
}

/* Currently hidden everywhere: the search button and clicking an image
   already reach search and the lightbox, so the hints only add clutter. The
   shortcuts (L and /) still work. Delete this rule to show the hints again. */
.page-hints {
  display: none;
}

/* Row hints: the arrow-key shortcuts for moving between rows
   (shortcuts.js). The hints for moving up sit at the top of the screen,
   below the title and icon buttons, and the hints for moving down sit at the
   bottom. At the first row, the Top and Previous hints fade out (see "Fading
   out" below), and likewise Next and End at the last row. */
.row-hints-top {
  top: calc(
    var(--icon-button-inset) + var(--icon-button-size) + 1.5rem +
      env(safe-area-inset-top, 0px)
  );
}

.row-hints-bottom {
  bottom: calc(2rem + env(safe-area-inset-bottom, 0px));
}

/* ---------- Row navigator ----------
   A column of short bars fixed to the right edge, one per row. The bar for the
   row in view is longer. Built by rail.js. */

.rail {
  position: fixed;
  top: 50%;
  right: 0.75rem;
  z-index: 5;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  max-height: 80vh;
}

.rail button {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex: 0 1 0.75rem; /* tall enough to click; shrinks when there are many rows */
  min-height: 4px;
  width: 1.5rem;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

.rail button[hidden] {
  display: none;
}

/* Each bar is drawn at full length and scaled down from the right edge with a
   transform. Safari does not repaint the area that a bar leaves when the
   bar's width shrinks, so a width transition would leave part of the longer
   bar on screen. */
.rail button::before {
  content: "";
  display: block;
  width: 1.5rem;
  height: 2px;
  background: currentColor;
  transform: scaleX(0.5);
  transform-origin: right;
}

.rail button[aria-current="true"]::before {
  transform: none;
}

/* Name appears to the left on hover or keyboard focus */
/* The rail labels and the tooltips (see "Tooltips" below) share one look:
   a small box that fades in on hover */
.rail button::after,
.icon-button[data-tooltip]::after {
  position: absolute;
  padding: 0.35rem 0.75rem;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
}

.rail button::after {
  content: attr(data-label);
  top: 50%;
  right: calc(100% + 0.6rem);
  transform: translate(0.35rem, -50%);
}

.rail button:hover::after,
.rail button:focus-visible::after {
  opacity: 1;
  transform: translate(0, -50%);
}

@media (prefers-reduced-motion: no-preference) {
  .rail button::before {
    transition:
      transform 0.2s ease,
      opacity 0.2s ease;
  }

  .rail button::after,
  .icon-button[data-tooltip]::after {
    transition:
      opacity 0.15s ease,
      transform 0.15s ease;
  }
}

/* Hidden on narrow screens */
@media (max-width: 900px) {
  .rail {
    display: none;
  }
}

/* ---------- Fading out ----------
   Controls that fade out while they have nothing to offer: the rail when one
   or no rows are showing, a row hint at the first or last row, and all key
   hints (on the main page and in the lightbox) while the key hint toggle
   (hint-toggle.js) hides them. visibility keeps the faded controls from
   being clicked or focused once the fade finishes. */

.rail[data-single],
.row-hints .hint-group:has(.key[data-off]),
:root[data-hide-key-hints] .key-hints .hint-group {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
  .rail,
  .key-hints .hint-group {
    transition:
      opacity var(--fade-duration) ease,
      visibility 0s linear 0s;
  }

  .rail[data-single],
  .row-hints .hint-group:has(.key[data-off]),
  :root[data-hide-key-hints] .key-hints .hint-group {
    transition:
      opacity var(--fade-duration) ease,
      visibility 0s linear var(--fade-duration);
  }
}

/* ---------- Sorting ----------
   sort.js reorders the rows inside a view transition, with data-sorting on
   the root element, so the page crossfades from the old order to the new
   one. The crossfade is short, so a sort feels quick. Browsers without view
   transitions reorder at once. */

:root[data-sorting]::view-transition-old(root),
:root[data-sorting]::view-transition-new(root) {
  animation-duration: 0.2s;
  animation-timing-function: ease;
}

/* ---------- Table ---------- */

.museum-table,
.museum-table tbody {
  display: block;
  width: auto;
  max-width: var(--table-width);
  margin: 0 auto;
}

/* Visually hidden but available to assistive technology: the column heads,
   and the "Sort by" legend of the sort options */
.museum-table thead,
.sort-options legend {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.museum-table tbody tr {
  display: grid;
  grid-template-columns: minmax(0, 2fr) 0 repeat(3, minmax(0, 1fr));
  grid-template-areas:
    "artist rule game game game"
    "name rule game game game"
    "year rule game game game"
    "media rule game game game"
    "place rule game game game"
    "orig rule img1 img2 img3"
    "about rule tell tell tell"
    "extra rule tell tell tell";
  column-gap: 2rem;
  row-gap: 0.35rem;
  padding: 3rem 0 3.25rem;
}

/* The rule between the two sides; a theme sets its width and color */
.museum-table tbody tr::before {
  content: "";
  grid-area: rule;
  justify-self: center;
  width: 1px;
  display: none;
}

/* Rows hidden by the search script. display: grid would otherwise override
   the default behavior of [hidden]. */
.museum-table tbody tr[hidden] {
  display: none;
}

.museum-table tbody td {
  display: block;
  min-width: 0;
  padding: 0;
  border: 0;
}

/* A cell with a data-label attribute shows it above the cell's content. */
.museum-table td[data-label]::before {
  content: attr(data-label);
  display: block;
  margin-bottom: 0.4rem;
}

/* ---------- Placement ----------
   Each cell is placed by its class, which src/app.py sets from the column. */

.museum-table .ac_name {
  grid-area: game;
}
.museum-table .real_name {
  grid-area: name;
}
.museum-table .artist {
  grid-area: artist;
}
.museum-table .year {
  grid-area: year;
}
.museum-table .location {
  grid-area: place;
}
.museum-table .medium {
  grid-area: media;
}
.museum-table .desc {
  grid-area: about;
}
.museum-table .extra-desc {
  grid-area: extra;
}
.museum-table .auth {
  grid-area: tell;
}
.museum-table .real_img {
  grid-area: img1;
}
.museum-table .fake_img {
  grid-area: img2;
}
.museum-table .diff_img {
  grid-area: img3;
}
.museum-table .orig_img {
  grid-area: orig;
}

.museum-table .ac_name {
  align-self: center;
}

.museum-table .auth {
  max-width: 32rem;
  margin-top: 1.75rem;
}

.museum-table .year {
  padding-top: 0.3rem;
}

.museum-table .desc {
  max-width: 36rem;
  margin-top: 1.75rem;
}

.museum-table .real_img,
.museum-table .fake_img,
.museum-table .diff_img,
.museum-table .orig_img {
  display: flex;
  flex-direction: column;
  margin-top: 2.5rem;
}

.museum-table img {
  display: block;
  width: 100%;
  max-width: 11rem;
  height: auto;
}

.museum-table .orig_img img {
  max-width: 100%;
  width: 100%;
}

/* Captions */
.museum-table .real_img::after,
.museum-table .fake_img::after,
.museum-table .diff_img::after,
.museum-table .orig_img::after {
  display: block;
  /* margin-top: auto; */
  padding-top: 1rem;
  line-height: 1.4;
}

.museum-table .real_img::after {
  content: "Genuine";
}
.museum-table .fake_img::after {
  content: "Forgery";
}
.museum-table .diff_img::after {
  content: "Forgery cues";
}

/* No caption for a cell without an image, such as the forgery and
   differences cells in rows with no forgery. The empty cell keeps its column,
   so the other images stay lined up. */
.museum-table :is(.real_img, .fake_img, .diff_img):not(:has(img))::after {
  content: none;
}

/* ---------- Narrower screens ---------- */

@media (max-width: 900px) {
  .museum-table tbody tr {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-template-areas:
      "artist artist artist"
      "name   name   name"
      "year   year   year"
      "media  media  media"
      "place  place  place"
      "orig   orig   orig"
      "about  about  about"
      "extra  extra  extra"
      "game   game   game"
      "img1   img2   img3"
      "tell   tell   tell";
    column-gap: 1rem;
    row-gap: 0.5rem;
  }

  .museum-table tbody tr::before {
    display: none;
  }

  .museum-table .ac_name {
    align-self: auto;
    margin-top: 2.5rem;
  }

  .museum-table .desc,
  .museum-table .auth {
    max-width: none;
  }

  .museum-table .auth {
    margin-top: 1.25rem;
  }

  .museum-table td.orig_img img {
    max-width: min(100%, 40rem);
  }
}

/* ---------- Phones ---------- */

@media (max-width: 600px) {
  /* The bar spans from the page margin to the icon buttons */
  .search-bar {
    left: max(var(--gutter), env(safe-area-inset-left, 0px));
    right: calc(6.75rem + env(safe-area-inset-right, 0px));
    width: auto;
    transform: translateY(-0.25rem);
  }

  .search-bar.open {
    transform: none;
  }

  /* Rows have less top padding on phones */
  html:has(.search-bar.open) {
    scroll-padding-top: calc(2rem + env(safe-area-inset-top, 0px));
  }

  .museum-table tbody tr {
    padding: 2rem 0 2.25rem;
  }

  .museum-table .real_img,
  .museum-table .fake_img,
  .museum-table .diff_img,
  .museum-table .orig_img {
    margin-top: 1.5rem;
  }

  .museum-table .desc,
  .museum-table .auth {
    margin-top: 1.25rem;
  }

  .museum-table .ac_name {
    margin-top: 1.75rem;
  }

  .museum-table td.orig_img img {
    max-width: 100%;
  }

  /* Phones hide image cells without an image */
  .museum-table :is(.real_img, .fake_img, .diff_img, .orig_img):not(:has(img)) {
    display: none;
  }
}

/* ---------- Print ---------- */

@media print {
  .icon-button,
  .search-bar,
  .sort-options,
  .page-hints,
  .row-hints,
  .rail {
    display: none;
  }

  .museum-table tbody tr {
    break-inside: avoid;
  }
}
