/* The Ming Young Museum of Art
   Designed for large tap targets and comfortable reading. */

:root {
  --ink: #33281d;
  --ink-soft: #6d5c4c;
  --cream: #fffaf0;
  --brass: #c08f45;
  --brass-dark: #8c6239;
  --shadow: 0 6px 22px rgba(58, 44, 31, .24);
  --radius: 18px;
  --ui: 'Iowan Old Style', 'Palatino Linotype', Palatino, 'Georgia', serif;
  /* kept for anything that wants the platform's own UI face; the museum's
     own functional type is --sign below */
  --sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  /* Signage. The big galleries all split their type the same way — a serif for
     the names of things, a grotesque for everything functional: Met Serif and
     Met Sans, Empirica and Mallory at the National Gallery of Art, MoMA Sans
     on every label and sign in the building. The customs are all out of the
     Helvetica line, so that is what this asks for first. */
  --sign: 'Helvetica Neue', Helvetica, 'Segoe UI', Roboto, Arial, sans-serif;
  /* Reading prose — the notes under a painting, the small print on a card.
     This was being ASKED FOR in three places and never defined, so `var(--body)`
     resolved to nothing and the text quietly inherited the serif from `body`.
     It looked right, which is why nobody noticed. Defined here as exactly what
     it was already resolving to, so the declaration now says what it does and
     nothing on screen moves. */
  --body: 'Iowan Old Style', 'Palatino Linotype', Palatino, 'Georgia', serif;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

/* Every field the museum has is at least 16px, and this is not a taste.
 *
 * Safari on iOS zooms the whole page in when you focus a field whose text is
 * under 16px, and it does not zoom back out when you are done. What is left is
 * a museum you can pan around: the top bar sitting off the top of the screen,
 * and the page's own dark background showing down the right-hand side and
 * along the bottom where the fixed canvas has run out. It looks exactly like
 * the drawing broke, and it is a font size.
 *
 * 16px is the threshold Safari uses, so this is the whole fix — and it is
 * written once, here, rather than on each field, so a field added later cannot
 * bring the bug back with it. `max()` keeps anything already larger. */
input, textarea, select { font-size: max(16px, 1em); }

/* The browser's own rule for [hidden] is display:none at the lowest possible
   specificity, so any class that sets display beats it — .btn is inline-flex,
   and a hidden button sat there in plain sight. Anything hidden is hidden. */
[hidden] { display: none !important; }

html, body {
  margin: 0; padding: 0; height: 100%;
  /* The page itself never scrolls. Everything a visitor sees is either the
     fixed canvas or a card that scrolls inside itself, so a scrolled document
     can only ever mean something has gone wrong — and what it looks like when
     it does is the top bar sliding off the screen and this background showing
     at the edges. There is nothing here to scroll to, so it does not. */
  overflow: hidden;
  background: #221a13;
  font-family: var(--ui);
  color: var(--ink);
  overscroll-behavior: none;
}

/* touch-action: none, because the hall is draggable. Left to itself the
   browser claims a moving finger for panning and rubber-banding the page —
   which has nothing to scroll anyway — and the drag never reaches the
   canvas. The cards on top are ordinary DOM and still scroll normally. */
#stage {
  position: fixed; inset: 0; display: block;
  touch-action: none;
  -webkit-user-select: none; user-select: none;
  -webkit-tap-highlight-color: transparent;
}

/* ---------- Top bar ---------- */
#topbar {
  position: fixed; top: 0; left: 0; right: 0;
  display: flex; align-items: center; gap: 7px;
  padding: 10px 10px;
  padding-top: max(10px, env(safe-area-inset-top));
  pointer-events: none;
  z-index: 20;
}
#topbar > * { pointer-events: auto; }

.btn {
  font-family: var(--ui);
  font-size: 17px; font-weight: 600;
  color: var(--ink);
  background: var(--cream);
  border: 2px solid rgba(140, 98, 57, .35);
  border-radius: 999px;
  padding: 0 20px;
  min-height: 52px; min-width: 52px;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  box-shadow: var(--shadow);
  cursor: pointer;
  transition: transform .12s ease, background .12s ease;
}
.btn:active { transform: scale(.96); background: #f5e9d2; }
.btn.icon { padding: 0; font-size: 22px; }
/* The bar carries four buttons and a room name, and on a 390-wide phone the
   name was losing: The Kids' Corner arrived as "The Kids' Cor…". The buttons
   are what a thumb aims at, so their height is untouchable — but the air
   either side of the words on them is not, and taking it back gives the name
   about forty pixels, which is the difference between the longest room name
   fitting and not. */
#topbar .btn { padding: 0 14px; }

/* The bar is a row of fixed things around one elastic thing. The buttons are
   sized by what is written on them and must never be squeezed narrower — on a
   phone that is what folded 中文 into a column of two characters — so only the
   label gives, and when it runs out of room it sets an ellipsis rather than
   wrapping down over the buttons. */
#topbar > .btn { flex: 0 0 auto; }

/* On a narrow phone the floor name is the half that gets cut — see
   setRoomLabel(). It goes rather than being sliced. */
@media (max-width: 460px) { #roomlabel em { display: none; } }

#roomlabel {
  flex: 1 1 auto; min-width: 0;
  text-align: center;
  font-size: 18px; font-weight: 600;
  color: var(--cream);
  text-shadow: 0 2px 8px rgba(0,0,0,.6);
  line-height: 1.25;
  pointer-events: none;
}
/* Two lines rather than an ellipsis.
   The bar is four buttons and a name, and on a narrow phone the name lost:
   Portraits of Women arrived as "Portraits of W…", which is a room nobody can
   look up. The buttons are what a thumb aims at so their width is not
   negotiable — but the bar is as tall as a button whatever is written in it,
   and two lines of the name plus the floor still fit inside that height. So
   the name wraps into the space that was already there. */
#roomlabel b {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  font-weight: 600; line-height: 1.12;
  overflow: hidden; overflow-wrap: break-word;
}
/* the room's name is a name, so it keeps the serif; the floor it is on is
   wayfinding, so it gets the signage grotesque, tracked out and small */
#roomlabel small {
  display: block; margin-top: 1px;
  font-family: var(--sign);
  font-size: 12px; letter-spacing: .09em; text-transform: uppercase;
  opacity: .72; font-weight: 500;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Han characters hold far more detail per glyph than Latin ones, so the same
   nominal size reads comfortably in English and as a smudge in Chinese. Every
   bilingual interface ends up doing this. */
#roomlabel i { font-style: normal; font-size: 1.16em; }
#roomlabel small i { font-size: 1.22em; letter-spacing: .02em; }
#roomlabel small em { font-style: normal; }

@media (max-width: 460px) {
  #roomlabel { font-size: 16px; }
  #roomlabel small { font-size: 11px; letter-spacing: .06em; }
}

/* Narrower still — an SE, a mini. Four buttons and a room name is a lot to ask
   of 360 points, so the buttons give back the air either side of their words
   and the name comes down another point and a half. Below this the two-line
   clamp takes over and sets an ellipsis, which is where it belongs: at the
   very end of what can be done, not as the first answer. */
@media (max-width: 405px) {
  #topbar { gap: 5px; padding-left: 8px; padding-right: 8px; }
  #topbar .btn { padding: 0 11px; }
  #roomlabel { font-size: 14px; }
}

/* The room-sound switch — currently not in the page. The sound is parked until
   there is better music for it, and this is kept whole for when it comes back.
   A filled ring when the room is audible, a hollow one when it is not — the
   same button either way, so nobody has to work out which of two icons means
   what. */
#btn-sound {
  position: relative;
  font-size: 20px; line-height: 1;
  min-width: 44px; padding-left: 0; padding-right: 0;
}
#btn-sound.off { color: rgba(74,56,38,.4); }
/* The switch always shows the other language — what you would get by pressing
   it — so it is a word, not an icon, and it is narrow. */
.btn.lang {
  font-family: var(--sign);
  font-size: 15px; font-weight: 600; letter-spacing: .04em;
  min-width: 56px; padding: 0 12px;
}
.btn.quiet.lang-door {
  display: inline-flex; margin: 0 auto 18px;
  font-family: var(--sign); font-size: 14px; letter-spacing: .04em;
  min-height: 38px; padding: 0 18px;
}

#btn-sound.off::after,
#btn-music.off::after {          /* struck through, the way a mute always is */
  content: ''; position: absolute; left: 22%; right: 22%; top: 50%;
  height: 2px; border-radius: 1px;
  background: rgba(74,56,38,.6);
  transform: rotate(-35deg);
}

/* The music button. A note, struck through when it is off — the same shape of
   control as the room-sound button above, so the top bar reads as one family
   rather than as two ideas about what a toggle looks like. */
#btn-music {
  position: relative;
  font-size: 19px; line-height: 1;
  min-width: 44px; padding-left: 0; padding-right: 0;
}
#btn-music.off { color: rgba(74,56,38,.4); }

/* ---------- Hint ---------- */
/* There is no visible hint element any more. The instruction is drawn into the
   scene, on a tail pointing at the object it names (see drawCallout in
   app.js), because a pill across the bottom of the screen sits exactly where a
   button sits and people tapped the words instead of the painting. This
   element stays in the page, off screen, purely so a screen reader announces
   what the visitor is standing in front of. */
#hint {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------- Overlays ---------- */
/* The backdrop is fixed and never scrolls — the card does. Blurring an element
   that also scrolls, with fixed children inside it, is what WebKit renders as
   a hard grey band across the page. */
/* The blur belongs to the shown state, not to the element. A full-screen
   fixed layer that asks for a backdrop-filter is asking the compositor to
   re-blur everything behind it whenever that changes — and behind these is a
   canvas repainting sixty times a second. At opacity 0 there is nothing to
   see for the cost, and there are four of them. `visibility` on top of that
   lets the compositor skip the layer altogether while it is away, and it is
   delayed by the length of the fade so the card can still be seen leaving. */
.overlay {
  position: fixed; inset: 0;
  background: rgba(34, 26, 18, .78);
  z-index: 40;
  display: flex; align-items: center; justify-content: center;
  padding: 16px;
  opacity: 0; pointer-events: none;
  visibility: hidden;
  transition: opacity .28s ease, visibility 0s linear .28s;
  overflow: hidden;
}
.overlay.show {
  opacity: 1; pointer-events: auto;
  visibility: visible;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  transition: opacity .28s ease, visibility 0s;
}

/* `manipulation` means panning and pinching, and nothing else — which drops
   the double tap that would otherwise zoom the page in. The hall already
   refuses it (`touch-action: none` on the canvas), but the cards did not, and
   several things in here are DELIBERATELY tapped several times quickly: the
   foundation stone, the room name, the curator's two taps on an entry. A
   museum should not zoom itself in because somebody did what it asked. */
.card, .btn, .overlay { touch-action: manipulation; }

.card {
  --pad: 22px;
  /* the last button in a card wants clear air under it, not a hairline */
  --padb: 44px;
  background: var(--cream);
  border-radius: var(--radius);
  box-shadow: 0 20px 60px rgba(0,0,0,.5);
  max-width: 900px; width: 100%;
  max-height: 100%;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  padding: var(--pad);
  padding-bottom: var(--padb);
  transform: translateY(14px); transition: transform .28s ease;
}

/* A way out that is always on screen — reaching the bottom of a long card
   just to close it is not a way out. */
.overlay-x {
  position: fixed;
  top: max(10px, env(safe-area-inset-top));
  right: 12px;
  z-index: 50;
  display: none;
  font-size: 20px;
}
body.overlay-open .overlay-x { display: inline-flex; }
/* A card covers the top bar, so the switch is repeated up here beside the way
   out — the whole point of it is that it is one tap from wherever you are. */
.overlay-lang { right: 74px; min-height: 52px; }
.overlay.show .card { transform: none; }

/* ---------- Artwork viewer ---------- */
#viewer .card { max-width: 1000px; }

.art-wrap { display: flex; flex-direction: column; gap: 22px; }
@media (min-width: 900px) {
  .art-wrap { flex-direction: row; align-items: flex-start; }
  .art-wrap.paired { flex-wrap: wrap; }
  /* A painting with nothing but a label — no award, no note from Ming, no
     story — was getting the same two-column card as one with a thousand words
     beside it, which on a laptop is a picture on the left and a title floating
     in three hundred pixels of empty cream. A short label goes UNDER the
     painting, centred, which is where a short label goes in every one of these
     buildings, and the card comes in to meet it. */
  .art-wrap.plain-label { flex-direction: column; align-items: center; }
  .art-wrap.plain-label .art-info {
    flex: 0 0 auto; text-align: center; max-width: 40rem; padding-top: 0;
  }
  #viewer .card:has(.art-wrap.plain-label) { max-width: 660px; }
}

.art-figure { flex: 1 1 auto; min-width: 0; margin: 0; }

/* THE PAINTING AND THE PHOTOGRAPH, SIDE BY SIDE — see renderArt(). The point
   of that button is holding the two up against each other, and stacked they
   could never both be on the screen at once. Two columns at every width,
   including a phone, where half a card each is small but is a comparison; both
   are still a tap away from the full-screen view. The moulding comes in with
   them: a clamp(17px, 3.6vw, 32px) gilt frame around a 170px picture is more
   frame than painting. */
.art-pair {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 14px; align-items: start; flex: 1 1 auto; min-width: 0;
}
.art-pair .art-figure .frame { --fw: clamp(9px, 2.2vw, 18px); }
.art-pair figcaption { font-size: 13px; }
@media (min-width: 900px) { .art-pair { gap: 20px; } }

/* A real gilded moulding: a carved bevel lit from above, a shadowed cove, a
   linen liner, and a dark fillet where the canvas begins. Built from stacked
   backgrounds and rings so it scales with whatever painting sits inside. */
.art-figure .frame {
  --fw: clamp(17px, 3.6vw, 32px);
  position: relative;
  width: fit-content; max-width: 100%;
  margin: 0 auto;
  padding: var(--fw);
  border-radius: 3px;
  line-height: 0;
  /* Four separate rails, each with its own bevel, so the moulding turns the
     corner the way a carved one does instead of reading as a flat wash. */
  background:
    repeating-linear-gradient(48deg,
      rgba(255,255,255,.14) 0 1px, rgba(92,63,20,.06) 1px 2px, transparent 2px 6px),
    /* top rail: outer edge in shade, inner edge catching the light */
    linear-gradient(180deg, #d8ad57 0%, #f2dda6 46%, #fbeec5 100%),
    /* bottom rail: darkest of the four */
    linear-gradient(0deg, #6d4d18 0%, #97701f 46%, #c39544 100%),
    linear-gradient(90deg, #b98c3c 0%, #e8cb8c 56%, #f4e2b0 100%),
    linear-gradient(270deg, #8d6320 0%, #b98c3c 56%, #dcb768 100%);
  background-repeat: no-repeat;
  background-size:
    auto,
    100% var(--fw),
    100% var(--fw),
    var(--fw) 100%,
    var(--fw) 100%;
  background-position:
    0 0,
    top, bottom, left, right;
  box-shadow:
    inset 0 0 0 1.5px #5b3f14,
    inset 0 0 22px rgba(92,63,20,.16),
    0 2px 0 rgba(255,255,255,.14),
    0 18px 44px rgba(20,12,4,.45),
    0 5px 14px rgba(20,12,4,.3);
}

/* corner ornaments, one gilt rosette per corner */
.art-figure .frame::before {
  content: ''; position: absolute; inset: 0;
  pointer-events: none;
  border-radius: 3px;
  background-repeat: no-repeat;
  background-size: clamp(18px, 3.6vw, 34px) clamp(18px, 3.6vw, 34px);
  background-position: top left, top right, bottom left, bottom right;
  background-image:
    radial-gradient(circle at 38% 38%, #fdf3d2 0 12%, #d3a445 42%, #8b6320 62%, transparent 66%),
    radial-gradient(circle at 62% 38%, #fdf3d2 0 12%, #d3a445 42%, #8b6320 62%, transparent 66%),
    radial-gradient(circle at 38% 62%, #fdf3d2 0 12%, #d3a445 42%, #8b6320 62%, transparent 66%),
    radial-gradient(circle at 62% 62%, #fdf3d2 0 12%, #d3a445 42%, #8b6320 62%, transparent 66%);
  opacity: .85;
}

.art-figure img {
  display: block;
  position: relative;
  max-width: 100%; max-height: 58vh;
  width: auto; height: auto;
  /* outward from the canvas: fillet, cove shadow, linen liner, cove again */
  box-shadow:
    0 0 0 2px #4a3311,
    0 0 0 3.5px #c9a15c,
    0 0 0 13px #ece2cb,
    0 0 0 14px rgba(92,63,20,.5),
    0 0 0 18px rgba(74,50,18,.6),
    0 0 18px 17px rgba(30,20,8,.35);
  margin: 7px;
}

/* the reference photograph gets a plain conservation mount, not a gilt frame */
.art-figure .frame.plain {
  padding: clamp(10px, 2vw, 16px);
  background: linear-gradient(160deg, #f3ead6, #ddd0b6);
  box-shadow:
    inset 0 0 0 1px rgba(92,63,20,.35),
    0 12px 30px rgba(20,12,4,.34);
}
.art-figure .frame.plain::before { content: none; }
.art-figure .frame.plain img {
  box-shadow: 0 0 0 1px rgba(92,63,20,.4), inset 0 0 20px rgba(0,0,0,.3);
  margin: 0;
}
/* An exhibit in The Doctor: a walnut moulding round a cut card mount.
   A painting is hung edge to frame because the paint goes to the edge of the
   canvas. A photograph is windowed in a mount with an inch of card round it,
   and that inch is most of what says "this is a document". */
.art-figure .frame.mount {
  padding: clamp(11px, 2.4vw, 18px);
  border-radius: 2px;
  background: linear-gradient(150deg, #8a5f38 0%, #4b3019 52%, #6a4526 100%);
  box-shadow:
    inset 0 0 0 1.5px #2c1c0f,
    inset 0 0 0 3px rgba(203, 163, 98, .30),
    0 14px 34px rgba(20, 12, 4, .42),
    0 4px 12px rgba(20, 12, 4, .28);
}
.art-figure .frame.mount::before { content: none; }
.art-figure .frame.mount img {
  --mt: clamp(14px, 3vw, 26px);
  /* the mount is drawn with margin + spread, so it has to come off the width
     as well or a full-width picture pushes its own mount off the card */
  max-width: calc(100% - var(--mt) * 2);
  box-shadow:
    0 0 0 var(--mt) #efe8d8,
    0 0 0 calc(var(--mt) + 1px) rgba(120, 100, 66, .5),
    inset 0 0 22px rgba(30, 20, 8, .16);
  margin: var(--mt);
}

/* The badge sits on the picture, not beside it. An instruction printed
   underneath would be read as a button — that lesson is already written on
   the hint labels — whereas a magnifier resting in the corner of the canvas
   belongs to the canvas, and the whole picture is the tap target. */
.zoom-badge {
  position: absolute;
  right: calc(var(--fw) + 9px); bottom: calc(var(--fw) + 9px);
  width: 46px; height: 46px; border-radius: 50%;
  display: grid; place-items: center;
  /* It was a dark blob in the corner of the canvas, which on a dark painting
     is nothing at all — and this is the way in to the best thing the museum
     does with a picture. Cream with a brass ring is what every other control
     in the building looks like, so it reads as something somebody put there
     rather than as a shadow. */
  color: #3a2a18;
  background: rgba(253, 246, 233, .93);
  box-shadow: 0 2px 14px rgba(0,0,0,.45), inset 0 0 0 2px rgba(160, 118, 44, .75);
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
  pointer-events: none;
}
.zoom-badge svg {
  width: 23px; height: 23px;
  fill: none; stroke: currentColor; stroke-width: 2.1;
  stroke-linecap: round; stroke-linejoin: round;
}
.art-figure .frame { cursor: zoom-in; }

/* ---------- Looking closer ---------- */
/* Its own layer above everything, on a ground dark enough that the painting
   is the only thing in the room. touch-action: none because both fingers are
   spoken for here — the browser must not take one for panning a page that
   cannot pan. */
.zoomer {
  position: fixed; inset: 0; z-index: 70;
  background: #14100a;
  opacity: 0; pointer-events: none;
  visibility: hidden;
  transition: opacity .24s ease, visibility 0s linear .24s;
  overflow: hidden;
  touch-action: none;
  -webkit-user-select: none; user-select: none;
  -webkit-tap-highlight-color: transparent;
}
.zoomer.show {
  opacity: 1; pointer-events: auto; visibility: visible;
  transition: opacity .24s ease, visibility 0s;
}
#zoom-img {
  position: absolute; top: 0; left: 0;
  transform-origin: 0 0;
  max-width: none; max-height: none;
  -webkit-user-drag: none;
}
/* promoted only while it is the thing being dragged about */
.zoomer.show #zoom-img { will-change: transform; }
/* The foot of the zoom view. Both children sit in here rather than pinning
   themselves to the bottom, because the caption is one line on a desk and
   three on a phone, and a tip that has to be told the caption's height is a
   tip that ends up sitting on top of it. */
.zoom-foot {
  position: absolute; left: 0; right: 0;
  bottom: calc(18px + env(safe-area-inset-bottom));
  /* Caption first, so the thing that stays sits nearest the picture and the
     tip that fades sits under it. It was the other way round, and Ming — whose
     dog it is — nearly missed his own words. */
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  padding: 0 16px;
  pointer-events: none;
}
/* A caption you can read, rather than one only a screen reader ever saw. All
   four of the photographs pinned up in the studio have carried one since they
   went up; none of them has ever been shown. */
/* Set to be read, not to be found. Ming on the first version: "Make lettering
   bigger for Agogo's contribution to arts. I almost missed it." */
.zoom-note {
  margin: 0; padding: 13px 20px;
  max-width: 30em;
  border-radius: 14px;
  background: rgba(20, 14, 8, .86);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.16);
  color: #fbf3e4;
  font-family: var(--sign); font-size: 18px; line-height: 1.5;
  text-align: center;
}
.zoom-note:empty { display: none; }
.zoom-tip {
  margin: 0; padding: 11px 18px;
  border-radius: 999px;
  background: rgba(20, 14, 8, .74);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.12);
  color: #f1e6d2;
  font-family: var(--sign); font-size: 15px; letter-spacing: .01em;
  white-space: nowrap;
  pointer-events: none;
  transition: opacity .6s ease;
}
.zoom-tip.gone { opacity: 0; }
.zoom-x {
  position: absolute;
  top: max(10px, env(safe-area-inset-top)); right: 12px;
  font-size: 20px;
}

/* An unfinished canvas has no frame — it has a stretcher. Bare linen turned
   over the edge, the shadow of a thing standing on a ledge, and none of the
   gilding, because gilding is what happens to a painting after it is done. */
.art-figure .frame.raw {
  padding: clamp(9px, 2vw, 15px);
  background: linear-gradient(168deg, #ece0c4 0%, #ddcda8 55%, #cdbb95 100%);
  box-shadow:
    inset 0 0 0 1px rgba(120, 92, 52, .45),
    0 14px 34px rgba(20, 12, 4, .34);
}
.art-figure .frame.raw::before { content: none; }
.art-figure .frame.raw img {
  box-shadow: 0 0 0 1px rgba(92, 63, 20, .38), 0 1px 6px rgba(20,12,4,.2);
}

.art-figure figcaption {
  margin-top: 12px; font-size: 14px; color: var(--ink-soft); text-align: center;
  font-family: var(--sign);
}
/* And whose photograph it is, on its own line under that.
   It was set at 12.5px, under the caption's 14 — the reflex that a credit is
   small print. Alex asked for it larger and he is right: the caption is a
   label the museum wrote about itself, and this is somebody's name, on the
   terms his photograph is here at all. So it is the bigger of the two now. */
.ref-by {
  display: block; margin-top: 6px;
  font-size: 15.5px; line-height: 1.5; opacity: .95;
  max-width: 34em; margin-left: auto; margin-right: auto;
}


.art-info { flex: 0 0 auto; }
@media (min-width: 900px) { .art-info { flex: 0 0 330px; padding-top: 4px; } }

.art-title { font-size: 27px; line-height: 1.2; margin: 0 0 2px; }
.art-title-zh { font-size: 20px; color: var(--ink-soft); margin: 0 0 14px; font-weight: 400; }
/* A wall label: the title above in the serif, and the medium, the size and
   the date below it in the signage grotesque — which is how every label in
   every one of those buildings is set. */
.art-meta {
  font-family: var(--sign); font-size: 15.5px; letter-spacing: .01em;
  color: var(--ink-soft); line-height: 1.55; margin-bottom: 14px;
}
.art-note { font-size: 17px; line-height: 1.6; margin: 0 0 16px; }
/* The two figures at the top of the restroom notice — the same pictograms
   that are on the plate over the door, in the museum's own ink rather than in
   the platform's blue emoji. */
.loo-signs { display: block; height: 42px; width: auto; margin: 2px 0 12px;
             color: var(--ink-soft); }

/* Chéry's pineapple, on the card that explains why there is a pineapple to
   carry. No border here: the photograph is of a framed painting and already
   has a frame in it, and the museum's own cream one around that would read as
   a mat nobody cut. It keeps the shadow, so it sits on the card like an object
   rather than a picture printed into it. Narrower than the drawing it replaced
   because it stands upright — 210 wide is 274 tall, which is about the height
   the landscape drawing took, and the card is the same length as it was. */
.chery-art {
  display: block; width: 100%; max-width: 210px; height: auto;
  margin: 4px auto 14px;
  border-radius: 3px;
  box-shadow: 0 4px 14px rgba(58,44,31,.22);
}

/* The award, given the room it deserves: a struck medal on a ribbon beside a
   gilt panel. Built out of layers rather than one gradient, because that is
   what makes metal look like metal — a conic sweep for the milled rim, a
   radial burst under the face, a rolled bevel, a specular hot spot up and to
   the left, and a sheen that travels across it. */
.award {
  position: relative; overflow: hidden;
  display: flex; align-items: center; gap: 18px;
  background:
    radial-gradient(120% 140% at 12% 0%, rgba(255,255,255,.55), transparent 55%),
    linear-gradient(160deg, #fdf1cf, #f0dba4 55%, #e3c688);
  border: 2px solid var(--brass);
  border-radius: 14px;
  padding: 16px 18px; margin: 0 0 18px;
  box-shadow: 0 6px 18px rgba(92,63,20,.22), inset 0 1px 0 rgba(255,255,255,.6);
}

.medal {
  --tail-w: 19px; --tail-h: 44px;
  flex: none; position: relative;
  width: 64px; height: 84px;
  filter: drop-shadow(0 4px 6px rgba(60,40,10,.45));
}

/* the ribbon: two tails splaying from a point, notched at the bottom, running
   down behind the medal */
.medal-ribbon { position: absolute; left: 50%; top: 0; width: 0; height: 0; }
.medal-ribbon::before,
.medal-ribbon::after {
  content: ''; position: absolute; top: 0;
  width: var(--tail-w); height: var(--tail-h);
  clip-path: polygon(0 0, 100% 0, 100% 82%, 50% 100%, 0 82%);
}
.medal-ribbon::before {
  right: -1px; transform-origin: 100% 0; transform: rotate(16deg);
  background: linear-gradient(96deg, #b0424a 0 40%, #7c2429 40% 62%, #98333a 62%);
}
.medal-ribbon::after {
  left: -1px; transform-origin: 0 0; transform: rotate(-16deg);
  background: linear-gradient(264deg, #b0424a 0 40%, #7c2429 40% 62%, #98333a 62%);
}

/* the medal itself */
.medal-disc {
  position: absolute; left: 50%; bottom: 0;
  width: 58px; height: 58px; margin-left: -29px;
  border-radius: 50%;
  background:
    /* the hot spot, up and to the left */
    radial-gradient(circle at 34% 30%, rgba(255,255,255,.85) 0 6%, rgba(255,255,255,0) 34%),
    /* the struck face, and the rolled bevel around it */
    radial-gradient(circle at 50% 50%,
      #fff4d2 0 26%, #e6c473 27% 42%, #b98d33 43% 47%, rgba(0,0,0,0) 48%),
    /* the burst under the face */
    repeating-conic-gradient(from 8deg at 50% 50%,
      #fff6d8 0deg 6deg, #b78c34 6deg 12deg),
    /* the milled rim */
    conic-gradient(from 210deg,
      #6f4d16, #d8ae54 12%, #fff2c8 22%, #c99a3c 34%, #7a561b 46%,
      #d8ae54 60%, #fff2c8 70%, #b98a30 82%, #6f4d16);
  box-shadow:
    inset 0 2px 3px rgba(255,255,255,.65),
    inset 0 -3px 6px rgba(80,52,10,.55);
}
.medal-disc::before {                    /* the star, struck into the face */
  content: '★'; position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 21px; line-height: 1; color: #6a4a12;
  text-shadow: 0 1px 0 rgba(255,247,214,.85), 0 -1px 1px rgba(60,40,8,.55);
}
.medal-disc::after {                     /* a sheen, travelling */
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  background: linear-gradient(58deg, transparent 34%, rgba(255,255,255,.75) 46%,
                              rgba(255,255,255,0) 58%);
  transform: translateX(-120%);
  animation: medal-sheen 5.5s ease-in-out 1.2s infinite;
}
@keyframes medal-sheen {
  0%, 62% { transform: translateX(-120%); }
  78%, 100% { transform: translateX(120%); }
}

.award-text { font-family: var(--sign); font-size: 16px; font-weight: 600; line-height: 1.45; }
.award-line { display: block; }
.award-line + .award-line { margin-top: 7px; padding-top: 7px; border-top: 1px solid rgba(138,99,32,.28); }
/* On an ordinary award this line is the generic word "Award" and the prize
   itself — "Third Place", "Honorable Mention" — is in the text below it, so
   this stays the small label it looks like. Best in Show is the exception, and
   it is handled as one further down. */
.award-tier {
  display: block;
  font-size: 12px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  color: #8a6320; margin-bottom: 5px;
}

/* Best in Show: heavier, and it says so */
.award.top {
  border-color: #a8802f; border-width: 3px;
  background:
    radial-gradient(120% 140% at 12% 0%, rgba(255,255,255,.6), transparent 55%),
    linear-gradient(160deg, #fff6da, #f3dda6 55%, #e2c176);
  box-shadow: 0 10px 26px rgba(92,63,20,.3), inset 0 1px 0 rgba(255,255,255,.7);
}
/* a slow bloom behind the medal, so the top prize glows a little */
.award.top::before {
  content: ''; position: absolute; left: 34px; top: 50%;
  width: 170px; height: 170px; margin: -85px 0 0 -85px;
  border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle, rgba(255,226,150,.75), rgba(255,226,150,0) 62%);
}
.award.top .medal { --tail-w: 25px; --tail-h: 56px; width: 84px; height: 110px; }
.award.top .medal-disc { width: 76px; height: 76px; margin-left: -38px; }
.award.top .medal-disc::before { font-size: 28px; }
/* Where the tier IS the prize, it is set like the prize.
 *
 * Best in Show was a twelve-pixel eyebrow over an eighteen-pixel exhibition
 * name, which had the hierarchy exactly the wrong way round: what this card is
 * about is that he WON, and the name of the show is where he won it. Tracking
 * comes down as the size goes up — letterspacing that reads as engraving at
 * twelve pixels reads as a gap at twenty. */
.award.top .award-text { font-size: 16px; font-weight: 500; }
.award.top .award-tier {
  color: #6d4a0c; font-size: 20px; letter-spacing: .09em; margin-bottom: 7px;
}

@media (prefers-reduced-motion: reduce) { .medal-disc::after { animation: none; } }




.art-actions { display: flex; flex-wrap: wrap; gap: 10px; position: relative; z-index: 1; }

/* ---------- "there is more down there" ---------- */
/* On a phone the painting fills the screen and the title, the award and the
   note sit below the fold with nothing to say so. This is that something. */
#scrollcue {
  position: fixed; left: 50%;
  bottom: max(20px, env(safe-area-inset-bottom));
  transform: translateX(-50%);
  display: none; align-items: center; gap: 9px;
  background: rgba(58, 44, 31, .92);
  color: var(--cream);
  font-family: var(--sign); font-size: 14px; font-weight: 600;
  letter-spacing: .04em;
  padding: 10px 18px;
  border-radius: 999px;
  box-shadow: 0 8px 22px rgba(0,0,0,.45);
  z-index: 45;
  pointer-events: none;
  opacity: 0; transition: opacity .3s ease;
}
#scrollcue.on { display: flex; opacity: 1; }
#scrollcue b { font-size: 18px; line-height: 1; animation: nudge 1.5s ease-in-out infinite; }
@keyframes nudge {
  0%, 100% { transform: translateY(-2px); }
  50%      { transform: translateY(3px); }
}
@media (prefers-reduced-motion: reduce) { #scrollcue b { animation: none; } }

/* ---------- the calm museum ----------
 *
 * The canvas half of this is in app.js beside `calm`; this is the page around
 * it. Everything that MOVES stops — cards no longer rise into place, buttons no
 * longer squash under a thumb, the pressed crayon no longer jumps a tenth
 * larger. Everything that FADES is left alone: an opacity change is not motion,
 * it is the one way an interface can say "this is different now" without moving
 * anything, and taking it away as well would leave things blinking in and out
 * with nothing to soften them.
 *
 * `!important` is here for one reason: every rule it overrides is more specific
 * than a bare media block can be, and the alternative is restating a dozen
 * selectors and keeping them true. */
@media (prefers-reduced-motion: reduce) {
  .card { transform: none !important; }
  .btn:active, .room-btn:active, .fb-btn:active, .book-more:active {
    transform: none !important;
  }
  .pad-swatch[aria-pressed="true"] { transform: none !important; }
  .pad-sheet, .pad-sheet.flying { transform: none !important; }
  /* and nothing that has a transform in its transition keeps one. Named
     rather than starred: a blanket rule would also have taken `visibility`
     off .overlay, which is not motion and is what stops a card from being
     clickable a third of a second after it has faded out. */
  .btn, .card, .room-btn, .fb-btn, .pad-sheet, .pad-swatch, .art-figure .frame {
    transition-property: opacity, background-color, border-color, color,
                         box-shadow, outline-color !important;
  }
}

/* And a scrim inside the card, so long text visibly runs off the bottom. It is
   a real box in flow, so its margins move the card's own bottom edge: the
   negative top margin is what stops it adding 92px of height, but a negative
   BOTTOM margin pulled the card's edge up by the whole of its bottom padding
   and sat every last button flush against it. */
.overlay .card::after {
  content: ''; position: sticky; display: block;
  left: 0; right: 0; bottom: calc(var(--padb) * -1); height: 132px;
  margin: -132px calc(var(--pad) * -1) 0;
  /* The ramp is shaped around where the cue sits rather than run evenly over
     the whole height. It was 92px of even fade, and "More below" landed at
     about a third of the way up it — over text still at two thirds strength,
     so the pill chopped a line in half instead of floating in a fade. Dr Lin's
     sentence about da Vinci was being cut mid-word on the Venus card every
     time it opened. The cue's top edge is now around 55% of this, where the
     cream has already closed over. */
  background: linear-gradient(rgba(253,246,233,0) 0%,
                              rgba(253,246,233,.72) 40%,
                              rgba(253,246,233,.985) 62%,
                              rgba(253,246,233,.985) 100%);
  pointer-events: none;
  opacity: 0; transition: opacity .3s ease;
  z-index: 0;
}
.overlay.more .card::after { opacity: 1; }

/* The scrim is for text running off the bottom, and never for the buttons.
   Ninety-six per cent cream over Sign the book washes it out until it reads as
   a button that has been turned off — the opposite of what a primary action
   should say. The row of actions sits above it. */
.menu-foot { position: relative; z-index: 1; }

/* ---------- which button is the button ---------- */
/* Every card carries the word Close as well as the ✕ that is always on screen
   and the backdrop you can tap, and on a card that also has a real action —
   sign the book, pin it up, see the photograph Ming painted from — three ways
   out were competing with the one thing worth doing. So Close steps back to
   being a word where it has company, and keeps its weight where it is the only
   thing in the row, because there it IS the action. */
.btn.close-word:not(:only-child) {
  background: transparent;
  border-color: rgba(140, 98, 57, .26);
  color: var(--ink-soft);
  box-shadow: none;
}
.btn.close-word:not(:only-child):active { background: rgba(140, 98, 57, .09); }

/* ---------- where the keyboard is ---------- */
/* There was no focus style anywhere in this file, so somebody moving through
   the museum by keyboard was doing it blind: the buttons are custom-drawn and
   the browser's own ring is all but invisible on a cream pill with a shadow.
   Brass, because brass is how this building says "this one" everywhere else —
   the pressed crayon, the room you are standing in, a tile you have found. */
:focus-visible {
  outline: 3px solid var(--brass);
  outline-offset: 3px;
}
.btn:focus-visible, .room-btn:focus-visible, .fb-btn:focus-visible,
.pad-swatch:focus-visible, summary:focus-visible { outline-offset: 4px; }
input:focus-visible, textarea:focus-visible {
  outline-offset: 1px; border-color: var(--brass);
}

/* ---------- Rooms menu ---------- */
.menu-title { font-size: 25px; margin: 0 0 4px; }
.menu-sub { font-family: var(--sign); font-size: 15px; color: var(--ink-soft); margin: 0 0 18px; }
.room-list { display: grid; gap: 11px; }
.level-head {
  font-size: 15px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
  font-family: var(--sign); color: var(--ink-soft);
  margin: 8px 0 -2px; display: flex; align-items: center; gap: 10px;
}
.level-head:first-child { margin-top: 0; }
.level-head span { text-transform: none; letter-spacing: 0; opacity: .8; }
.level-head::after {
  content: ''; flex: 1; height: 1px;
  background: linear-gradient(90deg, rgba(140,98,57,.4), rgba(140,98,57,0));
}
.room-btn {
  display: flex; align-items: center; gap: 15px;
  width: 100%; text-align: left;
  background: #fff; border: 2px solid rgba(140,98,57,.3);
  border-radius: 14px; padding: 15px 17px;
  cursor: pointer; font-family: var(--ui); color: var(--ink);
  min-height: 68px;
  transition: transform .12s ease, border-color .12s ease;
}
.room-btn:active { transform: scale(.985); }
.room-btn[aria-current='true'] { border-color: var(--brass); background: #fdf3e0; }
.swatch {
  width: 46px; height: 46px; border-radius: 8px; flex: none;
  box-shadow: inset 0 0 0 2px rgba(160, 118, 44, .55), 0 1px 4px rgba(30, 20, 8, .28);
}
/* A picture of the room instead of a colour chip — see roomTile(). Framed the
   way everything in this building is framed, small enough that nine of them do
   not turn the menu into a contact sheet. */
.room-thumb {
  width: 46px; height: 46px; border-radius: 8px; flex: none;
  overflow: hidden; background: #efe4cd;
  box-shadow: inset 0 0 0 2px rgba(160, 118, 44, .55), 0 1px 4px rgba(30, 20, 8, .28);
}
.room-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.room-btn b { display: block; font-size: 19px; font-weight: 600; line-height: 1.25; }
.room-btn small { font-family: var(--sign); font-size: 14px; color: var(--ink-soft); }

/* ---------- Title screen ---------- */
/* The door screen used to be a card on a solid brown void, so "Come in" was a
   promise about nothing you could see. The hall is already being drawn behind
   it — the loop starts before the title comes down — so letting it through,
   dimmed and blurred, means the first thing anybody sees is that there is
   somewhere in there. Dark enough that the card still wins, and .overlay.show
   is already doing the blur. */
/* Nothing to do while the door is shut, and a row of half-visible buttons
   behind a title card reads as a page that has not finished loading. */
body:has(#title.show) #topbar { opacity: 0; }
#topbar { transition: opacity .3s ease; }

#title {
  background:
    radial-gradient(135% 100% at 50% 42%, rgba(24,18,12,.30), rgba(18,13,9,.86) 76%),
    rgba(24, 18, 12, .16);
  z-index: 60;
}
#title .card {
  max-width: 620px; text-align: center; padding: 40px 28px;
  background: linear-gradient(#fdf6e9, #f6e8cf);
}
#title h1 { font-size: clamp(30px, 7vw, 44px); margin: 0 0 6px; line-height: 1.12; }
#title .zh { font-size: 20px; color: var(--ink-soft); margin: 0 0 20px; }
#title p { font-size: 17px; line-height: 1.65; color: var(--ink-soft); margin: 0 auto 26px; max-width: 44ch; }
#title .btn { font-size: 20px; min-height: 62px; padding: 0 38px; background: var(--brass); color: #fff; border-color: var(--brass-dark); }
#title .btn:active { background: var(--brass-dark); }

/* ---------- The door ---------- */
/* It carried a dark enamel plate for a while — COMING SOON while the building
   was unfinished, then NOW OPEN when it was not — and a padlock with a number
   to type. All of it is gone. A museum that is open does not put up a sign
   saying so; it has a door, and this is the door. */
#closed { margin: 10px 0 24px; }

/* The way in. It was a padlock, and the museum was not open; the plate above
   now says NOW OPEN and this says Come in, which between them is the whole
   announcement. It is deliberately the biggest thing on the door. */
#title .btn.enter, .btn.enter {
  display: block; margin: 18px auto 0;
  font-family: var(--ui); font-size: 21px; font-weight: 600;
  min-height: 58px; padding: 0 40px;
  border-radius: 999px;
  color: #2a2018;
  background: linear-gradient(#e6c47f, #c9a25a 55%, #b08b45);
  border: 1px solid rgba(120, 88, 30, .5);
  box-shadow: 0 3px 0 rgba(120, 88, 30, .45), 0 8px 20px rgba(58, 44, 31, .24);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .12s ease, box-shadow .12s ease;
}
.btn.enter:active {
  transform: translateY(3px);
  box-shadow: 0 0 0 rgba(120, 88, 30, .45), 0 4px 12px rgba(58, 44, 31, .2);
}

#title .btn.quiet, .btn.quiet {
  font-size: 16px; min-height: 46px; padding: 0 22px;
  background: transparent; border-color: rgba(140, 98, 57, .3); color: var(--ink-soft);
  box-shadow: none;
}

/* The one button in a card that the card is FOR.
 *
 * A row of buttons that all look the same asks the visitor to read every one
 * of them before doing the obvious thing. This is the door's brass at the size
 * of an ordinary button, so "Sign the book" is plainly the offer and "Close"
 * is plainly the way out. Only ever one of these in a card; the moment there
 * are two, neither is primary. */
.btn.go {
  color: #2a2018;
  background: linear-gradient(#e6c47f, #c9a25a 55%, #b08b45);
  border-color: rgba(120, 88, 30, .5);
  box-shadow: 0 3px 0 rgba(120, 88, 30, .4), 0 7px 18px rgba(58, 44, 31, .22);
}
.btn.go:active {
  transform: translateY(3px);
  background: linear-gradient(#dfba6f, #c09650 55%, #a37f3c);
  box-shadow: 0 0 0 rgba(120, 88, 30, .4), 0 4px 11px rgba(58, 44, 31, .2);
}

/* ---------- Artist card ---------- */
.artist-photo {
  width: 100%; max-width: 300px; border-radius: 12px; display: block; margin: 0 auto 18px;
  box-shadow: var(--shadow);
}
.artist-text p { font-size: 17px; line-height: 1.65; margin: 0 0 13px; }
/* His teacher's school, in his own sentence. Brass rather than browser blue,
   and underlined at a distance so the words still read as his prose and not
   as a button somebody dropped into it. */
.artist-text a {
  color: var(--brass-dark);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  text-decoration-color: rgba(140, 98, 57, .55);
}

@media (max-width: 500px) {
  .card { --pad: 18px; --padb: 38px; }
  .art-title { font-size: 23px; }
  /* leave room for the title and the award under the painting */
  .art-figure img { max-height: 44vh; }
  .artist-photo { max-height: 34vh; width: auto; }
  .award { padding: 13px 14px; gap: 12px; }
  .medal { --tail-w: 16px; --tail-h: 38px; width: 54px; height: 72px; }
  .medal-disc { width: 50px; height: 50px; margin-left: -25px; }
  .award.top .medal { --tail-w: 21px; --tail-h: 46px; width: 68px; height: 90px; }
  .award.top .medal-disc { width: 62px; height: 62px; margin-left: -31px; }
}

/* ---------- The suggestion box ----------
   Two doors out of one card, because the first thing anybody writing has to
   decide is who they are writing to, and a single mailto makes them decide it
   in the subject line where nobody will. Each button is an <a href="mailto:">
   rather than a scripted click, so it behaves the way every other mail link on
   the phone behaves — long-press to copy the address included. */
.post-mark {
  font-size: 34px; line-height: 1;
  text-align: center; margin-bottom: 4px;
  color: var(--brass);
}
.fb-list { display: flex; flex-direction: column; gap: 10px; margin-top: 14px; }
.fb-btn {
  display: block; width: 100%; text-align: left; text-decoration: none;
  font: inherit; cursor: pointer;
  padding: 14px 18px;
  border: 2px solid rgba(140, 98, 57, .35);
  border-radius: 16px;
  background: var(--cream);
  color: var(--ink);
  transition: transform .12s ease, background .12s ease;
}
.fb-btn:active { transform: scale(.985); background: #f5e9d2; }
.fb-btn b { display: block; font-size: 17px; font-weight: 600; }
.fb-btn small {
  display: block; margin-top: 3px;
  font-family: var(--sign); font-size: 13px;
  color: rgba(74, 56, 38, .68);
}
.fb-addr {
  margin-top: 14px; text-align: center;
  font-family: var(--sign); font-size: 13.5px;
  color: rgba(74, 56, 38, .72);
}
.fb-addr a { color: var(--brass-dark); }

/* the two ways out of the Rooms menu, side by side and wrapping on a phone */
.menu-foot {
  margin-top: 16px;
  display: flex; flex-wrap: wrap; gap: 10px; justify-content: center;
}

/* ---------- The building record ----------
   A works list, not prose: the date once at the head of its group and the
   changes under it, so a day with six changes reads as a day rather than as
   six repetitions of the same date. */
.log { margin: 14px 0 0; text-align: left; }
.log dt {
  font-family: var(--sign);
  font-size: 12px; letter-spacing: .08em; text-transform: uppercase;
  color: rgba(74, 56, 38, .55);
  margin: 16px 0 6px;
  padding-bottom: 5px;
  border-bottom: 1px solid rgba(140, 98, 57, .22);
}
.log dt:first-child { margin-top: 0; }
.log dd {
  margin: 0 0 7px;
  font-size: 15.5px; line-height: 1.4;
  color: var(--ink);
  padding-left: 15px;
  position: relative;
}
.log dd::before {
  content: '';
  position: absolute; left: 2px; top: .62em;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--brass);
}

/* ------------------------------------------------- the Kids' Corner
   The pad is a sheet of paper on a table, so it is white, it has a shadow
   under it, and it is the only surface in the museum with nothing printed on
   it. `touch-action: none` matters more than it looks: without it a finger
   dragged across the canvas scrolls the card instead of drawing a line. */
.pad-card { max-width: 30rem; }
/* A PAD of paper, not a rectangle. Two more sheets underneath, each turned a
   degree or two, which is what a pad on a table looks like from above — and
   the only thing in the museum made of paper you are allowed to write on. The
   canvas itself is never rotated: a finger lands where the line goes because
   the element it is measured against is square to the screen. */
.pad-sheet {
  position: relative;
  width: 100%; max-width: 17rem;
  margin: .6rem auto .7rem;
  aspect-ratio: 3 / 4;
  transition: transform .42s cubic-bezier(.4, 0, .25, 1), opacity .42s ease;
}
/* Under the sheet, and out of the way of the finger: ::after comes after the
   canvas in tree order, so without a layer of its own it painted OVER the
   drawing and swallowed every pointerdown aimed at it. */
.pad-sheet::before, .pad-sheet::after {
  content: ''; position: absolute; inset: 0; z-index: 0;
  border-radius: 4px; background: #f6ecd9;
  box-shadow: 0 4px 12px rgba(30, 20, 8, .18);
  pointer-events: none;
}
.pad-sheet::before { transform: rotate(-1.7deg) translate(-4px, 3px); }
.pad-sheet::after  { transform: rotate(1.3deg) translate(4px, 5px); }
/* Off the pad and onto the wall. See pinMyDrawing(): the card it becomes opens
   as this finishes, so the drawing goes somewhere rather than blinking out. */
.pad-sheet.flying { transform: translateY(-38%) scale(.34) rotate(7deg); opacity: 0; }
@media (prefers-reduced-motion: reduce) {
  .pad-sheet { transition: opacity .2s ease; }
  .pad-sheet.flying { transform: none; }
}
.pad-cv {
  display: block; position: relative; z-index: 1;
  width: 100%; height: 100%;
  background: #fffcf3;
  border-radius: 4px;
  border: 1px solid rgba(120, 92, 52, .3);
  box-shadow: 0 8px 20px rgba(30, 20, 8, .24), 0 2px 5px rgba(30, 20, 8, .16);
  touch-action: none;
  cursor: crosshair;
}
.pad-colors {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: .45rem; margin: 0 0 .7rem;
}
.pad-swatch {
  width: 2rem; height: 2rem; border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, .8);
  box-shadow: 0 1px 4px rgba(30, 20, 8, .3);
  padding: 0; cursor: pointer;
}
.pad-swatch[aria-pressed="true"] {
  outline: 2.5px solid var(--brass); outline-offset: 2px;
  transform: scale(1.12);
}
/* Three nibs and a rubber. Each nib is the dot it makes, at the size it makes
   it, because a child picking a crayon is picking a thickness — and "14px"
   would be no use to anybody at that table. */
.pad-tools {
  display: flex; justify-content: center; align-items: center;
  gap: .5rem; margin: 0 0 .75rem;
}
.pad-nib {
  width: 2.4rem; height: 2.4rem; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--cream); cursor: pointer; padding: 0;
  border: 2px solid rgba(140, 98, 57, .32);
  box-shadow: 0 1px 4px rgba(30, 20, 8, .2);
  color: var(--ink);
}
.pad-nib i { display: block; border-radius: 50%; background: currentColor; }
.pad-nib svg { width: 21px; height: 21px; fill: none; stroke: currentColor;
               stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.pad-nib[aria-pressed="true"] {
  border-color: var(--brass); background: #fdf3e0;
  box-shadow: 0 0 0 3px rgba(198, 154, 62, .35), 0 1px 4px rgba(30, 20, 8, .2);
}
.pad-rub { margin-left: .35rem; }

.pad-row { display: flex; justify-content: center; margin-bottom: .3rem; }
.pad-name { display: flex; align-items: center; gap: .5rem; font-size: .9rem; }
.pad-name input {
  font: inherit;
  font-size: max(16px, 1em);   /* never smaller — see the rule at the top */
  padding: .3rem .5rem; width: 9rem;
  border: 1px solid rgba(120, 92, 52, .4); border-radius: 4px;
  background: #fffdf7;
}
.pad-foot { flex-wrap: wrap; gap: .4rem; }

.kid-card { max-width: 32rem; }
.kid-img {
  display: block; width: 100%; height: auto;
  max-height: 68vh; object-fit: contain;
  border-radius: 3px; background: #fffdf7;
  box-shadow: 0 6px 18px rgba(30, 20, 8, .25);
}
.kid-by { margin: .7rem 0 .2rem; font-size: .95rem; opacity: .85; }

/* ------------------------------------------------ the visitors' book
   Every entry is somebody's afternoon, so each one is a card rather than a row
   in a list: a monogram in a colour that belongs to that name, the name in the
   display face the paintings' titles are set in, and the message itself given
   the room to be read. Entries that arrived since the last visit are tinted
   and carry the brass chip.

   This was a comment thread before — names and dates and dashed rules — and a
   comment thread is a thing you scan. A visitors' book is a thing you read.
*/
.book-card { max-width: 32rem; }
/* No height and no scrollbar of its own: the card is the only thing that
   scrolls, and what is below the newest few entries is a button that says so.
   A scroller inside a scroller hides things without looking as though it is
   hiding them. */
/* A BOOK, rather than a list of comments.
 *
 * It was a stack of rounded cards with round monograms — a comment thread,
 * which is what every other website's version of this is, and the least
 * museum-like screen in the museum. It is a page now: warm paper, a red margin
 * rule ruled down the left the way a ledger is, a soft gutter shadow where the
 * page turns into the spine, and entries written one under another and divided
 * by a hairline instead of boxed up.
 *
 * No ruled writing lines, deliberately. Entries are different lengths and the
 * monogram sets the row height, so the rules would never land under the words
 * — and a ruled page whose lines the writing ignores looks more wrong than a
 * plain one. */
.book-list {
  margin: .5rem 0 1.1rem; text-align: left;
  padding: .9rem 1rem .5rem 1.35rem;
  background:
    linear-gradient(rgba(176, 70, 58, .45), rgba(176, 70, 58, .45))
      1.05rem 0 / 1px 100% no-repeat,
    linear-gradient(#fffcf1, #fdf7e6);
  border-radius: 3px 12px 12px 3px;
  box-shadow:
    inset 9px 0 14px -11px rgba(60, 40, 16, .55),
    inset 0 0 0 1px rgba(140, 98, 57, .2),
    0 2px 9px rgba(60, 40, 16, .13);
}
.book-more {
  display: block; width: 100%;
  margin: .3rem 0 .2rem; padding: .75rem 1rem;
  font-family: var(--sign); font-size: .88rem; font-weight: 700;
  letter-spacing: .02em;
  color: var(--brass-dark);
  background: rgba(226, 196, 124, .16);
  border: 1px solid rgba(140, 110, 60, .45);
  border-radius: 999px;
  cursor: pointer;
}
.book-more:active { background: rgba(226, 196, 124, .3); }
/* An entry ON the page, not a card floating over it. The hairline underneath
   is where one signature ends and the next begins, which is all a guest book
   has ever needed. */
.book-entry {
  position: relative; overflow: hidden;
  display: grid;
  grid-template-columns: 2.4rem minmax(0, 1fr);
  column-gap: .8rem;
  padding: .7rem .2rem .8rem 0;
  border-bottom: 1px solid rgba(140, 98, 57, .18);
}
.book-entry:last-child { border-bottom: none; }
/* Since you were last in. A wash across the page and a brass rule beside it,
   rather than a card lifting off it. */
.book-entry.fresh {
  background: linear-gradient(90deg, rgba(226, 196, 124, .26), rgba(226, 196, 124, 0) 82%);
  box-shadow: inset 3px 0 0 var(--brass);
  border-radius: 0 6px 6px 0;
  padding-left: .55rem; margin-left: -.55rem;
}

/* The monogram. Its colour comes from the name, so the same person is the
   same colour every time and a page of entries has some variety in it. */
.book-mono {
  grid-row: 1 / span 3;
  width: 2.4rem; height: 2.4rem; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--ui); font-size: 1.15rem; font-weight: 700; line-height: 1;
  color: #fdf6e6;
  background: var(--mono, #8c6239);
  box-shadow: inset 0 -2px 5px rgba(0, 0, 0, .20), 0 1px 2px rgba(60, 40, 16, .18);
}
.book-t0 { --mono: #8c6239; }
.book-t1 { --mono: #2f8390; }
.book-t2 { --mono: #7a4fa8; }
.book-t3 { --mono: #4a8f4a; }
.book-t4 { --mono: #b0563a; }
.book-t5 { --mono: #3d6ea8; }

.book-head {
  grid-column: 2; display: flex; align-items: baseline;
  flex-wrap: wrap; gap: .1rem .5rem; min-height: 1.3rem;
}
.book-who { font-family: var(--ui); font-weight: 700; font-size: 1.02rem; }
.book-mine { font-family: var(--sign); font-size: .72rem; opacity: .55; }
/* What they wrote, in the museum's serif and slanted. Nobody signs a visitors'
   book in a user-interface font, and a hand is the one thing a web page cannot
   have without dragging a whole typeface down the wire for it — this is as
   close as the museum can get for nothing. */
.book-said {
  grid-column: 2;
  margin: .25rem 0 0; white-space: pre-wrap; overflow-wrap: anywhere;
  font-family: var(--ui);
  font-style: italic;
  font-size: 1.04rem; line-height: 1.55; color: rgba(44, 33, 20, .95);
}
.book-chip {
  font-family: var(--sign);
  display: inline-block; padding: .1rem .45rem;
  font-size: .62rem; letter-spacing: .1em; text-transform: uppercase;
  border-radius: 999px; background: var(--brass); color: #2a2018; font-weight: 700;
}
/* Not shown to anybody until the curator gesture asks for it. */
.book-x {
  grid-column: 2; justify-self: start;
  margin-top: .5rem; font: inherit; font-size: .72rem;
  padding: .2rem .6rem; border-radius: 999px; cursor: pointer;
  border: 1px solid rgba(140, 98, 57, .4);
  background: transparent; color: rgba(74, 56, 38, .7);
}
.book-x.sure { background: #8e3f3f; border-color: #8e3f3f; color: #fdf6e6; }
.book-none { opacity: .7; text-align: center; padding: 1.2rem 0; }
.book-form { text-align: left; }
.book-field { display: block; margin-bottom: .55rem; font-size: .86rem; }
.book-field span { display: block; margin-bottom: .2rem; opacity: .8; }
.book-field input, .book-field textarea {
  font: inherit;
  font-size: max(16px, 1em);   /* never smaller — see the rule at the top */
  width: 100%; padding: .4rem .55rem;
  border: 1px solid rgba(120, 92, 52, .4); border-radius: 4px;
  background: #fffdf7; resize: vertical;
}
.book-note { font-size: .76rem; opacity: .6; margin: .1rem 0 .6rem; }

/* ------------------------------------------- the story behind a painting
   A disclosure inside an art card. It used to be a bare line with a small
   triangle, which nobody reads as "there is more here" — it looked like the
   end of the label. It is a button now: a bordered pill in the museum's brass,
   with a word that says what tapping it does. */
.art-story {
  margin-top: .9rem;
  padding-top: .8rem;
  border-top: 1px solid rgba(120, 92, 52, .25);
  text-align: left;
}
.art-story > summary {
  cursor: pointer;
  list-style: none;
  display: flex; align-items: center; gap: .5rem;
  padding: .5rem .85rem;
  border: 1px solid rgba(140, 110, 60, .55);
  border-radius: 999px;
  background: rgba(226, 196, 124, .16);
  font-size: .88rem; font-weight: 700;
}
.art-story > summary::-webkit-details-marker { display: none; }
.art-story > summary::after {
  content: '▾';
  margin-left: auto; color: var(--brass); font-size: .8rem;
  transition: transform .15s ease;
}
.art-story[open] > summary::after { transform: rotate(180deg); }
.art-story[open] > summary { background: transparent; }
/* the word that says it is worth opening */
.art-story .story-more {
  font-weight: 500; opacity: .72; font-size: .8rem;
}
.art-story[open] .story-more { display: none; }
.art-story > p {
  margin: .8rem 0 0;
  font-size: .92rem;
  line-height: 1.62;
  opacity: .92;
}

/* --------------------------------- every drawing in the Kids' Corner
   A grid that grows a column rather than shrinking its tiles, so the
   hundredth drawing is the same size as the first. */
.kidall-card { max-width: 34rem; }
.kidall-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(6.4rem, 1fr));
  gap: .6rem;
  margin: .6rem 0 1rem;
  max-height: 56vh;
  overflow-y: auto;
}
.kidall-cell {
  display: block; padding: 0; border: 0; cursor: pointer;
  background: #fbf7ec;
  border-radius: 3px;
  box-shadow: 0 2px 7px rgba(30, 20, 8, .26);
  overflow: hidden;
  text-align: center;
}
.kidall-cell img {
  display: block; width: 100%; height: 5.4rem;
  object-fit: contain; background: #fffdf7;
}
.kidall-cell span {
  display: block; padding: .22rem .2rem .3rem;
  font-size: .7rem; opacity: .75;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Taking a drawing down. Quiet, and never shown unless this browser is the
   one that pinned it — or the curator has said who they are. */
.kid-unpin { color: #8c3f22; border-color: rgba(140, 63, 34, .45); }
.kid-unpin.sure { background: #8c3f22; color: #fff7e6; border-color: #8c3f22; }
.kid-by { cursor: default; }

/* The message box is the guest book now as well as the post box, so signing
   it is the first thing offered and it says when there is something new.

   It is also the thing most people opening this card want, and three
   identical rounded rectangles do not say which one that is. So this one
   carries the museum's brass — a wash of it, a firmer edge and a shadow off
   the page — and the two mail rows step back a shade to let it. */
.fb-sign {
  position: relative;
  border-width: 2px; border-color: rgba(176, 139, 69, .95);
  background: linear-gradient(rgba(230, 196, 127, .34), rgba(201, 162, 90, .17));
  box-shadow: 0 2px 0 rgba(120, 88, 30, .22), 0 7px 18px rgba(58, 44, 31, .14);
}
.fb-sign b { font-size: 18px; font-weight: 700; }
.fb-btn:not(.fb-sign) {
  border-color: rgba(140, 98, 57, .26);
  background: rgba(255, 250, 240, .6);
}
/* Big enough to be the reason you opened the card, and matching the brass tag
   on the box outside so the one is plainly the other. */
.fb-new {
  position: absolute; right: .7rem; top: 50%; transform: translateY(-50%);
  background: var(--brass); color: #2a2018;
  font-size: 14px; font-weight: 700; letter-spacing: .05em;
  padding: 5px 12px; border-radius: 999px;
  box-shadow: 0 1px 6px rgba(30, 20, 8, .35), 0 0 0 5px rgba(216, 178, 94, .22);
}
/* only the row that carries the tag makes room for it */
.fb-sign b, .fb-sign small { padding-right: 5.5rem; }


/* The attendance panel. Alex only, five taps on the room name — so it is
   plain: numbers and bars, no chrome, nothing that has to be maintained
   alongside the rest of the museum's furniture. */
#stats .card { max-width: 640px; }
.stat-tiles {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 10px; margin: 14px 0 4px;
}
.stat-big {
  background: rgba(120, 92, 44, .07); border-radius: 10px;
  padding: 10px 8px; text-align: center;
}
.stat-big b { display: block; font-size: 26px; color: #3a2c18; line-height: 1.1; }
.stat-big span { font-family: var(--sign); font-size: 11px; color: #7a6647; letter-spacing: .02em; }
.stat-big i { font-style: normal; opacity: .7; }
/* The one line under a group heading that says what the numbers below are
   counting. Small, quiet, and the difference between a panel you read and a
   panel you squint at. */
.stat-note {
  font-family: var(--body);
  font-size: 12px; line-height: 1.4;
  color: #8a7657;
  margin: -2px 0 8px;
}
.stat-door {
  margin: 12px 0 2px;
  padding: 8px 10px;
  background: rgba(160,130,70,.09);
  border-radius: 8px;
}
.stat-door .stat-h { margin-top: 4px; }
/* One counting method: its number, its name, and how it is arrived at. The
   number sets in a fixed column so the two methods line up and can be read as
   a comparison rather than as two separate facts. */
.stat-pair { display: flex; gap: 10px; align-items: baseline; margin: 7px 0; }
.stat-pair b {
  flex: 0 0 auto; min-width: 62px; text-align: right;
  font-size: 19px; color: #3a2c18; line-height: 1.15;
}
.stat-pair span { font-family: var(--sign); font-size: 11px; color: #7a6647;
                  letter-spacing: .02em; text-transform: uppercase; }
.stat-pair i {
  display: block; margin-top: 2px;
  font-family: var(--body); font-style: normal; font-size: 12px;
  line-height: 1.4; color: #8a7657; letter-spacing: 0; text-transform: none;
}
.stat-h {
  font-family: var(--sign); font-size: 11.5px; letter-spacing: .09em;
  text-transform: uppercase; color: #9a7d4a; margin: 20px 0 6px;
}
.stat-rows { display: flex; flex-direction: column; gap: 4px; }
.stat-row { display: grid; grid-template-columns: 1fr 84px 62px; align-items: center; gap: 8px; }
.stat-l {
  font-size: 14px; color: #4a3c26;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.stat-bar { background: rgba(120, 92, 44, .13); border-radius: 3px; height: 8px; overflow: hidden; }
.stat-bar i { display: block; height: 100%; background: #b08442; border-radius: 3px; }
.stat-n { font-family: var(--sign); font-size: 11px; color: #7a6647; text-align: right; }
/* one column a day, oldest on the left */
.stat-spark {
  display: flex; align-items: flex-end; gap: 2px;
  height: 46px; padding: 0 2px;
  background: rgba(120, 92, 44, .06); border-radius: 6px;
}
.stat-spark i { flex: 1 1 0; min-width: 2px; background: #b08442; border-radius: 2px 2px 0 0; }
.stat-ends {
  display: flex; justify-content: space-between;
  font-family: var(--sign); font-size: 10px; color: #9a7d4a; margin-top: 3px;
}
@media (max-width: 460px) {
  .stat-tiles { grid-template-columns: repeat(3, 1fr); gap: 6px; }
  .stat-big b { font-size: 21px; }
  .stat-big span { font-size: 10px; }
  .stat-row { grid-template-columns: 1fr 54px 56px; }
}

}
