/* The collection stylesheet. Paper and ink, Young Serif titles, Figtree body,
   wall labels under the works.

   Literal colors appear once, in the token block below, and nowhere else in
   this file or in any template. Everything downstream reads a var(), so a
   change to the palette is a change to one block. */

:root {
  color-scheme: light;

  --paper:      #f7f7f5;   /* page ground */
  --paper-2:    #eeeeeb;   /* image placeholder while loading, table zebra */
  --ink:        #141414;   /* text, rules, filled buttons, dark bands */
  --ink-2:      #333333;   /* lede and body on paper */
  --ink-3:      #6b6b6b;   /* wall labels, meta, secondary nav */
  --rule:       #141414;   /* 1px rules; never lighter than ink on paper */
  --accent:     #4b3fd6;   /* links, the one eyebrow line per page. Nothing else. */
  --on-dark:    #f7f7f5;   /* text on dark bands */
  --on-dark-2:  #c9c9c4;
  --on-dark-3:  #9a9a95;
  --verdict-nailed: #2f7d4f;  --verdict-close: #8a8a86;  --verdict-what: #b3402e; /* prompt vs reality only */

  /* The dialog scrim: ink at 60%. Written as rgb() rather than a hex pair so
     the one place colors live stays the one place they live. */
  --scrim: rgb(20 20 20 / 0.6);

  --serif: "Young Serif", Georgia, "Times New Roman", serif;
  --sans: "Figtree", "Helvetica Neue", Arial, sans-serif;

  /* Body measure, in the middle of the 58-to-66 character range. */
  --measure: 62ch;

  --gutter: 64px;
  --section-gap: 72px;
}

/* --- Reset ---------------------------------------------------------------- */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.5;
  font-weight: 400;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  /* The one thing standing between a long prompt and a horizontal scrollbar. */
  overflow-wrap: break-word;
}

img, svg { display: block; max-width: 100%; }

h1, h2, h3, h4, p, figure, blockquote, ul, ol, dl, dd { margin: 0; }

ul, ol { padding: 0; list-style: none; }

button, input, textarea, select { font: inherit; color: inherit; }

/* One rule, applied everywhere, so nothing is reachable without being visible. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* --- Type ----------------------------------------------------------------- */

.display-xl, .display-l, .display-m, .display-s {
  font-family: var(--serif);
  font-weight: 400;
  text-wrap: balance;
}

.display-xl { font-size: 72px; line-height: 1.02; letter-spacing: -0.015em; }
.display-l  { font-size: 44px; line-height: 1.05; letter-spacing: -0.015em; }
.display-m  { font-size: 30px; line-height: 1.15; }
.display-s  { font-size: 22px; line-height: 1.2; }

.lede  { font-size: 20px; line-height: 1.45; color: var(--ink-2); }

.body  { font-size: 17px; line-height: 1.5; color: var(--ink-2); }
.small { font-size: 15px; line-height: 1.45; }
.label { font-size: 13px; line-height: 1.4; }

/* The reset zeroes every margin, so the system says once where vertical space
   goes: under a title, and between paragraphs that follow one another. A page
   that wants something else says so; a page that says nothing still breathes. */
.display-xl, .display-l, .display-m, .display-s { margin-block-end: 24px; }
p + p { margin-block-start: 20px; }


/* Prose sets its own measure so a page never has to remember to. */
.measure { max-width: var(--measure); }

a { color: var(--accent); text-decoration: none; text-underline-offset: 0.18em; }
a:hover, a:focus-visible { text-decoration: underline; }

.link-plain { color: inherit; }

/* A button that reads as a link: More, Edit, Up, Down, Hide. Without this the
   browser draws its own grey box around the word. */
button.link-plain {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: var(--ink-3);
  text-underline-offset: 0.18em;
  cursor: pointer;
}
button.link-plain:hover, button.link-plain:focus-visible { color: var(--ink); text-decoration: underline; }

strong, b { font-weight: 600; }

/* --- Layout --------------------------------------------------------------- */

.container {
  width: 100%;
  max-width: 1440px;
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.grid-12 {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: 32px;
}

.span-7 { grid-column: span 7; }
.span-5 { grid-column: span 5; }
.span-6 { grid-column: span 6; }
.span-12 { grid-column: span 12; }

/* Works. Five across on a desktop, three on a tablet, two on a phone. */
.work-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: 20px;
  row-gap: 28px;
}

/* Vertical rhythm inside a block: forms, note stacks, anything that is a list
   of things one under another. */
.stack > * + * { margin-block-start: 20px; }

/* Sections are told apart by space, never by a card or a rule. */
.section { margin-block-start: var(--section-gap); }
.section:first-child { margin-block-start: 0; }

/* The single rule this system allows: under a section title row that carries
   filters or a count. */
.section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px 32px;
  padding-block-end: 16px;
  border-block-end: 1px solid var(--rule);
  margin-block-end: 32px;
}

/* The row aligns on the baseline, so nothing inside it carries the title's
   usual space underneath. */
.section-head > * { margin-block: 0; }

.band {
  background: var(--ink);
  color: var(--on-dark);
  padding-block: var(--section-gap);
}

.band .lede, .band .body { color: var(--on-dark-2); }
.band .wall-label, .band .meta { color: var(--on-dark-3); }
/* The accent is a paper colour. On ink it reads at 2.6:1, so the eyebrow gives
   it up rather than the band giving up the contrast. */
.band .eyebrow { color: var(--on-dark-2); }
.band a { color: var(--on-dark); text-decoration: underline; }

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--ink);
  color: var(--paper);
  padding: 12px 20px;
  z-index: 10;
}
.skip-link:focus { left: 0; }

/* --- Nav and footer ------------------------------------------------------- */

/* The wordmark and its tagline are one block, and the navigation sits beside
   them. They used to be a nav row with the tagline pulled up under it, which
   put the tagline under the links as soon as the links wrapped. */
.site-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px 24px;
  padding-block: 25px 0;
}

.nav { padding-block-start: 3px; }

.brand {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 22px;
  line-height: 1.2;
  color: var(--ink);
}
.brand:hover, .brand:focus-visible { text-decoration: none; }

.nav-links {
  display: flex;
  flex-wrap: wrap;
  gap: 28px;
  font-size: 15px;
  font-weight: 500;
}

.nav-links a { color: var(--ink-3); }
.nav-links a:hover, .nav-links a:focus-visible { text-decoration: none; color: var(--ink); }
.nav-links a[aria-current="page"] { color: var(--ink); }

/* The masthead's line, under the wordmark and on every page. The display face,
   because it belongs to the name above it, and quiet, because the name is what
   should be read first. */
.tagline {
  font-family: var(--serif);
  font-size: 15px;
  line-height: 1.3;
  color: var(--ink-3);
  margin-block: 6px 0;
}

/* The curator's own row of links, under the site's, on every page behind the
   door. A rule under it says the pages below it are not the public site. */
.curate-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px 24px;
  margin-block-start: 20px;
  padding-block: 12px;
  border-block-end: 1px solid var(--rule);
}

.page-main { flex: 1; padding-block: 32px var(--section-gap); }

.colophon {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px 32px;
  padding-block: 32px 40px;
  font-size: 14px;
  line-height: 1.45;
  color: var(--ink-3);
}

/* --- Component: work-figure ----------------------------------------------- */

.work-figure { display: block; }

.work-figure img {
  width: 100%;
  height: auto;
  background: var(--paper-2);
}

/* Grids crop to a common 2:3; a work page shows the whole picture. */
.work-grid .work-figure img {
  aspect-ratio: 2 / 3;
  object-fit: cover;
}

/* The held space for a work whose picture is not there: the loading ground at
   the ratio the picture would have had. */
.work-plate {
  aspect-ratio: 2 / 3;
  width: 100%;
  background: var(--paper-2);
}

.wall-label {
  margin-block-start: 12px;
  font-size: 13px;
  line-height: 1.4;
  color: var(--ink-3);
}

.wall-label .prompt {
  font-style: italic;
  display: block;
}

.wall-label .meta { display: block; }

.wall-label a { color: var(--ink-3); }
.wall-label a:hover, .wall-label a:focus-visible { color: var(--accent); }

/* --- Component: button ---------------------------------------------------- */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 50px;
  padding-inline: 24px;
  border: 1px solid var(--ink);
  border-radius: 0;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--sans);
  font-size: 16px;
  font-weight: 600;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
}
.button:hover, .button:focus-visible { text-decoration: none; color: var(--paper); }

.button-secondary {
  background: transparent;
  color: var(--ink);
}
.button-secondary:hover, .button-secondary:focus-visible { color: var(--ink); }

.button:disabled, .button[aria-disabled="true"] {
  opacity: 0.4;
  cursor: default;
}

/* --- Component: input ----------------------------------------------------- */

.input {
  width: 100%;
  height: 52px;
  padding: 0 18px;
  border: 1px solid var(--ink);
  border-radius: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
}

.input:focus { outline: 2px solid var(--ink); outline-offset: 0; }

textarea.input {
  height: auto;
  padding: 14px 18px;
  line-height: 1.5;
  resize: vertical;
}

.field { display: block; max-width: var(--measure); }

.field > .field-label {
  display: block;
  margin-block-end: 8px;
  font-size: 13px;
  line-height: 1.4;
  font-weight: 600;
  color: var(--ink-3);
}

/* --- Component: filter-row ------------------------------------------------ */

.filter-nav { max-width: 100%; }

.filter-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
  font-size: 14px;
  font-weight: 500;
}

.filter-row a { color: var(--ink-3); }
.filter-row a:hover, .filter-row a:focus-visible { color: var(--ink); text-decoration: none; }
.filter-row a[aria-current="true"] { color: var(--ink); }

/* --- Component: eyebrow --------------------------------------------------- */

.eyebrow {
  margin-block-end: 12px;
  font-size: 13px;
  line-height: 1.4;
  font-weight: 600;
  color: var(--accent);
}

/* --- Component: dialog ---------------------------------------------------- */

.dialog {
  max-width: 520px;
  width: calc(100% - 48px);
  padding: 32px;
  border: 1px solid var(--ink);
  border-radius: 0;
  background: var(--paper);
  color: var(--ink);
}

.dialog::backdrop { background: var(--scrim); }

.dialog-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-block-start: 24px;
}

/* --- Component: flash ----------------------------------------------------- */

/* A line at the top of the content, not a toast: it stays put, it is readable
   by a screen reader in document order, and it survives a page without script. */
.flash {
  margin-block-end: 32px;
  padding: 14px 18px;
  border: 1px solid var(--rule);
  font-size: 15px;
  line-height: 1.45;
  max-width: var(--measure);
}

.flash-error { background: var(--ink); color: var(--on-dark); }

/* --- Motion --------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
  a { transition: color 120ms linear; }
  .dialog { transition: opacity 160ms linear; }
}

/* --- Narrow widths -------------------------------------------------------- */

@media (max-width: 719px) {
  :root { --gutter: 24px; --section-gap: 64px; }

  /* The scale above is the desktop scale. Seventy-two pixels of Young Serif
     does not fit a 360px viewport, and "no horizontal scroll at 360" is the
     criterion that wins. */
  .display-xl { font-size: 44px; line-height: 1.05; }
  .display-l  { font-size: 34px; line-height: 1.08; }
  .display-m  { font-size: 26px; line-height: 1.18; }

  .grid-12 { grid-template-columns: minmax(0, 1fr); gap: 32px; }
  .span-4, .span-5, .span-6, .span-7, .span-8, .span-12 { grid-column: span 1; }

  .site-header { flex-direction: column; align-items: stretch; padding-block: 20px 0; }
  .nav { padding-block-start: 0; }
  .nav-links { gap: 8px 20px; }
}

@media (min-width: 720px) {
  .work-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (min-width: 1200px) {
  .work-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}

/* --- The collection pages -------------------------------------------------- */

/* The front page's hero. The picture sits beside the title on a desktop and
   under it everywhere else, which the 12-column grid already does. */
.hero { align-items: start; }

.hero-work { max-width: 420px; }

/* Two controls side by side, wrapping rather than shrinking. */
.button-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-block-start: 32px;
}

/* The line under a pair of buttons that says what the second one costs. */
.note { margin-block-start: 16px; color: var(--ink-3); }

.page-main > .band { margin-block-start: var(--section-gap); }

.band-copy { align-self: center; }

/* --- The index ------------------------------------------------------------- */

/* Two filter rows stacked on the right of the title row: subjects, then
   verdicts once there are any. */
.filter-stack { display: grid; gap: 10px; justify-items: start; }

.search-form {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  gap: 12px;
  margin-block-end: 32px;
}

.search-form .field { flex: 1 1 320px; }

/* The button sits on the input's baseline, which means matching its height
   rather than the field's, since the field carries a label above it. */
.search-form .button { height: 52px; }

/* The title and, when there is a search to undo, the link that undoes it. */
.heading-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px 16px;
}

.clear { font-weight: 500; }

.empty { margin-block: 8px 0; }

/* Plain text at the foot of a list of works. Not buttons: turning a page is
   going somewhere, and the browser already draws that. */
.pagination {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 16px 32px;
  margin-block-start: var(--section-gap);
  font-size: 15px;
  font-weight: 500;
}

/* One link on its own goes to the side it belongs on, so "Earlier works" does
   not slide left when there is nothing later. */
.pagination > a:only-child:last-child { margin-inline-start: auto; }

/* --- The work page --------------------------------------------------------- */

.work-page { align-items: start; }

.work-plate-column { display: flex; justify-content: center; }

/* The whole picture, never cropped. It is bounded by the viewport rather than
   by the column so a 512 × 768 work does not push the wall label off the
   screen on a short window. */
.work-full {
  width: auto;
  max-width: 100%;
  max-height: calc(100vh - 160px);
  height: auto;
  background: var(--paper-2);
}

.work-label .lede { margin-block-end: 32px; }

/* The wall label proper: a term and its value on one row, terms in the quiet
   ink so the values are what the eye lands on. */
.label-list {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 8px 24px;
  font-size: 15px;
  line-height: 1.45;
}

.label-list dt { color: var(--ink-3); }
.label-list dd { color: var(--ink-2); margin: 0; }

/* The document pages: About and License.
   Headings sit in a rail to the left of the prose rather than above it, so a
   heading and the paragraph it introduces start on the same line. A page of
   short sections stacked in one column reads as a list of disconnected blocks,
   which is what this is here to stop. Everything a reader actually reads sits
   in one column at one measure — the spec sheet included, because a definition
   list wider than the paragraph above it is the thing the eye notices first. */
.document-head { margin-block-end: 56px; }
.document-head > h1 { margin-block-end: 0; }

/* A document with no section headings — the license — is one column at the
   same measure, aligned with its own title. Running it through the rail layout
   above would indent the whole page past an empty gutter, which reads as a
   mistake rather than as a margin. */
.doc-body { max-width: var(--measure); }
.doc-body > * + * { margin-block-start: 14px; }
.doc-body > .lede + * { margin-block-start: 22px; }

.doc-section {
  display: grid;
  grid-template-columns: 200px minmax(0, var(--measure));
  column-gap: 48px;
  margin-block-start: 44px;
}
.doc-section:first-of-type { margin-block-start: 0; }
.doc-section > * { grid-column: 2; }
.doc-section > * + * { margin-block-start: 14px; }
.doc-section > h2 {
  grid-column: 1;
  grid-row: 1;
  margin-block-end: 0;
  color: var(--ink-3);
}
.doc-section > h2 + * { margin-block-start: 0; }
.doc-section > .button { margin-block-start: 24px; justify-self: start; }
.doc-section > .label-list { margin-block-start: 20px; }

@media (max-width: 1023px) {
  /* Under the width the rail needs, the heading goes back above its prose.
     Every child moves to the one remaining column: a child still asking for
     column 2 would make grid create an implicit one and take the width with
     it, leaving the headings stacked one letter wide. */
  .doc-section { grid-template-columns: minmax(0, 1fr); column-gap: 0; }
  .doc-section > * { grid-column: 1; }
  .doc-section > h2 { grid-row: auto; margin-block-end: 12px; }
  .doc-section > h2 + * { margin-block-start: 0; }
}

@media (max-width: 1199px) {
  /* Under the width the two columns need, the picture goes first at full
     width and the label follows it, which is the order the markup is in. */
  .work-page { grid-template-columns: minmax(0, 1fr); }
  .work-page > .span-5, .work-page > .span-7 { grid-column: span 1; }
  .work-full { max-height: none; }
}

@media (max-width: 719px) {
  .hero-work { max-width: none; }
  .search-form .field { flex-basis: 100%; }
}

/* --- The rack ------------------------------------------------------------- */

/* /machines is a diagram of a room: ten servers down the page, four Tesla K80
   halves across each one. It is not a table. A table would promise that the
   columns mean something comparable, and slot 2 of one server has nothing to do
   with slot 2 of another — they are positions in a chassis, not a series. */

.rack-layout { row-gap: 56px; }

.rack {
  display: grid;
  row-gap: 6px;
}

.rack-row {
  display: grid;
  grid-template-columns: 96px repeat(4, minmax(0, 1fr));
  align-items: center;
  column-gap: 6px;
}

.rack-node {
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

/* A cell is 40px tall whatever it says, so the rack keeps its shape while the
   fleet changes under it. Text that does not fit is clipped rather than
   wrapping: a cell that grows moves every row below it. */
.slot {
  height: 40px;
  display: flex;
  align-items: center;
  padding-inline: 10px;
  font-size: 12px;
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  font-variant-numeric: tabular-nums;
}

/* The four states, and the whole legend the lede describes. Dark is a visitor
   waiting, violet is the loop, light is a machine with nothing to do, and an
   outline is a machine that is not answering. */
.slot-commission { background: var(--ink); color: var(--paper); }
.slot-loop { background: var(--accent); color: var(--paper); }
.slot-resting { background: var(--paper-2); color: var(--ink-3); }
.slot-off { background: var(--paper); box-shadow: inset 0 0 0 1px var(--paper-2); }

.rack-counts {
  margin-block-start: 20px;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

.rack-week { color: var(--ink-3); font-variant-numeric: tabular-nums; }

/* Under 1200px the aside goes below the rack rather than beside it, and the
   rack keeps its full width: forty cells at half the width are unreadable long
   before the paragraph beside them is. */
@media (max-width: 1199px) {
  .rack-layout > .span-7,
  .rack-layout > .span-5 { grid-column: span 12; }
}

@media (max-width: 700px) {
  .rack-row { grid-template-columns: 72px repeat(4, minmax(0, 1fr)); column-gap: 4px; }
  .slot { padding-inline: 6px; font-size: 11px; }
}

/* --- The commission ------------------------------------------------------

   The one page where the site is a studio rather than a museum. The frames
   still hang the way works do — paper ground, wall label underneath, nothing
   overlaid on the picture — and the only thing that moves is the blur coming
   off a frame as the machine drawing it makes up its mind. */

.span-8 { grid-column: span 8; }
.span-4 { grid-column: span 4; }

.commission-form > * + *,
.sign-in-form > * + * { margin-block-start: 24px; }
.fixed-settings { color: var(--ink-3); max-width: var(--measure); }
.terms { color: var(--ink-3); max-width: var(--measure); }

.select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-3) 50%),
                    linear-gradient(135deg, var(--ink-3) 50%, transparent 50%);
  background-position: calc(100% - 20px) calc(50% + 2px), calc(100% - 14px) calc(50% + 2px);
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
  padding-inline-end: 40px;
}

.commission-prompt {
  font-size: 20px;
  line-height: 1.4;
  font-style: italic;
  color: var(--ink-2);
}

.frame-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 24px 20px;
}

/* The held space a frame occupies before anything has been drawn into it. It
   is the same ground a missing work uses, because that is what it is: a place
   on the wall with nothing on it yet. */
.frame-plate {
  background: var(--paper-2);
  display: block;
  width: 100%;
  overflow: hidden;
}

/* The three shapes a commission can ask for. The plate holds the one the
   machines are drawing, so the page does not reflow when the frames land. */
.frame-portrait  { aspect-ratio: 512 / 768; }
.frame-landscape { aspect-ratio: 768 / 512; }
.frame-square    { aspect-ratio: 1 / 1; }

.frame-plate img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* A preview is a half-drawn picture decoded cheaply, and it looks like one.
   The blur is set per frame from the step the machine is on, so it is an
   inline style rather than a class; what is here is the transition it eases
   along and the opacity it comes in at. */
.frame-drawing .frame-plate img {
  opacity: 0.6;
  filter: blur(12px);
  transition: filter 400ms linear, opacity 400ms linear;
}

.frame-done .frame-plate img,
.frame-flagged .frame-plate img {
  opacity: 1;
  filter: none;
}

.frame-failed .frame-plate,
.frame-flagged .frame-plate {
  border: 1px solid var(--paper-2);
  background: var(--paper);
}

.frame-actions { display: block; margin-block-start: 8px; }

.button-small {
  height: 32px;
  padding-inline: 14px;
  font-size: 13px;
}

.reuse {
  margin-block-start: 32px;
  display: flex;
  align-items: center;
  gap: 16px 20px;
  flex-wrap: wrap;
}

.checkbox {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 15px;
  line-height: 1.45;
  color: var(--ink-2);
  cursor: pointer;
}

.checkbox input {
  margin: 2px 0 0;
  width: 16px;
  height: 16px;
  accent-color: var(--ink);
}

.receipt { color: var(--ink-3); margin-block-start: 16px; }

.commission-actions {
  margin-block-start: 32px;
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}

.commission-actions form { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }

.seeds { color: var(--ink-3); font-variant-numeric: tabular-nums; }

@media (max-width: 900px) {
  .frame-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (prefers-reduced-motion: reduce) {
  .frame-drawing .frame-plate img { transition: none; }
}

/* --- Prompt vs reality ------------------------------------------------------ */

/* The round is the page: the band fills the viewport and the work hangs on it,
   so a picture that is hard to read sits where a difficult painting would. */
.versus-band {
  padding-block: calc(var(--section-gap) + 16px);
  margin-block-end: var(--section-gap);
}

.round-ask { align-self: center; }

/* Somebody else's words, quoted rather than styled as a heading: this is the
   one line on the site that was typed by a visitor. */
.round-prompt {
  margin: 8px 0 32px;
  padding: 0;
  border: 0;
  max-width: 30ch;
  font-size: 24px;
  line-height: 1.4;
  color: var(--on-dark);
}

.round-asked, .round-instead { color: var(--on-dark-3); }

.round-question {
  margin-block-end: 16px;
  font-size: 17px;
  color: var(--on-dark-2);
}

/* On ink the secondary button is a hairline of paper rather than of ink. */
.band .button-secondary {
  border-color: var(--on-dark);
  color: var(--on-dark);
  background: transparent;
}

.band .button-secondary:hover, .band .button-secondary:focus-visible {
  background: var(--on-dark);
  color: var(--ink);
}

/* The one primary button that appears on a band: paper, with the ink's own
   text, so the way on is the brightest thing in the band. */
.button-paper {
  background: var(--paper);
  border-color: var(--paper);
  color: var(--ink);
}

.button-paper:hover, .button-paper:focus-visible {
  background: var(--on-dark-2);
  border-color: var(--on-dark-2);
}

/* Three rectangles, one bar. It is 10 units tall in its own coordinates and
   10 pixels tall on the page, stretched to whatever width it is given. */
.verdict-bar {
  display: block;
  width: 100%;
  height: 10px;
  margin-block-end: 12px;
  background: var(--on-dark-3);
}

.verdict-bar .verdict-nailed { fill: var(--verdict-nailed); }
.verdict-bar .verdict-close  { fill: var(--verdict-close); }
.verdict-bar .verdict-what   { fill: var(--verdict-what); }

.verdict-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 20px;
  margin: 0;
  font-size: 12px;
  color: var(--on-dark-3);
  font-variant-numeric: tabular-nums;
}

/* The visitor's own answer, so somebody can find their vote in the result. */
.verdict-mine { color: var(--on-dark); font-weight: 600; }

.round-votes {
  margin-block: 16px 0;
  font-size: 13px;
  color: var(--on-dark-2);
  font-variant-numeric: tabular-nums;
}

/* The work, uncropped, on the ink. It is bounded by the height of the window
   as well as by its column, so the round is one screen: a band taller than the
   viewport hides the question under the picture. */
.round-work {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.round-work img {
  max-width: 100%;
  max-height: 62vh;
  width: auto;
  height: auto;
  background: var(--ink-2);
}

.round-work .body { color: var(--on-dark-2); max-width: var(--measure); }
.round-instead { margin-block: 16px 4px; }

/* Six across under the band, which is the whole of a session's history. */
.earlier-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* On paper the verdict colours label a work rather than fill a bar, so they
   are the same three names used as ink. */
.wall-label .verdict-nailed { background: none; color: var(--verdict-nailed); }
.wall-label .verdict-close  { background: none; color: var(--verdict-close); }
.wall-label .verdict-what   { background: none; color: var(--verdict-what); }

@media (min-width: 720px) {
  .earlier-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (min-width: 1200px) {
  .earlier-grid { grid-template-columns: repeat(6, minmax(0, 1fr)); }
}

/* --- The wall --------------------------------------------------------------- */

/* Kiosk mode: paper edge to edge, one work hanging on it. Every size here is
   in viewport units, because the screen this runs on is a television across a
   room and not a window somebody is reading at arm's length. */
.wall-body {
  height: 100vh;
  overflow: hidden;
  background: var(--paper);
  cursor: default;
}

/* The cursor goes after three seconds of nobody moving it. The class is put on
   by the script, so a page with no JavaScript keeps its cursor. */
.wall-body.wall-idle { cursor: none; }

.wall {
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 6vh 6vw;
}

/* The picture and the label, one column, both starting at the same left edge.
   The figure shrinks to whichever is wider and the whole thing is centred on
   the screen, which is how a label hangs beside a painting. */
.wall-frame {
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3vh;
  /* The figure is the picture's width, so the picture is what gets centred on
     the screen. The label hangs off it to the right, starting at its left edge
     the way a museum's does — it is wider than the picture and it is not what
     the room is looking at. */
  width: min-content;
  max-width: 100%;
}

/* The whole picture, never cropped and never boxed.
   78% of the height is the wall's proportion and the calc is the floor under
   it: on a 1080p screen the label and the margins need the rest, and a label
   clipped off the bottom of a television is worse than a picture an inch
   smaller. On anything taller — the 4K panel in a lobby — the 78% wins. */
.wall-work {
  max-height: min(78vh, calc(88vh - 150px));
  max-width: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
}

/* The label reads from three metres: the sizes scale with the height of the
   screen rather than being fixed at a desk's reading distance. */
.wall-plate {
  width: max-content;
  max-width: min(62ch, 86vw);
  text-align: left;
}

.wall-accession {
  margin: 0;
  font-size: clamp(20px, 2.6vh, 34px);
}

.wall-prompt {
  margin: 0.6vh 0 0;
  font-style: italic;
  color: var(--ink-2);
  font-size: clamp(17px, 2.1vh, 28px);
  line-height: 1.35;
}

.wall-detail {
  margin: 0.6vh 0 0;
  color: var(--ink-3);
  font-size: clamp(13px, 1.5vh, 20px);
}

/* The two corners. Both are the quiet ink, because neither is the work. */
.wall-address, .wall-paused {
  position: fixed;
  bottom: 2.4vh;
  margin: 0;
  color: var(--ink-3);
  font-size: clamp(12px, 1.3vh, 18px);
}

.wall-address { right: 2.4vw; }

.wall-paused {
  left: 2.4vw;
  display: flex;
  align-items: center;
  gap: 8px;
}

/* display: flex outruns the user agent's rule for the hidden attribute, so the
   word has to hide itself. Without this the wall says it is paused from the
   moment it loads, which is the one thing this word exists to tell the truth
   about. */
.wall-paused[hidden] { display: none; }

.wall-paused svg { fill: var(--ink-3); }

/* The crossfade between two works: the picture and its label go together, so
   the label never belongs to the picture before it. */
.wall-frame, .wall-address {
  transition: opacity 800ms ease;
}

.wall-fading .wall-frame,
.wall-fading + .wall-address { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  .wall-frame, .wall-address { transition: none; }
}
