/* Perry Lawson Fine Art v.2
   One committed identity, deliberately separate from the 90 North system.
   The brief, in Carole's words: "The more eyes that get on our art, the better."
   So the page has no colour of its own. The work supplies all of it. */

:root{
  /* Cool near-white ground, not cream, so warm paintings read true. */
  --paper:#fbfbfa;
  --plate:#ffffff;      /* artwork always sits on true white */
  --sunk:#f2f1ee;
  --ink:#16161a;
  --ink-2:#45454d;      /* secondary prose */
  --muted:#63636a;      /* meta; clears AA on paper and on sunk */
  --rule:#e3e2de;
  /* Raised from #d2d1cb, which measured 1.53:1 inside a white field and 1.48:1 on
     paper. WCAG 1.4.11 wants 3.0 for a control's boundary, and this token draws the
     border of every form field on ten routes and of the only way into the nav on a
     phone. #8b8b86 measures 3.01:1 on paper and 3.03:1 on white. */
  --rule-2:#8b8b86;
  /* No chromatic accent. Emphasis is weight, scale and space. */
  --maxw:1420px;
  --gut:clamp(20px,4.4vw,64px);
  /* The sticky header sits in flow, so anything that has to reach the fold subtracts it.
     It has exactly two heights and both are measured, not assumed: 20px padding either
     side of the 40px wordmark plus the rule on desktop, and 15px either side of the
     44px menu toggle plus the rule below 860px. The wordmark grew from 22px to 40px at
     Robin's request on 7 August, and it could grow exactly because the 40px Inquire
     button left the header in the same notes: the mark now fills the slot the button
     vacated, so both heights are unchanged and the hero math that subtracts this
     variable did not move. Keeping the nav on one line is what keeps this true. */
  --hdr:81px;
  --ctrack:.14em;
  --ease:cubic-bezier(.32,.72,0,1);
  --f-display:"Faustina",Georgia,serif;
  --f-body:"Work Sans",system-ui,-apple-system,sans-serif;
  /* ---- type scale ----
     Read off what the sheet was already doing rather than imposed on it. There were 23
     distinct plain sizes across 108 declarations and no token at all, so every new rule
     invented a value and near-duplicates piled up: 9.5 beside 10 beside 10.5, 15 beside
     15.5, 16 beside 16.5. These ten steps absorb all 23. Nothing that carries reading
     text moves: 17px and 15px are steps in their own right, because they are the two
     sizes the prose and the secondary prose are actually set at. The largest movement
     anywhere is 5.6%, and it lands on headings rather than on paragraphs.

     Named by the job, not by a t-shirt size, so the next rule written against this sheet
     picks a step by asking what the text is rather than how big it looks. */
  --t-micro:10px;     /* the smallest caps label */
  --t-label:11px;     /* the dominant uppercase label, 24 uses */
  --t-meta:12.5px;    /* metadata under a title */
  --t-small:14px;     /* small body, buttons, table cells */
  --t-minor:15px;     /* secondary prose: card descriptions, hints, spec rows */
  --t-base:16px;      /* UI base */
  --t-body:17px;      /* reading text: prose, form inputs */
  --t-lead:19px;      /* lead paragraph, small headings */
  --t-title:21px;     /* minor titles */
  --t-title-l:26px;   /* the largest fixed title */

  /* The display steps. `--t-page` was the one that mattered: the interior page h1 carried
     its size as an inline style on twelve pages, so h1 and h2 were the same class and only
     the inline copy told them apart. It is a token and a selector now, and a page title is
     a page title everywhere. */
  --t-page:clamp(30px,4.8vw,58px);
  --t-work:clamp(28px,3.6vw,46px);
  --t-section:clamp(26px,3.4vw,44px);
  /* A heading inside a page, under its title. Kept its own step rather than borrowing
     --t-section: "Getting Here" on /visit would have gone from 32px to 44px at desktop
     and started competing with the page title above it. */
  --t-subsection:clamp(22px,2.6vw,32px);
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;
     /* The header is fixed, so an in-page anchor would otherwise land its target
        underneath it. Every jump stops clear of the bar. */
     scroll-padding-top:calc(var(--hdr) + 12px)}
/* padding-top, because the header is fixed rather than sticky. See .site-head. */
body{margin:0;padding-top:var(--hdr);background:var(--paper);color:var(--ink);
     font-family:var(--f-body);font-size:var(--t-body);line-height:1.6;font-weight:400;
     -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
img{max-width:100%;height:auto;display:block}
a{color:inherit;text-decoration:none}
h1,h2,h3{font-family:var(--f-display);font-weight:400;letter-spacing:-.018em;
         line-height:1.06;margin:0;text-wrap:balance}
p{margin:0 0 1.15em}
:focus-visible{outline:2px solid var(--ink);outline-offset:3px}
/* A ring the colour of the ink is invisible on a photograph and on the lightbox's
   near-black: measured 1.08:1 inside the lightbox and about 1.4:1 on the home hero, which
   is exactly the keyboard path we monetise. A white ring with a dark halo survives a
   painting and a black ground alike. */
.lb :focus-visible,.hero--home :focus-visible,.hero--full :focus-visible,
[data-hero] .hero--home :focus-visible{
  outline:2px solid #fff;outline-offset:2px;box-shadow:0 0 0 4px rgba(12,12,13,.7)}
/* Visually hidden, still read aloud. The Desk shows its own name as bold text inside the
   brand lockup, which looks right and leaves the page with no h1 at all, so a screen
   reader lands on an application with no heading to orient by. */
.vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;
    clip-path:inset(50%);overflow:hidden;white-space:nowrap}
.skip{position:absolute;left:-9999px;top:0;z-index:100;background:var(--ink);color:var(--paper);
      padding:12px 20px;font-size:var(--t-small)}
.skip:focus{left:8px;top:8px}

.wrap{max-width:var(--maxw);margin:0 auto;padding:0 var(--gut)}
.caps{font-family:var(--f-body);font-size:var(--t-label);letter-spacing:var(--ctrack);
      text-transform:uppercase;color:var(--muted);font-weight:500}
.lede{font-size:clamp(17px,1.55vw,21px);line-height:1.55;max-width:58ch;color:var(--ink-2)}

/* ---------------- header ---------------- */
/* FIXED, not sticky, and the body carries the offset instead.
 *
 * 1 September: the bar was taking 9 to 11% of an iPhone screen on every page, and it does
 * it on all 198 of them. It condenses on scroll now, roughly 30px back on a phone.
 *
 * A sticky header cannot do that without jank. Sticky keeps the element IN FLOW, so
 * shrinking it at a scroll threshold shortens the flow and everything below jumps up by
 * the difference, once, mid-scroll. Fixed takes the header out of flow entirely and the
 * body's padding-top holds the space it used to occupy; when the bar condenses the page
 * does not move at all, there is simply less of it covered.
 * --hdr stays 81px throughout, so every calc(100dvh - var(--hdr)) elsewhere in this
 * sheet keeps meaning what it meant.
 *
 * WHAT DOES MOVE is the bar's own contents, the wordmark and the nav, and the
 * layout-shift API counts that: measured 0 on every phone width and 0.035 on a 1280
 * desktop, against a 0.1 threshold. It is not the fault CLS exists to catch, which is
 * content jumping under somebody mid-read, and the page body is provably still.
 * Writing "zero layout shift" flat would have been wrong, so the number is here. */
.site-head{position:fixed;top:0;left:0;right:0;z-index:40;background:var(--paper);
           border-bottom:1px solid var(--rule)}
.site-head__in{transition:padding .24s var(--ease)}
.brand img{transition:height .24s var(--ease)}
/* The condensed state. The wordmark stays legible and the nav does not move sideways;
   only the air above and below it goes. */
.site-head.is-condensed .site-head__in{padding-top:9px;padding-bottom:9px}
.site-head.is-condensed .brand img{height:28px}
/* On a phone the bar's height is NOT set by the wordmark. It is set by the Menu button,
   which is 44px because that is the touch-target floor, and 15px of padding either side
   of it is what made 75px. Shrinking the mark from 32 to 26 therefore bought nothing at
   all: measured, it moved the bar by zero, because the mark was never the tall thing in
   the row. The padding is what goes. 4px either side of a 44px button is a 53px bar, the
   button is untouched at 44, and 22px comes back on every page. */
@media (max-width:700px){
  .site-head.is-condensed .site-head__in{padding-top:4px;padding-bottom:4px}
  .site-head.is-condensed .brand img{height:28px}
}
@media (prefers-reduced-motion:reduce){
  .site-head__in,.brand img{transition:none}
}
.site-head__in{display:flex;align-items:center;justify-content:space-between;gap:26px;
               max-width:var(--maxw);margin:0 auto;padding:20px var(--gut)}
/* 40px, up from 22px (Robin, 7 August, "can we make the logo bigger?"). 40 and not
   more because 40 is the height the header already reserved for the Inquire button he
   removed in the same round: the mark nearly doubles and --hdr stays exactly 81px.
   The step below 420px is measured, not taste: the mark is 5.03x wider than it is
   tall, and at 40px it is 201px, which with the Menu toggle overflows a 320px screen
   and wraps the header to two lines of unknowable height. 32px keeps one line. */
.brand img{height:40px;width:auto}
@media (max-width:420px){.brand img{height:32px}}
.nav{display:flex;gap:clamp(13px,1.6vw,24px);flex-wrap:wrap}
.nav a{font-family:var(--f-body);font-size:var(--t-label);letter-spacing:var(--ctrack);text-transform:uppercase;
       font-weight:500;color:var(--ink);opacity:.66;padding-bottom:3px;border-bottom:1px solid transparent}
.nav a:hover{opacity:1}
.nav a[aria-current]{opacity:1;border-bottom-color:var(--ink)}
/* The Exhibitions dropdown, the one folder the live gallery site carries. It opens on
   hover and on focus, and the whole folder stays inside one hit area so the menu does
   not close while the pointer crosses the gap between the word and its list. */
.nav__folder{position:relative;display:inline-flex}
.nav__top{background:none;border:0;border-bottom:1px solid transparent;color:var(--ink);
          font-family:var(--f-body);font-size:var(--t-label);letter-spacing:var(--ctrack);
          text-transform:uppercase;font-weight:500;opacity:.66;padding:0 0 3px;cursor:pointer}
.nav__top::after{content:"";display:inline-block;width:5px;height:5px;margin-left:7px;
                 border-right:1px solid currentColor;border-bottom:1px solid currentColor;
                 transform:translateY(-2px) rotate(45deg)}
.nav__folder:hover .nav__top,.nav__folder:focus-within .nav__top{opacity:1}
.nav__top[aria-current]{opacity:1;border-bottom-color:var(--ink)}
.nav__sub{position:absolute;top:100%;left:-14px;z-index:50;display:flex;flex-direction:column;
          gap:11px;min-width:210px;padding:15px 18px 16px;background:var(--paper);
          border:1px solid var(--rule);opacity:0;visibility:hidden;transform:translateY(-4px);
          transition:opacity .16s var(--ease),transform .16s var(--ease),visibility .16s}
.nav__folder:hover .nav__sub,
.nav__folder .nav__top[aria-expanded="true"]+.nav__sub{opacity:1;visibility:visible;transform:none}
.nav__sub a{white-space:nowrap;opacity:.72}

/* The header address line and the Inquire button both left at Robin's request, 7
   August ("i don't think we need the address here", "please remove 'inquire' at
   top"). The header is the wordmark and the nav, nothing else; the money paths run
   through the pages themselves and the footer plate. */
.navtoggle{display:none;background:none;border:1px solid var(--rule-2);color:var(--ink);
           font:inherit;font-size:var(--t-label);letter-spacing:.13em;text-transform:uppercase;padding:9px 14px}

/* ---------------- hero ---------------- */
.hero{}
.hero__media{background:var(--sunk)}
/* <picture> is an inline box with no height of its own. Every hero image is wrapped in
   one, so `height:100%` on the img had nothing definite to resolve against and silently
   fell back to the intrinsic aspect: on the home hero that rendered a 1198x1200 painting
   at the full width of the window, 2128px tall inside a 1273px section, and with no
   overflow rule anywhere it painted straight down over the two sections below it. That
   is the "pages 1-3 are broken" bleed. Blocking the wrapper is what makes the percentage
   height mean what it says. */
.hero__media picture{display:block;width:100%}
.hero__media img{width:100%;height:min(72vh,660px);height:min(72dvh,660px);object-fit:cover}
/* The plate hero carried no height rule at all, only a cap on its image, so on 24
   exhibition pages it stopped wherever that particular painting plus that particular
   title block happened to stop. Measured: short by 300px at 2560x1440 and by 259px on
   a 15 Pro Max, where the body copy then starts above the fold. Where it reached the
   fold at all it was coincidence. This is the same pair `.hero--full` carries, `vh`
   first and `dvh` second, with the media taking the slack so the painting centres in
   whatever room is left rather than the gap falling under the title. */
.hero--plate{display:flex;flex-direction:column;
             min-height:calc(100vh - var(--hdr));
             min-height:calc(100dvh - var(--hdr))}
.hero--plate .hero__media{padding:clamp(28px,5vw,72px);background:var(--plate);
                          border-bottom:1px solid var(--rule);
                          flex:1;display:flex;align-items:center;justify-content:center}
.hero--plate .hero__media img{height:auto;max-height:min(66vh,620px);max-height:min(66dvh,620px);object-fit:contain;
                              margin:0 auto;width:auto}
/* Halved on 1 September. Robin, pinning the title block on the Ben Schonzeit page
   with the note's scope set to everywhere: "a little bit too much of a gap there, let's
   just say half of it, take 50% out", and then "make sure it doesn't appear like this
   anywhere else". It is the OUTER padding that is halved, the band between the picture
   and the eyebrow above and the body copy below. The margins inside the block are left
   where they are, because the same conversation asked for the title to keep its own
   room: cutting those as well would close the block up on itself rather than close the
   gap around it. */
.hero__body{max-width:var(--maxw);margin:0 auto;
            padding:clamp(15px,2vw,26px) var(--gut) clamp(17px,2.2vw,29px)}
.hero__eyebrow{font-family:var(--f-body);font-size:var(--t-label);letter-spacing:var(--ctrack);
               text-transform:uppercase;color:var(--muted);font-weight:500;margin:0 0 20px}
.hero__title{font-size:clamp(36px,5.8vw,76px);margin:0 0 12px;max-width:20ch}
.hero__sub{font-size:clamp(17px,1.7vw,23px);line-height:1.4;color:var(--ink-2);margin:0 0 14px;
           max-width:46ch;font-family:var(--f-display)}
/* The second line of a two-line exhibition title. It used to take the lede setting
   above, 17-23px against a 36-84px first line, a 3.6x drop that read as a minor
   subtitle when the line is usually the other half of the title: the collaborators on
   a joint show, the artist's name on a solo. Rebalanced at the 9 August meeting to
   hold near 1.65x at every width, in the ink rather than the secondary grey, and the
   title cap comes down a step (84 to 76) so the pair reads as one title instead of two
   shouts; every ladder below keeps the same relationship, so the pair never splits
   back into title plus caption on a phone. Sentence-length subs (About, Visit,
   Commissions, Gatherings) do not carry this class and keep the lede setting. */
.hero__sub--title{font-size:clamp(22px,3.5vw,46px);line-height:1.22;color:var(--ink);
                  letter-spacing:-.018em;text-wrap:balance}
.hero__dates{font-family:var(--f-body);font-size:var(--t-meta);letter-spacing:var(--ctrack);
             text-transform:uppercase;color:var(--muted);margin:0 0 30px}

/* full-bleed opening: art first, one action, no explanation */
/* The photograph header, and it fills the window, which `min(88dvh,880px)` never did:
   88 of anything is short of the fold by definition, and it was measured short at ten of
   the thirteen geometries and overflowing at the other three. Same recipe the home page
   already uses: a minimum height of the window less the sticky header, in `vh` first for
   anything that has never heard of `dvh`, the picture absolutely filling the box behind
   the type. `min-height`, never `height`, so a short screen grows the section instead of
   cropping the words in it. */
.hero--full{position:relative;border-bottom:0;overflow:hidden;
            display:flex;flex-direction:column;justify-content:flex-end;
            min-height:calc(100vh - var(--hdr));
            min-height:calc(100dvh - var(--hdr))}
.hero--full .hero__media{position:absolute;inset:0;z-index:0}
.hero--full .hero__media picture{height:100%}
.hero--full .hero__media img{width:100%;height:100%;object-fit:cover}
/* The wash. Measured 1 September against the pixels actually rendered under each line,
   not against a token pair: the eyebrow was coming out at 3.64:1 where AA wants 4.5,
   because the old ramp had already fallen to 14% black by the height the eyebrow sits at.
   The lower half is darker and the falloff moved up. Above 84% it is still clear glass,
   so the photograph is not flattened, which was the point of a gradient over a plate. */
.hero--full::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:1;
  background:linear-gradient(to top,rgba(0,0,0,.82) 0%,rgba(0,0,0,.68) 20%,rgba(0,0,0,.5) 42%,rgba(0,0,0,.2) 64%,transparent 86%)}
.hero--full .hero__body{position:relative;z-index:2;color:#fff;
  padding-bottom:clamp(34px,5vh,64px)}

/* The height ladder. A landscape phone is about 402px tall and this header carries a
   two-sentence explanation of which business runs which half of the house. That sentence
   is the first thing to go, then the display type steps down. The button never goes. */
@media (max-height:620px){
  .hero--full .hero__sub{display:none}
  .hero--full .hero__title{font-size:clamp(26px,4.4vh,38px)}
  .hero--full .hero__body{padding-bottom:20px}
}
@media (max-height:460px){
  .hero--full .hero__eyebrow{display:none}
  .hero--full .hero__title{font-size:clamp(21px,4vh,28px);margin-bottom:10px}
  .hero--full .hero__body{padding-bottom:14px}
}
/* EVERY line over the photograph, not three of the four. `.hero__sub` was the one text
   element this block never claimed, so it kept `--ink-2` from the base rule: dark grey
   ink sitting on a photograph, measured at 2.06:1 on /gatherings where AA wants 4.5.
   Nothing looked broken, which is why it stood: the words were legible against the light
   part of that particular picture and would have disappeared entirely against a darker
   one. A rule that recolors three of four siblings is a rule with a hole in it. */
.hero--full .hero__eyebrow,.hero--full .hero__dates{color:rgba(255,255,255,.94)}
/* Full white, not .94. Measured against the real pixels it came out at 4.42:1 where AA
   wants 4.5, which is the kind of miss that only a measurement finds: it looks fine.
   The last 6% of opacity is what closes it, and the wash below carries the rest. */
.hero--full .hero__sub{color:#fff}
.hero--full .hero__title{color:#fff}
.hero--full .btn{border-color:#fff;background:#fff;color:#16161a}
.hero--full .btn:hover{background:transparent;color:#fff}

/* the curatorial statement: one thought, given the whole width */
.statement{margin:0;border-left:0;padding:0;max-width:64ch}
.statement p{font-family:var(--f-display);font-size:clamp(21px,2.4vw,31px);line-height:1.42;
  color:var(--ink);margin:0 0 18px;text-wrap:pretty}
.statement__slot{color:var(--muted)}
.statement cite{font-style:normal}

/* The "three selected works" module and the home events preview (.sel, .evp) left the
   sheet with the sections themselves: Robin removed both from the home page in her
   7-8 August notes, and nothing else ever drew them. */

/* ---------------- actions ---------------- */
.btn{display:inline-flex;align-items:center;min-height:46px;font-family:var(--f-body);font-size:var(--t-label);
     letter-spacing:.15em;text-transform:uppercase;font-weight:500;padding:0 26px;
     border:1px solid var(--ink);color:var(--ink);background:transparent;
     transition:background .25s var(--ease),color .25s var(--ease)}
.btn:hover{background:var(--ink);color:var(--paper)}
.btn:active{transform:translateY(1px)}
.btn--solid{background:var(--ink);color:var(--paper)}
.btn--solid:hover{background:transparent;color:var(--ink)}
.btn--quiet{border-color:transparent;border-bottom:1px solid var(--ink);padding:0 0 4px;min-height:0}
.btn--quiet:hover{background:transparent;color:var(--muted);border-bottom-color:var(--muted)}

/* A quiet button whose visible word is short is still a target a thumb has to land on.
   "View" plus a visually hidden exhibition title measured 37px wide on Current and
   upcoming, at every touch geometry: it clears WCAG 2.5.8's 24px but not the 44px a
   phone actually wants. Width, not height, was the miss. Centring keeps the label where
   it already sat for anything wider than 44px. */
@media (pointer:coarse){
  .btn{min-width:44px;justify-content:center}
  .btn--quiet{min-width:44px}
}
/* WCAG 2.2 AA wants a 24px target and this link was 21, everywhere it appears in prose:
   Connect, About, Events, the exhibition pages. Padding on an INLINE element grows the
   box that is hit and drawn without touching the line box, so the paragraph does not
   move a pixel and the underline stays where the reader expects it. `padding-inline: 0`
   is deliberate: horizontal padding on an inline element would widen the hit area past
   the words and swallow the space either side of the link. */
/* Every link inside prose, not only the ones carrying .inline-link. The email address
   on the open-call page is a bare <a> in a paragraph and came out 20px, four short of
   the WCAG 2.2 AA target, because no rule had claimed it. */
.inline-link,.prose p a,.note p a,.lede a{border-bottom:1px solid var(--rule-2);
             padding-block:2.5px;padding-inline:0}
.inline-link:hover{border-bottom-color:var(--ink)}

/* ---------------- sections ---------------- */
/* ---- the vertical rhythm ----
   Two numbers were doing the work of one. Every section carried the full step top AND
   bottom, so wherever two sections met, the gap between one piece of content and the next
   was 208px at desktop: a screen and a bit of nothing on the short pages, which measured
   30% padding on About, Commissions and every service page.

   So the step comes down, and the boundary between two sections is ONE step rather than
   two. A section that opens a page keeps the full measure above it, because that space is
   the page beginning; a section that follows another only needs enough to be read as a
   new thing. Measured across 59 pages: 4.4 screens average before, and the padding share
   is what moved, not the content. */
.sec{padding:clamp(48px,5.8vw,84px) 0}
.sec+.sec{padding-top:clamp(34px,3.9vw,56px)}
.sec--tight{padding:clamp(34px,4vw,54px) 0}
.sec--tight+.sec,.sec+.sec--tight{padding-top:clamp(30px,3.4vw,48px)}
/* A heading block that runs straight into the thing it names, with no hairline drawn
   between the two. Asked for on Past exhibitions, 14 August. */
.sec--noline{border-bottom:0}
.sec--plate{background:var(--plate)}
.sec__head{display:flex;align-items:baseline;justify-content:space-between;gap:24px;
           flex-wrap:wrap;margin-bottom:clamp(28px,3.2vw,48px)}
.sec__title{font-size:var(--t-section)}
/* A page title is not a section heading. Both wore .sec__title, and on 32 routes the only
   thing separating them was an inline font-size repeated on twelve pages. The element
   carries the difference now, so nothing has to remember to write it. */
h1.sec__title{font-size:var(--t-page)}
h1.sec__title--work{font-size:var(--t-work)}
/* The second line of an exhibition title inside a module (Current, Upcoming). Same
   9 August rebalance as the hero's .hero__sub--title: near 1.65x of the .sec__title
   above it, display face, in the ink, so the pair reads as one title rather than a
   heading over a caption. Rides on .lede for measure and rhythm and overrides its
   size and colour, so it must stay below .lede in this sheet. */
.ex__sub{font-family:var(--f-display);font-size:clamp(18px,2.05vw,27px);line-height:1.25;
         letter-spacing:-.014em;color:var(--ink)}
.prose{max-width:64ch}
.prose p{font-size:var(--t-body);line-height:1.72;color:var(--ink-2);text-wrap:pretty}
.prose p:first-of-type{font-size:var(--t-lead);line-height:1.6;color:var(--ink)}
/* One size for every paragraph in the block. The rule above promotes an opening paragraph
   to --t-lead, which is right where that paragraph is a standfirst and wrong where it is
   simply the first of several equal ones. 29 August, the gallery, on About: "make font
   same as bios". The founding paragraph ran at 19px over three biographies at 17px, so
   the page read as a lede followed by small print, when all four paragraphs are the same
   kind of writing doing the same job. */
.prose--plain p:first-of-type{font-size:var(--t-body);line-height:1.72;color:var(--ink-2)}
/* A reading column with nothing beside it sits in the middle of its band. 29 August, the
   gallery, on the exhibition text: "make the left and right margins the same". A 64ch
   measure hung on the left of a full-width wrap leaves a hand's width of air on one side
   and a screen's worth on the other, which is what she is looking at. The measure is the
   thing worth keeping, so the column centers rather than widening to fill. */
.prose--mid{margin-inline:auto}
.prose h3,.prose .prose-h{font-size:clamp(19px,1.9vw,24px);margin:34px 0 12px;color:var(--ink);
  font-family:var(--f-display);font-weight:400;letter-spacing:-.018em;line-height:1.12}
.cols{display:grid;grid-template-columns:1.4fr 1fr;gap:clamp(32px,5vw,80px);align-items:start}
.cols--flip{grid-template-columns:1fr 1.4fr}
.cols--flip>:first-child{order:2}
.cols--even{grid-template-columns:1fr 1fr}
/* The founders' photograph on About, back near the top at Robin's request. A `.plate`
   would draw a frame around it and the frames came off every photograph on 21 August,
   so this is the picture and nothing else, square, at the head of the narrow column. */
.por{margin:0}
.por img{display:block;width:100%;height:auto}
/* On a phone the two columns stack, and stacking put the photograph at 1,772px of a
   3,305px page: after both biographies, which is the opposite of the note that asked
   for it "back toward the top". Desktop honoured her and mobile reversed her. It leads
   the section under 860px, where most people read this page. */
@media (max-width:860px){
  /* `order` has to sit on the grid CHILD, not on the figure inside it: the figure is a
     grandchild of .cols and ordering it moved nothing. */
  .cols > :has(.por){order:-1}
  .cols .por{max-width:340px}
}

.grid{display:grid;gap:clamp(24px,2.8vw,44px)}
.g2{grid-template-columns:repeat(2,1fr)}
.g3{grid-template-columns:repeat(3,1fr)}
/* Row gap only, and only on Services. Two of the 29 August notes land on one service card
   asking for less space, and the largest gap around that card is the one to the card
   below it. The column gap stays as it is: it is what keeps three services reading as
   three rather than as one column of six. */
.grid--svc{row-gap:clamp(20px,2.2vw,30px)}
.g4{grid-template-columns:repeat(4,1fr)}

/* ---------------- the artists index ----------------
   Three squares to a row, no frame under them, the artist's name below. Rebuilt on
   14 August: "We're highlighting the ARTIST. No works below/mentioned. 3 artists PER
   line. Larger images", with Kenise Barnes Fine Art's artists page as the reference,
   and "we want the images to float", "same square format", "uniform cropped".

   Floating means exactly that: no plate, no border, no padding. The image sits on the
   paper and the page reads as a wall of work rather than a row of product cards. It is
   the one grid on this site that crops (see the matting rule below), because a square
   index only reads as one gallery if every tile is the same shape, and the whole work
   is one click away on the artist's own page.

   Three, two, one, and the drop to two comes early: at 860 a third of the column is
   about 290px, which is where a face in a painting stops being legible. */
/* Three across, fixed, and it stays fixed: "3 artists PER line" is the gallery's own
   instruction above, not a preference to be optimised away. The auto-fill track tried on
   23 August ran /artists to four columns on a laptop and five on a wide screen, which is
   a contact sheet, not an index of thirteen represented artists. Three inside the 1420px
   measure gives every artist the same ~400px square at desktop. The thirteenth sitting
   alone on the last row is the price of the shape, and it is accepted. */
.gq{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(30px,3.4vw,56px)}
.aq{display:block}
.aq__media{display:block;overflow:hidden;margin-bottom:16px;background:var(--plate)}
/* cover, so thirteen artists read as thirteen equal squares: "same square format",
   "uniform cropped", again the gallery's own words. `contain`, tried 23 August,
   letterboxed each painting to its own ratio on the same white as the page behind it, so
   no square was visible at all and the grid read as scattered images of thirteen
   different sizes. The index crops; the artist's own page shows the work whole on the
   plate. Where a centre crop cuts the subject, that artist gets an `object-position`
   below rather than the whole grid giving up its shape. */
.aq__media img{display:block;width:100%;aspect-ratio:1;object-fit:cover;
               transition:transform .7s var(--ease)}
.aq:hover .aq__media img{transform:scale(1.035)}
/* The positions the rule above promises, written 11 September after looking at every one of
   these tiles rendered at its real 398px rather than at the size of the source file. Each is
   the smallest move off center that stops the square eating something the painting needs, and
   the hook is the tile's own href, which the generator writes for the index and for the peers
   row both, so a painting crops the same way wherever it is shown.

   Brian Hart, 840x1100: a centered square takes 12% off the top and the standing figure loses
   the crown of its head, which is the one thing a crop may never do. Up to 25% clears the head
   with air above it and spends the difference at the bottom, where the weave carries on.

   Evan Jorgensen, 847x1100: the plate is the picture, and centered, both the top rim and the
   top of the bread slice fall outside the square. Up to 35% puts the whole ellipse back inside
   and still lets the knife run out of the bottom edge, which it does on the canvas too.

   Jay Wu, 885x1100: centered, the trunk meets the ground about 12px from the bottom of the
   tile and the tree reads as standing on the frame. Down to 60% gives it the orange foreground
   to stand in, and gives up the top of the canopy, which runs off the top of the canvas anyway.

   Taylor Bielecki, 1100x866: the dark transformer box on the left-hand pole is the only drawing
   in an otherwise empty blue, and a centered square slices its left side flat against the frame.
   Left to 38% puts the box back whole; what the right edge gives up in exchange is empty sky.

   Emily Hopkins, 1100x762: the widest canvas of the thirteen and the one the square serves
   least. The orange runs from 66% to 91% across the picture and a centered square ends at 85%,
   so the one hot passage gets cut through the middle. Right to 64% recovers nearly all of it
   while the pale column and the pink at the left stay whole. Going further to catch the last of
   the orange starts cutting the column, which is the larger form, so this is a trade and not a
   fix: at 64% the tail of the orange still reaches the frame.

   Niva Shrestha, 1100x922: the blue cistern sits at 86% to 94% across and a centered square
   ends at 92%, cutting a hard-edged cylinder in half, which in a flat architectural painting
   reads as damage rather than as a crop. Left to 14% stops the square just short of it, so the
   cistern is left out cleanly and the stepped chimney at the other edge survives whole. The
   staircase, which is the subject, sits dead center and was never at risk either way.

   Stephanie Serpick is absent from this list on purpose. Her canvas gives up 20% of its width
   to the square and none of it costs anything: both edges are soft curtain falls with no hard
   form to sever, and the lit window and the drapery sit inside the centered square already. A
   position with nothing to fix is noise in a file this long. */
.aq[href^="artist-brian-hart"] .aq__media img{object-position:50% 25%}
.aq[href^="artist-evan-jorgensen"] .aq__media img{object-position:50% 35%}
.aq[href^="artist-jay-wu"] .aq__media img{object-position:50% 60%}
.aq[href^="artist-taylor-bielecki"] .aq__media img{object-position:38% 50%}
.aq[href^="artist-emily-hopkins"] .aq__media img{object-position:64% 50%}
.aq[href^="artist-niva-shrestha"] .aq__media img{object-position:14% 50%}
.aq__n{display:block;font-family:var(--f-display);font-size:clamp(19px,1.6vw,23px);
       line-height:1.3;letter-spacing:-.015em;color:var(--ink)}
.aq:hover .aq__n{color:var(--ink-2)}
@media (max-width:860px){.gq{grid-template-columns:repeat(2,1fr)}}
@media (max-width:520px){.gq{grid-template-columns:1fr}}
/* "Also at the gallery" is a footnote, and it was outranking the page it sits on.
   Measured 23 August on Christine Lafuente's page: her own paintings drew 227px and the
   twelve OTHER artists under them drew 360px. Nothing on an artist's page may be larger
   than her own work. Six across at a laptop puts twelve peers in two clean rows at about
   153px, which is an index of who else is here rather than a second gallery. */
.gq--peers{grid-template-columns:repeat(auto-fill,minmax(140px,1fr));
           gap:clamp(18px,1.8vw,28px)}
.gq--peers .aq__n{font-size:var(--t-small);line-height:1.35}
@media (max-width:520px){.gq--peers{grid-template-columns:repeat(2,1fr)}}

/* ---------------- the work ----------------
   Every piece is matted on true white and shown whole: `.wall__media`, `.work__plate`,
   `.arch__i` and `.hl__media` all letterbox onto the plate rather than filling their box,
   and the archive rows do the same at thumbnail size.

   Two things do not obey this rule, and both are deliberate rather than overlooked. The
   home hero fills the window and carries a gradient scrim, because it was approved that
   way and because the scrim is what holds the type over it above AA; it is a poster, not
   a plate. The venue photographs on /visit and /gatherings crop, because a room is not a
   piece of work. Nothing else may crop or tint an artwork. */
.card{display:block}

/* ------------------------------------------------------------------ the wall label
 *
 * Robin and Carole, 25 August, with the gallery's original artist page as the reference:
 * every work carries who made it, what it is called, what it is made of, how big it is
 * and what it costs, centred under the picture, the way a label is set beside work on a
 * wall. The fields come from the archive record. Two of them, medium and dimensions, had
 * never been printed anywhere on this site, and they are the two a collector at a
 * distance actually needs.
 *
 * THE SHELF. Each work is given the same height and sits on the bottom of it, so a row
 * reads as work hung on a line rather than as tiles in a grid, and each keeps its own
 * proportion: a 30 x 48 painting comes out wider than a 12 x 12 one instead of both
 * being squashed into the same square. `height` on the media box rather than the image
 * is what makes the labels align too, because every picture then hands the label the
 * same baseline whatever shape it is.
 *
 * Nothing is cropped, ever. `object-fit:contain` with both maxima set means the whole
 * work is inside the box at its true aspect ratio, which is rule 4 of the artist-site
 * standard and the reason a gallery can use this page to sell from. */
/* THE `<picture>` IN THE MIDDLE IS THE WHOLE PROBLEM, and it cost two goes to see.
   The build wraps every sized image in `<picture>` for the srcset ladder, so the img is
   a grandchild of this box, not a child. `<picture>` is an inline box of automatic
   height, which breaks the percentage-height chain: `height:100%` on the img resolves
   against something with no definite height and quietly falls back to auto, the picture
   grows to whatever the photograph is, and three works land on top of the biography.
   The first attempt at this shelf used flexbox and `max-height:100%` and failed for the
   same reason, and it was misread as a WebKit flex bug because BOTH engines were wrong
   and the check was measuring the img against its `<picture>`, which by definition
   always matches it.
   So the picture is made a block with a real height, and the chain is definite again.
   The QA assertion measures the img against `.wall__media`, never against its parent. */
.wall__media{position:relative;background:var(--plate);
             height:clamp(190px,21vw,272px);
             padding:clamp(10px,1.1vw,18px);margin-bottom:24px;
             transition:transform .45s var(--ease)}
.wall__media picture{display:block;height:100%;width:100%}
.wall__media img{width:100%;height:100%;display:block;
                 object-fit:contain;object-position:center bottom}
.card:hover .wall__media{transform:translateY(-2px)}

/* THE LABEL IS FIVE ROWS THE WHOLE GRID SHARES.
   Each card spans five rows of the works grid and hands them to `subgrid`, so every
   artist name in a row sits on one line, every title on the next, and a title that wraps
   to two lines lifts that row for every card rather than pushing one card's price out of
   step with its neighbours. Jake, 25 August: "have the label be symmetrical across the
   cards". Without subgrid the lines still stack in the right order and simply do not
   align across cards, which is where this started rather than a broken page. */
/* THE ROW GAP HAS TO COME OFF THE PARENT, not off the card.
   Once the card hands its rows to `subgrid`, those five label lines ARE rows of the
   outer grid, so the outer grid's 44px gutter sits between every one of them and the
   label falls apart down the page. `row-gap:0` on the card does nothing about it: a
   subgrid does not own the gutters between its parent's tracks. So the grid gives up its
   row gap entirely and the space between one row of works and the next is carried by the
   card's own bottom padding, which is the only thing that should be creating it. */
.grid--works,.wk-grid{row-gap:0}
.grid--works > .card,.wk-grid > .card{grid-row:span 6;row-gap:0;
                                      padding-bottom:clamp(30px,3.2vw,52px)}
@supports (grid-template-rows: subgrid){
  .grid--works > .card,.wk-grid > .card{display:grid;grid-template-rows:subgrid}
}
.wall__a,.wall__t,.wall__m,.wall__d,.wall__p{
      display:block;text-align:center;font-family:var(--f-body);
      font-size:var(--t-meta);line-height:1.55;color:var(--ink-2);text-wrap:pretty;
      margin:0}
.wall__a{color:var(--ink);font-weight:600}
/* The title is the one italic on this site, and it is a wall-label convention rather
   than emphasis: it is how a work's name is set on a label, in a catalogue and in a
   checklist. Body text is never italic here (§2b). */
.wall__t{color:var(--ink);font-weight:600;font-style:italic}
.wall__p{color:var(--ink-2)}
/* An empty row still holds its place in the grid, and holds no height of its own. */
.wall__a:empty,.wall__t:empty,.wall__m:empty,.wall__d:empty,.wall__p:empty{
  line-height:0;min-height:0}

/* A phone takes two to a row and keeps the shelf. One across would turn Robin Reynolds'
   twenty works into twenty screens, and the reader would lose the one thing the grid is
   for, which is knowing how big the body of work is before committing to it. */
@media (max-width:700px){
  .wall__media{height:clamp(150px,42vw,200px);margin-bottom:16px;
               padding:clamp(6px,1.6vw,12px)}
  .wall__a,.wall__t,.wall__m,.wall__d,.wall__p{font-size:12px;line-height:1.55}
}

/* The sold badge is gone from this sheet with the rule that drew it, 25 August: sold work
   is not shown, so nothing is left to badge. The argument it used to carry, that a gallery
   which never shows a red dot has no evidence anyone has ever bought there, is a real one
   and it is answered somewhere other than an availability grid. `.price--sold` stays: the
   lightbox and the work bar still read a price line. */
.price--sold{color:var(--muted)}
.price--sold b{color:var(--ink);font-weight:600}

/* The same plate at exhibition scale.

   The gesture was applied inversely to importance: a 280px artist thumbnail got the plate,
   the hairline and 26px of air, while the 700px exhibition image that carries Current and
   Upcoming got no rule at all and bled straight into the paper. The bigger the work on the
   page, the more it earned the frame. `.plate` is that frame at any size, and it letterboxes
   rather than crops, so it obeys the rule stated above. */
/* The padding went to zero on 23 August, and it is the second half of a decision the
   gallery already made. On 21 August they asked three times, in three different words,
   to take the lines off the pictures. The hairline came off then and this stayed: a
   pure white margin, measured at 20.5px against #fbfbfa paper, on all four sides of
   every artwork on the site. A visible white rectangle around a painting IS a frame,
   whether or not it has a line at its edge. The white ground stays, because a painting
   on a white ground reads true and one on warm paper does not, but it now only ever
   sits UNDER the picture and never around it. */
.plate{display:block;background:var(--plate);
       transition:border-color .45s var(--ease),transform .45s var(--ease)}
.plate img{display:block;width:100%;height:auto;object-fit:contain;margin:0 auto}
a.plate:hover{border-color:var(--ink);transform:translateY(-2px)}

/* Carriers for the lightbox only: the other works in the collection, so prev and next walk
   the gallery from whichever piece was opened rather than dead-ending on one picture.
   They hold attributes, never a src, so nothing is fetched for them. */
.lb-more{display:none}
.card:active .wall__media{transform:translateY(0)}
/* An artwork's title is set in italic, the way a gallery sets one: in a card, in a
   listing row, in a caption and in the lightbox. Jake, 14 August, "Artwork titles are ALL
   italicized", with the one exception he gave in the same breath, "not italicized if it's
   in a TITLE". So a title stays roman where it IS the heading, on an artwork's own page
   and on the lead work of an artist page, because a display line set apart at 40px is
   already doing what the italic is for. Exhibition titles, artist names and event names
   are not artworks and never take it. */
.card.wk .card__t,.card--work .card__t,.lb__t,.wt{font-style:italic}
.card__t{font-family:var(--f-display);font-size:clamp(17px,1.4vw,20px);letter-spacing:-.012em;
         margin:0 0 3px;line-height:1.22}
.card__a{font-family:var(--f-body);font-size:var(--t-label);letter-spacing:var(--ctrack);font-weight:500;
         text-transform:uppercase;color:var(--muted);margin:0 0 7px;display:block}
.card__p{font-family:var(--f-body);font-size:var(--t-small);color:var(--ink-2);margin:0}
.card__d{font-family:var(--f-body);font-size:var(--t-minor);line-height:1.55;color:var(--ink-2);margin:0}
/* An exhibition card's second line is the other half of the title, so it does not wear
   the uppercase artist-label dress the work cards use: same face as the line above it,
   a step down in size, in the secondary ink rather than the muted grey. Part of the
   9 August rebalance; the first line gains a step so the pair still ranks. */
.card--ex .card__t{font-size:clamp(19px,1.5vw,22px)}
.card--ex .card__a{font-family:var(--f-display);font-size:clamp(13px,1vw,14px);
                   letter-spacing:-.01em;text-transform:none;color:var(--ink-2)}

/* a single work, given real size */
.work{display:grid;grid-template-columns:1.55fr 1fr;gap:clamp(30px,4.4vw,72px);align-items:start}
/* THE WHOLE WORK, INSIDE THE WINDOW, at first paint. Rule 4.1 of the artist-site
   standard and the one a collector notices: nobody should have to scroll to see the
   bottom of a painting.
   `max-height:76vh` failed it at every laptop height and in landscape, because the plate
   starts about 250px down the page, so 76% of the window measured from the top of the
   window overshot the bottom of the screen by however far down the plate had already
   been pushed. Measured: 16px cut at 1440x900, 44px at 1280x800, 98px in landscape.
   The height is taken from what is left of the window BELOW where the plate begins, so
   the picture fits whatever the header and the breadcrumb above it have used, and the
   hint line under it is counted too. A floor keeps it from collapsing on a short screen,
   where scrolling a little is better than a stamp. */
.work__plate{background:var(--plate);padding:clamp(20px,3vw,52px)}
.work__plate img{width:100%;object-fit:contain;margin:0 auto;cursor:zoom-in;
                 max-height:max(320px, calc(100vh - var(--hdr) - 300px));
                 max-height:max(320px, calc(100dvh - var(--hdr) - 300px))}
@media (max-width:700px) and (min-height:621px){
  .work__plate img{max-height:max(320px, calc(100dvh - var(--hdr) - 190px))}
}
@media (max-height:620px){
  .work__plate img{max-height:max(200px, calc(100dvh - var(--hdr) - 150px))}
  .work__plate{padding:clamp(12px,2vw,24px)}
}
/* A landscape phone is about 390px tall and the floor above overshot it by 33px. The
   order of sacrifice from the standard: the hint goes first, because anyone who has just
   turned their phone sideways to look at a painting does not need to be told they can tap
   it. That plus the padding buys the whole work its room, with no floor to fight. */
@media (max-height:460px){
  /* 112px was the reserve for the breadcrumb and hint above the work. Measured on a
     844x390 landscape phone the real figure is 118.9px, so the bottom of the painting
     was cut at first paint, which is the one thing this rule exists to prevent. */
  .work__plate img{max-height:calc(100dvh - var(--hdr) - 120px)}
  /* The bar is position:fixed, so it is outside the flow and the plate's viewport maths
     cannot see it. The sheet already reserves its height for the footer and lifts the
     review pill clear; the plate needed the same and did not have it, because until now
     the bar had never actually rendered. Measured at 844x390: without this the bar sits
     over the bottom of the painting. 56px is the bar at this height, where its padding
     is halved by the rule below. */
  body:has(.workbar) .work__plate img{max-height:calc(100dvh - var(--hdr) - 120px - 56px)}
  .work__plate{padding:8px}
  .work__plate .viewhint{display:none}
}
.spec{border-top:1px solid var(--rule);margin:0 0 26px}
.spec div{display:grid;grid-template-columns:9.5rem 1fr;gap:14px;padding:11px 0;
          border-bottom:1px solid var(--rule);font-size:var(--t-minor)}
.spec b{font-family:var(--f-body);font-size:var(--t-label);letter-spacing:var(--ctrack);
        text-transform:uppercase;color:var(--muted);font-weight:500;padding-top:3px}
.spec span{color:var(--ink)}
.spec .pending{color:var(--muted)}
.price{font-family:var(--f-display);font-size:var(--t-title);margin:0 0 22px;color:var(--ink)}

/* ---------------- rows ---------------- */
.row{display:grid;grid-template-columns:112px 1fr auto;gap:clamp(18px,2.2vw,34px);align-items:center;
     padding:20px 0;border-bottom:1px solid var(--rule);transition:background .3s var(--ease)}
.row:first-of-type{border-top:1px solid var(--rule)}
.row:hover{background:var(--sunk)}
/* The thumbnail is small, so cropping it to a square was the cheap way to make the
   column line up, and it cut the top and bottom off every landscape painting in the
   archive. The box stays 112px square and the work sits whole inside it, matted on
   the same plate the cards use. */
/* No border. The 21 August pass took the frames off the photographs and this one
   survived on 34 event rows and 22 past-exhibition rows, which is the largest
   remaining population of framed pictures on the site. */
.row img{width:112px;height:112px;object-fit:contain;background:var(--plate);
         }
.row__t{display:block;font-family:var(--f-display);font-size:clamp(18px,1.8vw,25px);
        letter-spacing:-.014em;margin:0 0 5px}
.row__d{display:block;font-family:var(--f-body);font-size:var(--t-meta);letter-spacing:var(--ctrack);
        text-transform:uppercase;color:var(--muted)}
.row__go{font-family:var(--f-body);font-size:var(--t-label);letter-spacing:.15em;text-transform:uppercase;
         font-weight:500;color:var(--muted);white-space:nowrap;display:flex;align-items:center;min-height:44px}
/* The event's own description, under the meta line. The migration dropped every event
   page's copy, so a row said "October 4 . Opening reception" and nothing else; the
   sentence about what actually happens is back, in the body face at reading case. The
   transform and tracking are reset because the line sits beside .row__d, which is
   uppercase, and inheriting either would shout a paragraph. Width is capped at a
   measure, not the grid column, so a long description stays a readable column. */
.row__x{display:block;font-family:var(--f-body);font-size:var(--t-small);line-height:1.55;
        letter-spacing:0;text-transform:none;color:var(--ink);max-width:62ch;margin-top:8px}
.row__x+.row__x{margin-top:6px}
.row:hover .row__go{color:var(--ink)}
.yr{font-family:var(--f-body);font-size:var(--t-label);letter-spacing:.22em;text-transform:uppercase;
    color:var(--muted);font-weight:500;margin:48px 0 14px}
.yr:first-of-type{margin-top:0}

/* The events page's lists, tightened (Robin, 8 August: "reduce space"). Padding drops
   everywhere; the smaller thumbnail only above 860px, because the mobile block below
   already sets its own 80px column and a two-class selector here would beat it by
   specificity from any distance. The 44px row__go target is untouched, so no row can
   compress below a thumb's reach. */
.evlist .row{padding:12px 0}
/* No rule between an events heading and its first event. Jake, 14 August. The heading
   and its count already close the block above; a hairline under them drew a second
   divider a few pixels from the section rule and read as a table of contents. The rules
   BETWEEN events stay, because they are what separates one event from the next. */
.evlist .row:first-of-type{border-top:0}
@media (min-width:861px){
  .evlist .row{grid-template-columns:88px 1fr auto}
  .evlist .row img{width:88px;height:88px}
}

/* The past archive's reveal. A native <details>, because the archive must still open
   with JavaScript unavailable and a <summary> is a control the keyboard reaches on its
   own; a scripted reveal would have been a wall for both. Drawn in the quiet button's
   language so it reads as an act rather than another row, at the full 44px everywhere
   because the go-labels beside it already hold that height. The default triangle comes
   off: the summary swaps its own words by state, and the words say which way it goes. */
.evmore{margin-top:26px}
.evmore__s{display:inline-flex;align-items:center;min-height:44px;cursor:pointer;
           font-family:var(--f-body);font-size:var(--t-label);letter-spacing:.15em;
           text-transform:uppercase;font-weight:500;color:var(--ink);
           list-style:none;border-bottom:1px solid var(--ink);
           transition:color .25s var(--ease),border-bottom-color .25s var(--ease)}
.evmore__s::-webkit-details-marker{display:none}
.evmore__s::marker{content:""}
.evmore__s:hover{color:var(--muted);border-bottom-color:var(--muted)}
.evmore[open] .evmore__s{margin-bottom:14px}
.evmore__hide{display:none}
.evmore[open] .evmore__show{display:none}
.evmore[open] .evmore__hide{display:inline}

/* "Tap the work to view it larger" was shown to everyone, including the desktop visitor
   holding a mouse, who cannot tap anything. The instruction is the same act either way, so
   the page says it in the reader's own word rather than picking one and being wrong half
   the time. Both are in the markup, so a screen reader gets a sentence either way. */
.viewhint__fine{display:none}
@media (pointer:fine){
  .viewhint__coarse{display:none}
  .viewhint__fine{display:inline}
}

.qa{border-top:1px solid var(--rule);padding-top:20px}
/* h2, not h3: these are the page's own sections and the page has one h1 above
   them, so h3 skipped a level for a screen reader walking the outline. */
.qa h2{font-family:var(--f-display);font-weight:400;font-size:clamp(18px,1.7vw,22px);
       letter-spacing:-.014em;line-height:1.2;margin:0 0 10px;color:var(--ink)}
.qa p{margin:0;font-size:var(--t-base);line-height:1.62;color:var(--ink-2)}

.status{display:grid;grid-template-columns:auto 1fr auto;gap:clamp(16px,2.2vw,28px);align-items:center;
        border:1px solid var(--rule);background:var(--sunk);padding:clamp(22px,2.6vw,32px)}
.status__dot{width:9px;height:9px;border-radius:50%;background:var(--muted);flex:0 0 auto;
             box-shadow:0 0 0 5px rgba(99,99,106,.14)}
.status__t{font-family:var(--f-display);font-size:clamp(19px,1.9vw,24px);letter-spacing:-.014em;
           margin:0 0 6px;color:var(--ink)}
.status__d{margin:0;font-size:var(--t-base);line-height:1.6;color:var(--ink-2);max-width:70ch}
@media (max-width:860px){.status{grid-template-columns:auto 1fr;gap:14px}
  .status .btn{grid-column:1 / -1;justify-self:start;margin-top:6px}}

/* ---------------- supporting ---------------- */
/* The gallery's address on the Visit page, given the weight Robin asked for on 8
   August ("highlight the 90 North block info"): display face at display size over a
   heavy rule, leading the column the way a fact row cannot. */
/* The contact rail on Connect: the gallery's address, the submissions notice and the
   90 North box, in the narrow column beside the form rather than stacked under the
   directions. `gap` rather than a margin on each child, so the three read as one rail
   and a fourth block cannot arrive with its own spacing. */
.rail{display:flex;flex-direction:column;gap:28px}
.rail>*{margin-top:0!important}
/* 29 August, the gallery, on Connect: "Make a space between these two blocks".
   
   THE TWO BOXES WERE TOUCHING, exactly as reported, and two rules had to be dead for that
   to happen. `.rail>*{margin-top:0!important}` above kills any margin on a child, so the
   28px the markup asked for never applied. And `.rail{display:block;margin:0}` further
   down this sheet overrides the `display:flex` on line 692, so the `gap` beside it was
   never a gap either: it computes, it just does not draw, because a block box has no gap.
   Measured, not read: the second note's top and the first note's bottom were the same
   pixel, and what looks like a divider between them is their two 1px borders meeting.
   
   Written as `.rail.rail--sep` on purpose. `.rail--sep` alone is the same specificity as
   the `.rail{display:block}` rule that comes later in the file, so it would lose the very
   property it needs. Two classes beats one, wherever either sits. */
.rail.rail--sep{display:flex;flex-direction:column;gap:clamp(40px,4.2vw,60px)}
/* The head of Getting Here: the section title on the left, the gallery's address on the
   right, on one baseline, over the two ways of arriving. The address is set a step under
   the title (21px against 32px) so two lines of the same face at nearly the same size do
   not fight for the same job. */
.gh__head{margin-bottom:clamp(28px,3vw,44px);align-items:baseline}
/* The address, set as a gallery sets an address rather than as an interface sets a label.
   It was 21px at weight 400 beside a 32px heading at weight 300: smaller AND heavier than
   the thing it stood next to, which is why it read as a caption stranded in a wide band.
   It is lighter than the heading now and close to it in size, so the two are told apart by
   voice rather than by scale, and the leading is opened to 1.55 so three short lines read
   as a plaque and not as a paragraph. */
/* Robin asked for this smaller on the morning of 25 August and Jake asked for it larger
   the same evening, and the later instruction is the one that stands. It is the gallery's
   own address on the page whose job is getting somebody to the door, so it is set back up
   as a plaque rather than as another line of prose. */
/* 29 August, the gallery: "make name and address same size as font below". What is below
   is Parking and By Metro-North, which run at --t-body, so that is the size this takes.
   The weight goes up as the size comes down: 200 is a display weight drawn to be seen at
   27px, and at 17px it thins to something a phone loses in daylight. It keeps the display
   face, so it still reads as the plaque it is rather than as one more paragraph. */
.gh__addr{margin:0;font-family:var(--f-display);font-weight:400;
          font-size:var(--t-body);line-height:1.72;letter-spacing:0;
          color:var(--ink);text-wrap:balance}

/* The accessibility line, moved under Parking on 25 August. It is a separate statement
   from the parking directions above it, so it gets a rule and real air rather than
   reading as a fourth sentence about where to leave a car, and it is set at --t-body,
   the size the paragraphs either side of it run at. */
/* The two map links under the address. Quiet, side by side, and each one clears 44px
   because on a phone this is the control somebody taps while walking. */
.gh__maps{display:flex;flex-wrap:wrap;gap:8px 22px;margin:16px 0 0}
.gh__map{font-family:var(--f-body);font-size:var(--t-small);color:var(--ink-2);
         display:inline-flex;align-items:center;min-height:44px;
         text-decoration:underline;text-decoration-thickness:1px;
         text-underline-offset:4px;text-decoration-color:var(--rule-2)}
.gh__map:hover{color:var(--ink);text-decoration-color:var(--ink)}

.gh__ada{margin:26px 0 0;padding-top:22px;border-top:1px solid var(--rule);
         font-size:var(--t-body);line-height:1.72;color:var(--ink-2);text-wrap:pretty}

.facts{border-top:1px solid var(--rule)}
.facts div{display:flex;justify-content:space-between;gap:18px;padding:13px 0;
           border-bottom:1px solid var(--rule);font-size:var(--t-minor)}
.facts b{font-family:var(--f-body);font-size:var(--t-label);letter-spacing:var(--ctrack);
         text-transform:uppercase;color:var(--muted);font-weight:500;padding-top:3px}
.facts span{color:var(--ink);text-align:right}
/* The inquiry form used to hold the wide half of a two-column row, with the "what
   happens next" panel and the gallery facts beside it. Both came off on 14 August, and
   a form stretched across the full measure is a form nobody wants to fill in, so it
   keeps roughly the width it had rather than inheriting the empty column's. */
.form-col{max-width:640px}
/* A list of links with nothing drawn around it. The service pages point at each other
   with one, and a bulleted list would be the only bullet on the site. */
.plainlist{list-style:none;margin:0;padding:0;display:grid;gap:14px;max-width:640px}
.plainlist li{font-family:var(--f-display);font-size:clamp(17px,1.4vw,20px);letter-spacing:-.012em}

/* A card's heading, when the heading is the way in. No rule under it: at 21px in the
   display face an .inline-link border reads as a section divider rather than as a link,
   and the cursor plus the hover shift carry the affordance the way a headline link does
   everywhere else. The whole card is not the target, because the card also holds a
   button going somewhere else. */
.card__t--link a{color:var(--ink);transition:color .3s var(--ease)}
.card__t--link a:hover{color:var(--muted)}

/* A service, on the services page. Six of them are the page's whole middle and they were
   six bare divs: no ground, no boundary, no response to a cursor, on cells whose headings
   became links on 14 August.

   The enclosure is a RULE, not a frame. This site frames exactly one thing, the artwork
   plate, and that frame is legible precisely because nothing else on the page wears one;
   putting a bezel round six paragraphs of consulting copy would spend the gallery's one
   visual claim on its least important content. A hairline over each cell is the same
   vocabulary the facts rows and the listing rows already speak, and it turns the grid
   into six columns rather than six boxes.

   The rule darkens to ink when the thing inside it is actually clickable, which is the
   move `.plate` already makes on the same curve. `:focus-within` carries it for the
   keyboard, so the response is not mouse-only. Nothing moves, because a text cell that
   lifts is a card pretending to be a button. */
/* 29 August, the gallery, twice on the same card: "reduce space". */
.svc{border-top:1px solid var(--rule);padding-top:clamp(14px,1.4vw,20px);
     transition:border-color .45s var(--ease)}
.svc:hover,.svc:focus-within{border-top-color:var(--ink)}
.note{background:var(--sunk);padding:clamp(24px,3vw,38px);border:1px solid var(--rule)}
/* The slab is full width; the sentence inside it is not. Every note on the site measured
   115 characters on a 1440 desktop, which is about forty past the line a reader tracks
   without losing their place, and the worst of them runs 59 words. The box stays the
   width it is, because it is the page's call-out and it reads as one; only the text is
   set to a measure. In ch rather than px so it survives the gallery changing its face
   from the dock. */
.note p{max-width:68ch}
.note p:last-of-type{margin-bottom:18px}
/* The one ask at the foot of a page, as a line and a button rather than a grey slab.
   The past exhibitions asked twice on the way down, once under the dates and once in a
   .note beside the record; both came off on 14 August and this closes the page instead.
   It sits on the paper, so it reads as the end of the page and not as another panel. */
.closer{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
        gap:18px 32px}
.closer__t{margin:0;font-family:var(--f-display);font-size:clamp(19px,1.7vw,23px);
           line-height:1.35;letter-spacing:-.015em;color:var(--ink);max-width:34ch}
.occs{display:flex;flex-wrap:wrap;gap:10px}
.occ{border:1px solid var(--rule);background:var(--plate);padding:13px 21px;font-size:var(--t-base)}
.steps{counter-reset:s;list-style:none;padding:0;margin:0}
.steps li{counter-increment:s;position:relative;padding:0 0 28px 52px;border-left:1px solid var(--rule);
          margin-left:11px}
.steps li:last-child{border-left-color:transparent;padding-bottom:0}
.steps li::before{content:counter(s);position:absolute;left:-11px;top:0;width:22px;height:22px;
                  background:var(--paper);border:1px solid var(--rule-2);border-radius:50%;
                  font-family:var(--f-body);font-size:var(--t-label);display:grid;place-items:center;color:var(--muted)}
.steps h3{font-size:var(--t-lead);margin:0 0 6px}
.steps p{color:var(--ink-2);margin:0;font-size:var(--t-base)}

/* ---------------- footer: the colophon ---------------- */
/* The top padding came down from 96 when the mail plate above the footer was folded in
   (Jake, 9 August: "condense, combine these elements into one footer bar"): the air the
   two slabs carried between them belongs to neither once they are one band. */
/* Very light gray, 25 August, Robin: "can you change the footer background to a very
   light gray to distinguish footer". It was true white against a #fbfbfa page, a half
   step nobody could see. --sunk is the site's own recessed ground rather than a new
   hex, and the footer's smallest type, --muted, clears AA on it at 5.28 to 1. */
.site-foot{background:var(--sunk);border-top:1px solid var(--rule);
           padding:clamp(28px,3vw,42px) 0 clamp(24px,2.6vw,36px);margin-top:0}

/* The first row is the wordmark and the signup, one bar. The signup used to be a
   separate plate stacked above the footer on every page (and the home page's own bar
   in the same position), which read as two footers and ran the foot of the page past
   1,300px; the 9 August condensing put the form here, where Robin had already asked
   for it to be attached, and cut the plate.

   The second condensing, later the same day, is why the form no longer wraps. The
   first build let the fields, the button and the heading wrap independently, so
   between roughly 900 and 1200 the button sat alone under the fields with half a
   row of nothing beside it, and the heading floated centred against no baseline.
   Jake: "cant let the footer break like this based on width. I want it compressed.
   not as tall. distill it down." The form is now one nowrap row that shrinks as a
   unit; when its 560px basis no longer fits beside the wordmark it drops below it
   whole, and under 620 it stacks whole. Three states, no half state between them.
   16px input type stays so an iPhone does not zoom; the button stretches to the
   fields' height so the row has one edge. */
.foot-join{display:flex;flex-wrap:wrap;align-items:center;gap:14px 32px;
           padding-bottom:clamp(16px,1.8vw,24px);border-bottom:1px solid var(--rule)}
.foot-mark{flex:0 0 auto;margin-right:auto}
/* The wordmark stands alone: the sentence that ran under it came off at Robin's
   request, 7 August ("remove this block"). */
.foot-mark img{height:30px;width:auto;display:block}
.foot-join .signup__form{display:flex;flex-wrap:nowrap;align-items:stretch;gap:10px;
                         flex:1 1 560px;max-width:720px;min-width:0}
.foot-join .signup__form input{width:auto}
.foot-join #s-name{flex:1 1 150px;min-width:100px}
.foot-join #s-email{flex:1.4 1 200px;min-width:140px}
.foot-join .signup__form .btn{flex:0 0 auto;white-space:nowrap}
.foot-join .signup__status{flex-basis:100%;margin:0;text-align:right}
/* Under 620 the one-line form can no longer hold usable fields (they bottom out at
   100 and 140px), so the whole thing stacks: full-width name, email, button, in
   that order, nothing orphaned. */
@media (max-width:620px){
  .foot-join .signup__form{flex-direction:column;align-items:stretch;max-width:none}
  /* In a column the fields' flex-basis would become height, and a 200px-tall email
     box is how the first stacked build reached four figures. Auto height here. */
  .foot-join #s-name,.foot-join #s-email{flex:0 0 auto;min-width:0}
  .foot-join .signup__status{text-align:left}
}

/* The facts, one line: address, hours, email, the social marks. They were a 2x2 field
   of labelled columns (Gallery / Hours / Write to us / Follow), and the labels were
   naming things that name themselves: an address is recognisably an address, an email
   is recognisably an email, and the marks are recognisably social links. Cutting the
   label tier took the row from a column grid to a single quiet line, which is where
   most of the 9 August height cut came from. Grid rather than wrapping flex, because
   a wrap would drop the last item alone into a second row; the grid steps whole,
   four across, then two by two, then a single column. */
.foot-facts{display:grid;grid-template-columns:auto auto auto auto;align-items:center;
            justify-content:space-between;gap:14px 28px;
            padding:clamp(14px,1.6vw,20px) 0;border-bottom:1px solid var(--rule)}
.foot-addr{margin:0;font-size:var(--t-base);line-height:1.55;color:var(--ink-2)}
/* The address, the hours and the email are three facts of one kind, so they are set as
   one: the body face at the row's own size. The email had been in the display face a
   step larger, which made it read as a heading for the row rather than a member of it.
   It keeps the darker ink and the rule under it, because it is the only one of the three
   that is a link and has to look like one. overflow-wrap so it can never push the page
   sideways on a narrow phone. */
.foot-email{font-size:var(--t-base);line-height:1.55;color:var(--ink);
            border-bottom:1px solid var(--rule-2);padding-bottom:2px;
            display:inline-block;justify-self:start;
            transition:border-color .2s var(--ease);overflow-wrap:anywhere}
.foot-email:hover{border-bottom-color:var(--ink)}
/* Below 1150 the four facts pair up, address beside hours and email beside the marks,
   because the one-line row needs about 1,000px of content width before the hours
   wrap mid-phrase, and a wrapped opening time reads like two facts. */
@media (max-width:1150px){
  .foot-facts{grid-template-columns:auto auto}
}
/* Below 720 the pairs no longer fit either, so the facts stack singly, in reading
   order, each line whole. */
@media (max-width:720px){
  .foot-facts{grid-template-columns:1fr;gap:11px}
}

/* Instagram and Facebook, back by Robin's request of 7 August: the marks the gallery
   already shows on perrylawsonfineart.com. Inline SVG in currentColor, so they take
   the footer's ink and cost no request. 36px squares clear WCAG 2.5.8's 24px on a
   mouse; the coarse-pointer block below grows them to the full 44. The keyboard ring
   is the sheet's own :focus-visible outline, which reads clearly on the plate. */
.foot-social{display:flex;gap:10px}
.foot-social a{display:inline-flex;align-items:center;justify-content:center;
  width:36px;height:36px;border:1px solid var(--rule-2);color:var(--ink);
  transition:background .18s var(--ease),color .18s var(--ease),border-color .18s var(--ease)}
.foot-social a:hover{background:var(--ink);color:var(--paper);border-color:var(--ink)}
@media (pointer:coarse){.foot-social a{width:44px;height:44px}}

/* credentials. Three marks the gallery did not draw, in three different lockups: a
   wordmark, a stacked block-and-text, and a solid square.
   
   29 August, the gallery: "please make these logos smaller and uniform size". The rule
   that stood here sized each mark on its own axis and argued that this left the row
   optically even without being mechanically equal. The argument is right and the result
   was not: the three marks came out 27px, 71px and 62px tall, a spread of two and a half
   times, which is one small credential standing beside two large ones. That is the thing
   being reported.
   
   So the row is set by HEIGHT now, one number for all three, and the number came down.
   Height and not width, because these are three different shapes and matching widths
   would make the square enormous and the line of type a sliver.
   
   The old comment's warning is kept, because it is true: a solid square and a single line
   of type do not read as equal to an open lockup at the same box height. Both get a
   named reduction below rather than the whole idea being abandoned.

   The numbers were picked off a rendered comparison of the shipped row against 38px, 42px
   and 44px, not off the arithmetic. 42 is the one where every mark comes out the same
   height or SMALLER than it shipped: the two that dominated lose about 40% of their
   height, and the wordmark lands within a pixel of where it already was. At 44 the
   wordmark grows, which answers "uniform" while contradicting "smaller" in the same
   sentence of the same note. */
.creds__row{display:flex;align-items:center;gap:clamp(22px,2.8vw,48px);
            list-style:none;margin:0;padding:0;flex:0 0 auto;--cred-h:42px}
/* Held back by opacity, not by desaturation. Greyscale was the first instinct, since the
   Arts Council's four colours are the only colour anywhere on this page, but greyscaling
   a mark whose whole identity is four coloured squares turns it into four grey squares,
   and a credential a reader cannot identify is not a credential. It sits back at .86 and
   comes fully forward on hover and on keyboard focus instead. */
.creds__m{display:inline-flex;align-items:center;opacity:.86;
          transition:opacity .25s var(--ease)}
/* No hover state any more: these are not links. They stopped being links when it turned
   out none of them could prove what they claim, and a mark that lifts under the pointer
   tells somebody to click a thing that does nothing. */
/* One height, with two optical corrections, both for the same reason: ink, not box.
   
   1stDibs is ONE line of type where the other two stack three, so in an identical box its
   letters come out half again as tall as theirs and it reads as the loudest thing in a
   row of equals. At .72 its cap height matches theirs, which is what an eye compares.
   
   The women art dealers mark is a SOLID black square. A filled shape carries more weight
   than an open one of the same height, which is the swamping the old comment warned
   about. .92 is the smallest correction that answers it while the row still measures as
   one height to anybody checking. */
.creds__m img{width:auto;height:var(--cred-h)}
.creds__m--dibs img{height:calc(var(--cred-h) * .66)}
.creds__m--awad img{height:calc(var(--cred-h) * .90)}
@media (max-width:540px){
  .creds__row{gap:24px;--cred-h:36px}
}
/* One more step at 360, because at 320 the 540 sizes still sum past the 280px of
   content a 320 screen leaves, and the row wrapped its last mark alone. */
@media (max-width:360px){
  .creds__row{gap:16px;--cred-h:31px}
}

/* The base row: affiliations and the legal line share it since the 9 August condensing,
   because each alone was a slim strip with a rule over it, and two strips is how the old
   footer got tall. The relationship sentence that once led the legal came off at Robin's
   request, 8 August ("delete: Perry Lawson Fine Art presents and sells..."). Nowrap at
   full width and stepped by media query below it, because free wrapping is what left
   the legal line alone in a second row with the whole band's width empty beside it. */
.foot-base{display:flex;flex-wrap:nowrap;align-items:flex-start;gap:16px clamp(28px,3.4vw,56px);
           padding-top:clamp(16px,2vw,26px)}
/* The legal flows left after the marks rather than sitting flush right, because the
   review launcher is fixed at the lower right corner and a right-aligned last line
   sat exactly under it. The lower right of this footer stays empty on purpose.
   Top-aligned, not centred, for the same launcher: centring dropped the one-line
   submissions link into the pill's band whenever the legal beside it ran taller,
   measured as a 10 to 27px overlap between 680 and 1340. Hung from the row's top
   line, the link clears the pill at every width the sweep drives. */
.legal{margin:0;font-size:var(--t-small);line-height:1.6;color:var(--muted);max-width:52ch}
/* The base row's one utility link, the way in for artists. It holds the legal line's
   size and ink so it cannot compete with the signup or the marks above it, and keeps
   an underline so it still declares itself a link; the 44px touch height rides the
   .foot-base a rule with every other footer link. */
/* The underline is drawn by text-decoration rather than a bottom border so the link can
   carry vertical padding without the rule sliding away from the word. It needed the
   padding: at 14px the box came out 23px tall on a mouse, one pixel under WCAG 2.2 AA's
   24px minimum target, on every page of the site. Touch was never affected, since
   .foot-base a already holds these to 44px there. */
.foot-note{font-size:var(--t-meta);color:var(--muted);white-space:nowrap;
           /* 12.5px from 25 August, Robin, "make these links smaller". The padding goes
              up as the type comes down, for the reason directly above: the box, not the
              type, is what has to clear 24px. 12.5px sets a 15px line box, so 5px a side
              lands at 25px rather than the 23px that was already a pixel short. */
           display:inline-block;padding-block:5px;
           text-decoration:underline;text-decoration-thickness:1px;
           text-underline-offset:3px;text-decoration-color:var(--rule-2)}
.foot-note:hover{color:var(--ink);text-decoration-color:var(--ink)}
/* Below 1100 the three marks take their own line and the legal and the submissions
   link share the next; below 640 those two stack as well. Whole rows at every step. */
@media (max-width:1100px){
  .foot-base{flex-wrap:wrap}
  .creds__row{flex-basis:100%}
}
@media (max-width:640px){
  .legal{flex-basis:100%}
}
/* Two lifts for the same fixed pill. On a coarse pointer the submissions link grows
   to a 44px target, deep enough to reach back down into the pill's band, so the row
   ends 16px earlier. Under 380 the link's own line is all the row has left and the
   pill's x-range reaches it, so the row ends high enough to pass over the pill
   rather than beside it. The 380 rule is written after the coarse one because a
   320px phone is both, and needs the larger of the two. */
@media (pointer:coarse){
  .foot-base{margin-bottom:16px}
}
@media (max-width:380px){
  .foot-base{margin-bottom:34px}
}


/* ---------------- QR wall label ---------------- */
.qr{display:flex;gap:18px;align-items:center;margin:30px 0 0;padding:18px;
    background:var(--sunk);border:1px solid var(--rule)}
.qr img{width:112px;height:112px;flex:0 0 auto;background:#fff;padding:6px;border:1px solid var(--rule)}
.qr p{margin:0;font-size:var(--t-minor);color:var(--ink-2);line-height:1.5}
@media (max-width:540px){.qr{flex-direction:column;text-align:center}}

/* ---------------- form ---------------- */
.form{max-width:46rem}
.form__plate{background:var(--plate);border:1px solid var(--rule);
             padding:clamp(24px,3vw,36px);margin:0 0 18px}
.form__plate--quiet{background:var(--sunk)}
/* deliberately no <legend>: it renders on the fieldset border and refuses to shrink
   below min-content. A labelled paragraph plus aria-labelledby keeps the semantics. */
.form__step{font-family:var(--f-body);font-size:var(--t-label);letter-spacing:var(--ctrack);
            text-transform:uppercase;color:var(--muted);font-weight:500;margin:0 0 24px;
            padding-bottom:14px;border-bottom:1px solid var(--rule);width:100%}
.field{margin:0 0 26px;border:0;padding:0;min-width:0}
/* a fieldset will not shrink below min-content unless told to */
fieldset{min-width:0}
.check span{min-width:0}
.form__plate .field:last-of-type{margin-bottom:0}
.field>label,.fld>label{display:block;font-family:var(--f-body);font-size:var(--t-small);letter-spacing:0;
             text-transform:none;color:var(--ink);font-weight:500;margin:0 0 10px}
.req{text-transform:uppercase;letter-spacing:.12em;font-weight:500;color:var(--muted);
     font-size:var(--t-micro);margin-left:9px;vertical-align:1px}
/* `tel` joined this list on 1 September. It was never in it, so the phone field on the
   accepted-artist form rendered as a bare browser input: half the height of the email
   box beside it, no plate, no border of ours. Nothing was broken enough to fail a test,
   it just looked like somebody else's form had been pasted in. A selector that lists
   input types by hand is a selector that goes stale the first time a new one is used. */
.field input[type=text],.field input[type=email],.field input[type=tel],.field select,.field textarea{
  display:block;width:100%;font:inherit;font-size:var(--t-body);color:var(--ink);background:var(--paper);
  border:1px solid var(--rule-2);padding:14px 16px;min-height:54px;
  transition:border-color .2s var(--ease),background .2s var(--ease)}
.field textarea{min-height:140px;resize:vertical;line-height:1.55}
.field select{appearance:none;cursor:pointer;
  background-image:linear-gradient(45deg,transparent 50%,var(--muted) 50%),linear-gradient(135deg,var(--muted) 50%,transparent 50%);
  background-position:calc(100% - 22px) 24px,calc(100% - 16px) 24px;background-size:6px 6px;background-repeat:no-repeat}
.field input:focus,.field select:focus,.field textarea:focus{border-color:var(--ink);background:var(--plate)}
.field input:focus-visible,.field select:focus-visible,.field textarea:focus-visible{
  outline:2px solid var(--ink);outline-offset:2px}
.field input::placeholder,.field textarea::placeholder{color:var(--muted);opacity:1}
.field input[aria-invalid=true],.field textarea[aria-invalid=true]{border-color:#8f2118;border-width:2px}
.field--bad>label{color:#8f2118}
.hint{font-size:var(--t-minor);color:var(--muted);margin:10px 0 0;line-height:1.55}

.check{display:flex;gap:14px;align-items:flex-start;font-size:var(--t-base);color:var(--ink-2);
       text-transform:none;letter-spacing:0;font-weight:400;margin:0 0 12px;
       cursor:pointer;line-height:1.55}
.check span{text-transform:none;letter-spacing:0}
.check input{margin:3px 0 0;width:19px;height:19px;flex:0 0 auto;accent-color:var(--ink);cursor:pointer}
.check--lead{font-size:var(--t-body);color:var(--ink)}
.checks{display:grid;grid-template-columns:repeat(2,1fr);gap:2px 28px;margin-top:10px}
.checks .check{margin:0;min-height:44px;align-items:center;font-size:var(--t-base)}
@media (max-width:640px){.checks{grid-template-columns:1fr}}

.form__send{display:flex;align-items:center;gap:24px;flex-wrap:wrap;margin-top:28px}

/* The honeypot. Off-screen rather than display:none, because some form-fillers skip a
   field they can see is hidden and fill one they cannot. Out of the tab order and out of
   the accessibility tree by virtue of being unreachable, so a person never meets it. */
.hp{position:absolute;left:-9999px;top:auto;width:1px;height:1px;overflow:hidden}

/* A send that failed says so in the ink the rest of the form uses for a problem, not in a
   red banner. The message beside the button is already a live region. */
.hint--bad{color:#8f2118}

/* What stands where the form stood. The plate is the same sunk panel the aside uses, so
   the page does not change texture at the moment it confirms something. */
.form__done{background:var(--sunk);border:1px solid var(--rule);
            padding:clamp(26px,3.2vw,38px)}
.form__done:focus{outline:none}
.form__done:focus-visible{outline:2px solid var(--ink);outline-offset:3px}
.form__done p{margin:0 0 10px;color:var(--ink-2);font-size:var(--t-minor)}
.form__done p:last-child{margin-bottom:0}
.form__done-t{font-family:var(--f-display);font-size:var(--t-lead);color:var(--ink);
              line-height:1.3;margin-bottom:14px}
.btn:disabled{opacity:.55;cursor:default}
.btn--lg{min-height:56px;padding:0 40px;font-size:var(--t-meta)}

.aside{background:var(--sunk);border:1px solid var(--rule);padding:clamp(24px,3vw,34px)}
.aside__h{font-family:var(--f-body);font-weight:500;font-size:var(--t-label);letter-spacing:var(--ctrack);
          text-transform:uppercase;color:var(--muted);margin:0 0 24px}
.steps--tight li{padding-bottom:22px}
.steps--tight h3{font-size:var(--t-body)}
.steps--tight p{font-size:var(--t-minor)}

/* ---------------- the work viewer ----------------
 *
 * Rebuilt 1 September. It was a dark overlay with a one-line caption; it is now the
 * surface Carole asked for, carrying what their Artwork Archive embed carried: the
 * record, the artist's biography, View All, Next through the artist's collection, and
 * Inquire and Purchase as forms that send.
 *
 * THREE PARTS, AND ON A PHONE ONLY ONE OF THEM SCROLLS. The work is held at the top, the
 * record and biography scroll under it, and the two actions sit in a bar pinned above the
 * home indicator. Picked off a rendered board of five constructions: it is the only one
 * where the painting never leaves the screen and buying is never more than one thumb
 * reach away, which is the entire argument for it on a 402px screen.
 *
 * On a desktop the same three parts run side by side and nothing is pinned, because a bar
 * fixed across a 1400px window is a phone idea wearing a desktop costume.
 *
 * Light ground, not the dark overlay it replaced. A dark sheet is right for a picture and
 * wrong for two forms, a price and 120 words of biography, which is most of what is on
 * this surface now. The backdrop stays dark so the page behind it goes away. */
.lb{border:0;padding:0;background:transparent;overflow:visible;
    width:100vw;max-width:100vw;height:100vh;height:100dvh;max-height:100dvh;margin:0}
.lb::backdrop{background:rgba(12,12,13,.92)}

/* The arrival, chosen at the gate: the work rises and settles, the record follows just
   behind it. 260ms on the picture because that is about where a movement stops reading as
   a transition and starts reading as a delay. */
@keyframes lb-arrive{from{opacity:0;transform:translateY(10px) scale(.985)}
                     to{opacity:1;transform:none}}
@keyframes lb-rec{from{opacity:0;transform:translateY(7px)} to{opacity:1;transform:none}}
@keyframes lb-sheet{from{opacity:0;transform:translateY(14px)} to{opacity:1;transform:none}}
.lb[open] .lb__sheet{animation:lb-sheet .26s var(--ease) both}
.lb__img.is-arriving{animation:lb-arrive .26s cubic-bezier(.2,.7,.3,1) both}
.lb[open] .lb__rec{animation:lb-rec .3s .06s var(--ease) both}
@media (prefers-reduced-motion:reduce){
  .lb[open] .lb__sheet,.lb__img.is-arriving,.lb[open] .lb__rec{animation:none}
}

.lb__sheet{position:relative;background:var(--paper);color:var(--ink);
           height:100%;display:flex;flex-direction:column;overflow:hidden}

/* Held. Does not scroll, does not shrink below its share, and never grows past 44% of the
   screen so the record underneath is not a rumour. */
.lb__stage{position:relative;flex:0 0 auto;max-height:44dvh;background:var(--sunk);
           border-bottom:1px solid var(--rule);
           padding:calc(env(safe-area-inset-top,0px) + 58px) 22px 20px;
           display:flex;align-items:center;justify-content:center}
.lb__img{display:block;max-width:100%;max-height:100%;width:auto;height:auto;
         object-fit:contain;box-shadow:0 1px 2px rgba(0,0,0,.10),0 10px 26px rgba(0,0,0,.13)}

.lb__scroll{flex:1 1 auto;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;
            overscroll-behavior:contain;padding:24px 22px 26px}
.lb__rec{margin:0 0 20px}
.lb__artist{margin:0;font-family:var(--f-display);font-weight:500;font-size:17px;
            letter-spacing:-.005em;color:var(--ink)}
.lb__artist[hidden]{display:none}
.lb__t{margin:2px 0 0;font-family:var(--f-display);font-weight:300;font-style:italic;
       font-size:clamp(21px,5.4vw,26px);letter-spacing:-.01em;line-height:1.2;color:var(--ink)}
.lb__spec{margin:11px 0 0;font-size:var(--t-body);line-height:1.6;color:var(--ink-2)}
.lb__spec[hidden]{display:none}
.lb__price{margin:12px 0 0;font-family:var(--f-display);font-size:20px;color:var(--ink)}
.lb__price[hidden]{display:none}

.lb__bio{margin:24px 0 0;padding-top:20px;border-top:1px solid var(--rule)}
.lb__bio[hidden]{display:none}
.lb__bioh{margin:0 0 10px;font-size:var(--t-label);letter-spacing:var(--ctrack);
          text-transform:uppercase;color:var(--muted);font-family:var(--f-body);font-weight:500}
/* 16px, like every other block of reading on the site. A biography set at 13 because it is
   "secondary" is a biography nobody reads on a phone. */
.lb__biot p{margin:0 0 12px;font-size:var(--t-body);line-height:1.7;color:var(--ink-2);text-wrap:pretty}
.lb__biot p:last-child{margin-bottom:0}

.lb__walk{display:flex;align-items:center;justify-content:space-between;gap:12px;
          margin:24px 0 0;padding-top:16px;border-top:1px solid var(--rule)}
/* min-width as well as min-height. "Next" is a short word and came out 43px wide, one
   pixel under the floor, on all thirteen geometries. A target is a box, and checking only
   its height passes half of it. */
.lb__walk button,.lb__walk a{background:transparent;border:0;padding:12px 8px;
          min-height:44px;min-width:44px;justify-content:center;
          display:inline-flex;align-items:center;font-family:var(--f-body);
          font-size:var(--t-label);letter-spacing:var(--ctrack);text-transform:uppercase;
          color:var(--ink-2);text-decoration:none;cursor:pointer}
.lb__walk button:hover,.lb__walk a:hover{color:var(--ink)}
.lb__walk [hidden]{display:none}
.lb__all{text-decoration:underline;text-underline-offset:4px;text-decoration-color:var(--rule-2)}

/* Pinned, and clear of the home indicator. Two actions, equal weight in size and unequal
   in emphasis, because Inquire is the one most people want and Purchase is the one the
   gallery wants to be possible. */
.lb__bar{flex:0 0 auto;display:flex;gap:10px;background:var(--plate);
         border-top:1px solid var(--rule);
         padding:13px 22px calc(13px + env(safe-area-inset-bottom,0px))}
.lb__bar .btn{flex:1;min-height:48px;display:inline-flex;align-items:center;justify-content:center}

.lb__close{position:absolute;z-index:6;
           top:calc(env(safe-area-inset-top,0px) + 12px);right:14px;
           width:44px;height:44px;border-radius:50%;border:1px solid var(--rule);
           background:rgba(255,255,255,.94);color:var(--ink);cursor:pointer;
           display:flex;align-items:center;justify-content:center;padding:0}
.lb__close svg{width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round}
.lb__close:hover{background:#fff;border-color:var(--rule-2)}

.lb__nav{position:absolute;top:50%;transform:translateY(-50%);z-index:5;
         width:44px;height:44px;border-radius:50%;border:1px solid var(--rule);
         background:rgba(255,255,255,.9);color:var(--ink);cursor:pointer;padding:0;
         display:flex;align-items:center;justify-content:center;opacity:.9}
.lb__nav svg{width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:1.6;
             stroke-linecap:round;stroke-linejoin:round}
.lb__nav:hover{opacity:1;background:#fff}
.lb__nav[hidden]{display:none}
.lb__prev{left:10px}.lb__next{right:10px}

/* ---- the two forms, expanded in place under the record ---- */
.lbf{margin:20px 0 0;padding-top:20px;border-top:1px solid var(--rule)}
.lbf[hidden]{display:none}
.lbf__lead{margin:0 0 16px;font-size:var(--t-small);line-height:1.6;color:var(--muted);max-width:56ch}
.lbf__row{margin:0 0 14px;display:flex;flex-direction:column}
.lbf__row label{font-size:var(--t-label);letter-spacing:var(--ctrack);text-transform:uppercase;
                color:var(--muted);margin-bottom:6px;font-weight:500}
.lbf__row .req{letter-spacing:.06em;text-transform:none;color:var(--rule-2)}
/* 16px is not a taste decision. Under it, iOS zooms the whole page the moment the field
   takes focus and the visitor is left pinched in on a form they now have to scroll
   sideways. Every input on this site clears it and these do too. */
.lbf__row input,.lbf__row textarea{font:400 16px/1.5 var(--f-body);color:var(--ink);
   background:var(--plate);border:1px solid var(--rule);border-radius:0;
   padding:12px 13px;min-height:48px;width:100%;-webkit-appearance:none;appearance:none}
.lbf__row textarea{min-height:88px;resize:vertical}
.lbf__row input:focus-visible,.lbf__row textarea:focus-visible{outline:2px solid var(--ink);
   outline-offset:1px;border-color:var(--ink)}
.lbf__send{margin:18px 0 0;display:flex;flex-wrap:wrap;align-items:center;gap:12px}
.lbf__send .btn{min-height:48px}
.lbf__status{font-size:var(--t-small);line-height:1.5;color:var(--ink-2);flex:1 1 14ch}
.lbf__status a{color:var(--ink)}

@media (min-width:620px){
  .lbf__row--half{width:calc(50% - 7px);display:inline-flex;vertical-align:top}
  .lbf__row--half + .lbf__row--half{margin-left:14px}
}

/* ---- desktop: side by side, nothing pinned ---- */
@media (min-width:900px){
  /* [open], and it has to be. An author `display` on a <dialog> beats the UA's
     `dialog:not([open]){display:none}`, so an unscoped `.lb{display:flex}` here left the
     CLOSED lightbox rendered on every viewport at or above 900px: a 900px empty panel
     below the footer on four page types, 22 keyboard tab stops inside a dialog nobody
     opened, and an empty <h2> sitting in the accessibility tree. It was invisible below
     900px, which is why it survived the phone passes. `showModal()` sets [open], so the
     open layout is unchanged. */
  .lb[open]{display:flex;align-items:center;justify-content:center;padding:34px}
  .lb__sheet{height:min(880px,calc(100dvh - 68px));width:min(1180px,100%);
             border-radius:2px;flex-direction:row;
             box-shadow:0 24px 70px rgba(0,0,0,.34)}
  .lb__stage{flex:1 1 58%;max-height:none;border-bottom:0;border-right:1px solid var(--rule);
             padding:34px}
  .lb__scroll{flex:1 1 42%;max-width:520px;padding:38px 36px 34px}
  /* The actions ride at the top of the reading column and stay put as the biography
     scrolls under them, which is the desktop answer to a pinned bar. */
  .lb__bar{position:sticky;bottom:0;order:0;background:linear-gradient(to top,var(--paper) 72%,rgba(251,251,250,0));
           border-top:0;padding:0}
  .lb__sheet{display:grid;grid-template-columns:1fr minmax(380px,470px);grid-template-rows:1fr auto}
  .lb__stage{grid-column:1;grid-row:1 / span 2}
  .lb__scroll{grid-column:2;grid-row:1}
  .lb__bar{grid-column:2;grid-row:2;padding:14px 36px 30px;border-top:1px solid var(--rule);
           background:var(--plate)}
  .lb__close{top:14px;right:14px}
}

/* A landscape phone has almost no height. The work gives up most of it rather than
   squeezing the record into a slot nothing can be read in. */
@media (max-height:520px) and (max-width:899px){
  .lb__stage{max-height:52dvh;padding:calc(env(safe-area-inset-top,0px) + 46px) 16px 12px}
  .lb__scroll{padding:16px 18px 18px}
  .lb__bar{padding:10px 18px calc(10px + env(safe-area-inset-bottom,0px))}
  .lb__bar .btn{min-height:44px}
}

/* ---------------- responsive ---------------- */
@media (pointer:coarse){
  /* quiet links stay visually tight to the text; the hit area grows behind them */
  .btn--quiet,.facts .inline-link,.spec .inline-link,nav.caps .inline-link{position:relative}
  .btn--quiet::after,.facts .inline-link::after,.spec .inline-link::after,nav.caps .inline-link::after{
    content:"";position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);
    height:44px;min-width:44px}
  .nav a{min-height:44px;display:flex;align-items:center}
  .foot a{min-height:44px;display:flex;align-items:center}
  .brand{min-height:44px;display:flex;align-items:center}
  .navtoggle{min-height:44px}
  nav.caps a{min-height:44px;display:inline-flex;align-items:center;padding-right:8px}
  /* The three affiliation marks sit outside .foot, so the rule above never reached them and
     they were 22px tall on every phone. The hit area grows; the mark itself does not, because
     these are supplied logos at fixed widths and scaling them up would coarsen them. */
  .creds__m{min-height:44px}
}
@media (max-width:1080px){
  .g4{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:860px){
  :root{--hdr:75px}
  .site-head__in{flex-wrap:wrap;gap:14px;padding:15px var(--gut)}
  /* 44px on every pointer, not only coarse. The Inquire button used to be the 44px
     element that made this header 75px tall; when Robin removed it the toggle became
     the tallest thing in the row, and on a mouse it measured 39px, which left the
     header at 69px while --hdr promised 75 and the hero stopped 6px short of the
     fold. The toggle is the one control this layout always shows, so it carries the
     height on both pointers and the variable is true again. */
  .navtoggle{display:block;margin-left:auto;min-height:44px}
  .nav{display:none;width:100%;flex-direction:column;gap:0;border-top:1px solid var(--rule);padding-top:6px}
  .nav.open{display:flex}
  .nav a{padding:12px 0;font-size:var(--t-meta)}
  /* "You are here", not "a new group starts here". Stacked, .nav a is a full width row,
     so the desktop underline became a 353px ink rule spanning the whole menu, identical
     to the divider above the list and the one under it. Weight and full ink say the same
     thing without drawing a line the width of the panel. */
  .nav a[aria-current]{border-bottom-color:transparent;font-weight:600}
  /* Stacked, a folder is a heading with its pages indented under it rather than a
     panel floating over the page it is sitting on. */
  .nav__folder{display:block;width:100%}
  .nav__top{width:100%;text-align:left;padding:12px 0;font-size:var(--t-meta);min-height:44px}
  .nav__sub{position:static;opacity:1;visibility:visible;transform:none;border:0;
            min-width:0;padding:0 0 6px 16px;gap:0;display:none}
  .nav__top[aria-expanded="true"]+.nav__sub{display:flex}
  .cols,.cols--flip,.cols--even,.work{grid-template-columns:1fr}
  .cols--flip>:first-child{order:0}
  .g3,.g2{grid-template-columns:repeat(2,1fr)}
  .row{grid-template-columns:80px 1fr;align-items:start}
  .row img{width:80px;height:80px}
  .row__go{grid-column:2;margin-top:4px}
  .spec div{grid-template-columns:1fr;gap:2px}
  /* The footer's own phone steps live with the rest of its rules in the colophon
     section, so its wrap behaviour reads as one story in one place. */
  .occ,.card__d,.facts div{font-size:var(--t-base)}
}
@media (max-width:540px){
  .g4,.g3,.g2{grid-template-columns:1fr}
  /* Except a grid of works. Robin Reynolds holds twenty, and one to a row would be
     twenty screens: the reader loses the ability to see how big the body of work is,
     which is the whole job of the grid. Two across, shelf and label intact. */
  .grid--works.g4,.grid--works.g3,.grid--works.g2,
  .wk-grid.g4,.wk-grid.g3,.wk-grid.g2{grid-template-columns:repeat(2,1fr)}
  .hero__title{font-size:clamp(30px,8.8vw,42px)}
  .hero__sub--title{font-size:clamp(19px,5.4vw,26px)}
  .steps li{padding-left:40px}
}
@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}

/* ================= open call: rule lists and open status ================= */
/* 34em, not 86ch. `ch` is the width of a zero, so 86ch measured 909px and rendered
   about 107 characters a line: the eligibility terms, the one text on this site an
   artist has to read word for word, were the only overset block on it. */
.rules{list-style:none;margin:0;padding:0;max-width:34em;border-top:1px solid var(--rule)}
.rules li{position:relative;padding:16px 0 16px 34px;border-bottom:1px solid var(--rule);
          color:var(--ink-2);line-height:1.55}
.rules li::before{content:"";position:absolute;left:6px;top:27px;width:12px;height:1px;
                  background:var(--rule-2)}
.status--open .status__dot{background:var(--ink)}

/* ================= home hero, six directions =================
   Review tool. `data-hero` on <html> selects the direction; `current` is the
   shipped design and the default. Remove this block, the switcher and the extra
   font families once one direction is locked. */
/* A hard guard, kept even though the picture fix above removes the cause: a hero whose
   artwork is its background must never be able to paint outside itself, whatever a future
   image rule does. The scrim is inset:0 on this same box, so it is clipped with it. */
.hero--home{position:relative;border-bottom:0;display:flex;flex-direction:column;overflow:hidden}
/* Source order is head, media, meta. Each direction places them itself; without this
   the artwork lands under the title in every image-first direction. */
[data-hero="vitrine"] .hero--home .hero__media,
[data-hero="diptych"] .hero--home .hero__media,
[data-hero="card"]    .hero--home .hero__media{order:1}
[data-hero="vitrine"] .hero--home .hero__head,
[data-hero="diptych"] .hero--home .hero__head,
[data-hero="card"]    .hero--home .hero__head{order:2}
[data-hero="vitrine"] .hero--home .hero__meta,
[data-hero="diptych"] .hero--home .hero__meta,
[data-hero="card"]    .hero--home .hero__meta{order:3}
[data-hero="horizon"] .hero--home .hero__head{order:1}
[data-hero="horizon"] .hero--home .hero__meta{order:2}
[data-hero="horizon"] .hero--home .hero__media{order:3}
.hero--home .hero__img2{display:none}
.hero--home .hero__head,.hero--home .hero__meta{max-width:var(--maxw);margin:0 auto;
                                                padding-left:var(--gut);padding-right:var(--gut)}
.hero--home .hero__title{margin:0}
.hero--home .hero__sub{margin:0 0 14px}
.hero--home .hero__dates{margin:0 0 30px}

/* ---- 1 current: cinematic full bleed, copy over a scrim ---- */
/* The media is the backdrop and the copy stacks on top of it in normal flow. Positioning
   head and meta separately against the bottom edge made their overlap depend on guessing
   how tall the meta block is, which it never reliably is. */
/* The hero fills the window, and the header is what it has to fill around. `88dvh` was
   never the window and the `880px` cap was never anything: on a 1600x900 laptop the
   picture stopped 108px short of the fold, and on a landscape phone, where the header
   costs 111px of 430, the type block finished 59px BELOW it, so the dates and the call
   to action were off-screen on the one geometry with no room to spare. Both numbers go.
   `vh` first for anything that predates `dvh`, `min-height` never `height` so a short
   window grows the section rather than cropping the type, and the ladder at 620/460
   steps the type back so growing is rare. */
[data-hero="current"] .hero--home{min-height:calc(100vh - var(--hdr));
                                  min-height:calc(100dvh - var(--hdr));
                                  justify-content:flex-end}
[data-hero="current"] .hero--home .hero__media{position:absolute;inset:0;z-index:0}
[data-hero="current"] .hero--home .hero__media picture{height:100%}
[data-hero="current"] .hero--home .hero__media img{width:100%;height:100%;object-fit:cover}
/* The scrim is measured, not eyeballed: it is the only thing standing between the type
   and whatever the photograph happens to be doing behind it. The eyebrow sits highest of
   the four lines and came in at 3.47:1 on a wide screen, under the 4.5 an 11px line needs,
   because the 58% stop had faded to .22 exactly where the smallest text sits. Deepening
   the middle of the ramp buys the eyebrow its contrast without flattening the picture,
   which is what raising the bottom stop would have done. */
/* The stops are in pixels, not percentages, and that is the whole point. A percentage
   ramp is measured against the hero, and the hero is not a fixed height: the copy block
   is roughly the bottom third of a 819px desktop hero and roughly the whole of a 315px
   landscape-phone one. So the same gradient that measured 5.4:1 on the eyebrow at
   1440x900 measured 1.14:1 at 844x390, because at that height the eyebrow had risen into
   the part of the ramp that has already faded out. Pixel stops do not move when the hero
   does. The four values are the old percentages resolved against the desktop hero, so
   the wide view is unchanged and only the short ones gain darkness, which is the only
   place any was missing. */
/* Rebuilt 1 September. Carole: "it seems a little dark", and then the reason, which
   is the one that matters: "I wonder if some of the artists are gonna be like, my
   painting's all dark". The scrim was a full width ramp, so it dimmed the whole bottom
   half of the picture in order to seat four lines of type in the bottom LEFT corner.
   Every painting the gallery leads with paid for that, across its whole width.
   It is two layers now. An ellipse anchored to the bottom left carries the contrast,
   sized in pixels for the same reason the old ramp's stops were: a percentage is
   measured against the hero, and the hero is 819px on a desktop and 315px on a
   landscape phone, so a percentage ellipse would drift off the type exactly where
   there is least room. Under it a much lighter full width ramp seats the composition.
   Where they overlap, bottom left, the two compose to about .84 against the old .86, so
   the type keeps its measured backing. Away from the type, on the right of the frame,
   the picture carries about .42 where it used to carry .86. That is the painting the
   gallery is showing, at close to its own value.

   THE ELLIPSE'S STOPS ARE PERCENTAGES AND THE RAMP'S ARE PIXELS, and mixing the two in
   one rule is not an oversight. A radial gradient's ray is horizontal, so a stop written
   in pixels is measured against the HORIZONTAL radius and then scaled down the vertical
   one: written in pixels against a 1150 by 660 ellipse, a stop meant to land 200px above
   the bottom edge lands at 115px, and the wash under the type had fallen to a third of
   its intended value before the eyebrow. Measured on the pale Next Gesture bouquet it
   put the eyebrow at 1.8:1 where AA wants 4.5. A percentage is the same fraction of the
   ellipse in every direction, which is what "660px of darkness above the bottom edge"
   actually means. The linear ramp underneath has no such trap and keeps its pixel stops
   for the reason the old comment gives: the hero is 819px on a desktop and 279px on a
   landscape phone, and a percentage there moves with it. */
[data-hero="current"] .hero--home::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:1;
  background:
    radial-gradient(ellipse 1250px 900px at 0% 100%,
      rgba(10,10,12,.80) 0%,rgba(10,10,12,.74) 30%,rgba(10,10,12,.60) 45%,
      rgba(10,10,12,.34) 70%,rgba(10,10,12,0) 100%),
    linear-gradient(to top,rgba(10,10,12,.42) 0px,rgba(10,10,12,.30) 230px,
      rgba(10,10,12,.14) 430px,rgba(10,10,12,0) 620px)}
/* The faint edge on the characters themselves, which is the other half of what was
   asked for: "just a border around the actual characters", and immediately after it the
   constraint, "faint, nothing that's gonna stand out visually". It is doing real work
   rather than decorating. A shadow travels with the type, so the smallest line keeps its
   separation over whatever part of the painting it happens to land on, which is what
   lets the wash above be lighter than it was. */
[data-hero="current"] .hero--home .hero__head,
[data-hero="current"] .hero--home .hero__meta{
  text-shadow:0 1px 2px rgba(10,10,12,.55),0 0 22px rgba(10,10,12,.38)}
[data-hero="current"] .hero--home .hero__head{position:relative;z-index:2;order:1}
[data-hero="current"] .hero--home .hero__meta{position:relative;z-index:2;order:2;padding-bottom:44px}
/* Full white, not .86 of it. The transparency bought nothing a reader could see and
   cost the smallest line on the page its legibility; the hierarchy here is carried
   by size and tracking, which is where it belongs. */
[data-hero="current"] .hero--home .hero__eyebrow{color:#fff}
[data-hero="current"] .hero--home .hero__title{color:#fff}
/* .92, up from .84: at title scale the second line is half the title, and half the
   title does not get to be a quarter dimmer than the line above it. */
[data-hero="current"] .hero--home .hero__sub{color:rgba(255,255,255,.92)}
[data-hero="current"] .hero--home .hero__dates{color:rgba(255,255,255,.74)}
[data-hero="current"] .hero--home .btn--solid{background:transparent;border:1px solid rgba(255,255,255,.6);color:#fff}
[data-hero="current"] .hero--home .btn--solid:hover{background:#fff;color:var(--ink)}
/* The ladder. Keyed to height, because width says nothing about how much room is left
   above the fold. Nothing is dropped: on a gallery's home page the second line is the
   two artists' names and the third is the run of the show, and an artist's name is not
   a thing to sacrifice for a landscape phone. Type and padding step back instead, and
   the call to action neither shrinks below its touch target nor moves. */
@media (max-height:620px){
  [data-hero="current"] .hero--home .hero__title{font-size:clamp(30px,5.2vw,54px)}
  [data-hero="current"] .hero--home .hero__sub{font-size:clamp(18px,3.2vw,33px);margin-bottom:8px}
  [data-hero="current"] .hero--home .hero__dates{margin-bottom:20px}
  [data-hero="current"] .hero--home .hero__meta{padding-bottom:28px}
}
@media (max-height:460px){
  [data-hero="current"] .hero--home .hero__eyebrow{margin-bottom:8px}
  [data-hero="current"] .hero--home .hero__title{font-size:clamp(26px,4.6vw,40px)}
  [data-hero="current"] .hero--home .hero__sub{font-size:clamp(16px,2.8vw,24px);margin-bottom:6px}
  [data-hero="current"] .hero--home .hero__dates{margin-bottom:16px}
  [data-hero="current"] .hero--home .hero__meta{padding-bottom:20px}
}

/* ---- 2 vitrine: the work whole on true white, quiet centred type ---- */
[data-hero="vitrine"] .hero--home{border-bottom:1px solid var(--rule)}
[data-hero="vitrine"] .hero--home .hero__media{background:var(--plate);
  border-bottom:1px solid var(--rule);padding:clamp(40px,6vw,86px) var(--gut)}
[data-hero="vitrine"] .hero--home .hero__media img{margin:0 auto;width:auto;
  max-height:min(56vh,540px);object-fit:contain}
[data-hero="vitrine"] .hero--home .hero__head{text-align:center;padding-top:clamp(38px,5vw,64px)}
[data-hero="vitrine"] .hero--home .hero__meta{text-align:center;padding-bottom:clamp(46px,6vw,76px)}
[data-hero="vitrine"] .hero--home .hero__title{font-family:"Marcellus",Georgia,serif;
  font-size:clamp(32px,4.6vw,60px);letter-spacing:.005em;line-height:1.1;margin:20px 0 16px}
[data-hero="vitrine"] .hero--home .hero__sub{font-family:"Marcellus",Georgia,serif;
  max-width:none;letter-spacing:.01em}

/* ---- 3 broadsheet: title at newspaper scale, facts in a rail ---- */
[data-hero="broadsheet"] .hero--home{display:grid;
  grid-template-columns:minmax(210px,1fr) 2.35fr;
  grid-template-areas:"head head" "meta media";
  gap:0 clamp(24px,3.4vw,52px);
  padding:clamp(40px,5vw,72px) 0 clamp(40px,5vw,68px);
  border-bottom:1px solid var(--rule);align-items:end}
[data-hero="broadsheet"] .hero--home .hero__head{grid-area:head;padding-bottom:clamp(24px,3vw,38px)}
[data-hero="broadsheet"] .hero--home .hero__meta{grid-area:meta;border-top:1px solid var(--ink);
  padding-top:18px;padding-right:0}
[data-hero="broadsheet"] .hero--home .hero__media{grid-area:media;border-top:1px solid var(--ink);
  padding-top:18px;padding-right:var(--gut)}
[data-hero="broadsheet"] .hero--home .hero__media img{width:100%;height:min(50vh,468px);object-fit:cover}
[data-hero="broadsheet"] .hero--home .hero__title{font-family:"Bodoni Moda",Didot,Georgia,serif;
  font-size:clamp(44px,9.4vw,146px);line-height:.9;letter-spacing:-.028em;max-width:15ch;margin-top:16px}
[data-hero="broadsheet"] .hero--home .hero__sub{font-family:"Bodoni Moda",Georgia,serif;
  font-size:clamp(17px,1.5vw,21px);line-height:1.32;color:var(--ink)}

/* ---- 4 diptych: two works, both whole, side by side ---- */
[data-hero="diptych"] .hero--home{border-bottom:1px solid var(--rule)}
[data-hero="diptych"] .hero--home .hero__media{display:grid;grid-template-columns:1fr 1fr;
  background:var(--plate);border-bottom:1px solid var(--rule)}
[data-hero="diptych"] .hero--home .hero__img2{display:block;border-left:1px solid var(--rule)}
[data-hero="diptych"] .hero--home .hero__media img{width:100%;height:min(58vh,556px);
  object-fit:contain;padding:clamp(24px,3.4vw,54px)}
[data-hero="diptych"] .hero--home .hero__head{text-align:center;padding-top:clamp(36px,4.6vw,62px)}
[data-hero="diptych"] .hero--home .hero__meta{text-align:center;padding-bottom:clamp(42px,5.4vw,72px)}
[data-hero="diptych"] .hero--home .hero__title{font-family:"Cormorant Garamond",Georgia,serif;
  font-weight:300;font-size:clamp(40px,6.6vw,86px);line-height:1.02;letter-spacing:-.01em;margin:18px 0 12px}
[data-hero="diptych"] .hero--home .hero__sub{font-family:"Cormorant Garamond",Georgia,serif;
  font-size:clamp(19px,2vw,27px);max-width:none}

/* ---- 5 card: the private view invitation, at full size ---- */
[data-hero="card"] .hero--home{background:var(--sunk);padding:clamp(38px,5vw,82px) var(--gut);
  border-bottom:1px solid var(--rule);text-align:center}
[data-hero="card"] .hero--home>*{background:var(--plate);max-width:760px;margin-left:auto;margin-right:auto;
  padding-left:clamp(26px,4vw,64px);padding-right:clamp(26px,4vw,64px)}
[data-hero="card"] .hero--home .hero__media{padding-top:clamp(30px,4vw,58px);
  border:1px solid var(--rule-2);border-bottom:0;box-shadow:0 -8px 40px -34px rgba(0,0,0,.5)}
[data-hero="card"] .hero--home .hero__media img{margin:0 auto;width:auto;
  max-height:min(42vh,376px);object-fit:contain}
[data-hero="card"] .hero--home .hero__head{padding-top:clamp(28px,3.4vw,44px);
  border-left:1px solid var(--rule-2);border-right:1px solid var(--rule-2)}
[data-hero="card"] .hero--home .hero__meta{padding-bottom:clamp(34px,4.4vw,62px);
  border:1px solid var(--rule-2);border-top:0;box-shadow:0 30px 64px -44px rgba(0,0,0,.45)}
[data-hero="card"] .hero--home .hero__title{font-family:"Cinzel",Georgia,serif;
  font-size:clamp(21px,2.7vw,37px);letter-spacing:.055em;line-height:1.24;
  text-transform:uppercase;margin:0 0 16px}
[data-hero="card"] .hero--home .hero__sub{font-family:"EB Garamond",Georgia,serif;
  font-size:clamp(17px,1.6vw,21px);line-height:1.44;max-width:none}

/* ---- 6 horizon: monumental title, work whole beneath ---- */
[data-hero="horizon"] .hero--home{border-bottom:1px solid var(--rule)}
[data-hero="horizon"] .hero--home .hero__head{padding-top:clamp(46px,6vw,96px)}
[data-hero="horizon"] .hero--home .hero__title{font-family:"Libre Caslon Display",Georgia,serif;
  font-size:clamp(42px,8.4vw,132px);line-height:.96;letter-spacing:-.022em;margin-top:22px;max-width:none}
[data-hero="horizon"] .hero--home .hero__meta{display:flex;justify-content:space-between;
  align-items:flex-end;gap:26px;flex-wrap:wrap;
  margin-top:clamp(26px,3vw,40px);padding-top:22px;
  border-top:1px solid var(--ink)}
[data-hero="horizon"] .hero--home .hero__sub{font-family:"Libre Caslon Display",Georgia,serif;
  font-size:clamp(17px,1.6vw,22px);line-height:1.36;margin:0;max-width:40ch}
[data-hero="horizon"] .hero--home .hero__dates{margin:0 0 14px}
[data-hero="horizon"] .hero--home .hero__media{background:var(--plate);
  border-top:1px solid var(--rule);margin-top:clamp(30px,3.6vw,52px);padding:clamp(30px,4vw,64px) var(--gut)}
[data-hero="horizon"] .hero--home .hero__media img{margin:0 auto;width:auto;
  max-height:min(52vh,500px);object-fit:contain}

/* ---- the switcher itself ---- */
.hswitch{position:fixed;z-index:45;left:50%;transform:translateX(-50%);bottom:18px;
  display:flex;align-items:center;gap:14px;padding:9px 9px 9px 16px;
  background:rgba(22,22,26,.93);backdrop-filter:saturate(1.4) blur(9px);
  border-radius:999px;box-shadow:0 18px 44px -22px rgba(0,0,0,.7);max-width:calc(100vw - 24px)}
.hswitch__l{font-family:var(--f-body);font-size:var(--t-micro);letter-spacing:var(--ctrack);
  text-transform:uppercase;color:rgba(255,255,255,.56);font-weight:500;flex:none}
.hswitch__set{display:flex;gap:3px;overflow-x:auto;scrollbar-width:none}
.hswitch__set::-webkit-scrollbar{display:none}
/* Ten faces rather than five, so each name is set in its own type and given less room:
   sentence case instead of uppercase, because a face is judged on its lowercase and
   uppercase hides exactly the letters that tell two grotesques apart. The set scrolls
   sideways under the thumb rather than wrapping the bar into two rows over the page. */
.hswitch button{flex:none;font-size:var(--t-meta);letter-spacing:0;
  font-weight:500;color:rgba(255,255,255,.72);
  background:transparent;border:0;border-radius:999px;padding:9px 12px;cursor:pointer;
  transition:background .18s var(--ease),color .18s var(--ease);white-space:nowrap}
.hswitch button:hover{color:#fff;background:rgba(255,255,255,.12)}
.hswitch button[aria-pressed="true"]{background:#fbfbfa;color:#16161a}
@media (max-width:700px){
  .hswitch{bottom:10px;padding:7px 7px 7px 12px;gap:9px}
  .hswitch__l{display:none}
  .hswitch button{padding:8px 12px;font-size:var(--t-micro)}
}
@media (max-width:860px){
  [data-hero="broadsheet"] .hero--home{grid-template-columns:1fr;
    grid-template-areas:"head" "media" "meta";gap:0}
  [data-hero="broadsheet"] .hero--home .hero__media{padding-left:var(--gut);padding-right:var(--gut)}
  [data-hero="broadsheet"] .hero--home .hero__meta{border-top:0;padding-top:24px}
  [data-hero="diptych"] .hero--home .hero__media{grid-template-columns:1fr}
  [data-hero="diptych"] .hero--home .hero__img2{border-left:0;border-top:1px solid var(--rule)}
  [data-hero="diptych"] .hero--home .hero__media img{height:min(42vh,380px)}
  /* `calc(24px + 7.4em)` used to sit here, holding the title 150px clear of the artists'
     names. It read as a hole rather than as a composition, and it cost twice: on a
     landscape phone it pushed the dates and the call to action off the bottom, and on a
     portrait one it floated the eyebrow ~400px above the bottom edge, so far up the scrim
     that the only way to make an 11px label legible there was to black out the lower two
     thirds of the painting. Closed to an ordinary gap, the copy reads as one block, the
     picture keeps its bottom half, and the label lands where the scrim is already dark. */
  [data-hero="current"] .hero--home .hero__head{padding-bottom:clamp(16px,3.2vw,30px)}
}

.credit{font-size:var(--t-meta);line-height:1.5;color:var(--muted);margin-top:26px;max-width:60ch}

/* ================= directions, site-wide =================
   Overriding --f-display on <html> retypes every h1/h2/h3 on every page, since the
   whole stylesheet already reads that token. The rules under each direction then
   carry it through the header, the footer, the buttons and the section rules, so a
   direction is a whole site rather than a hero. `current` is the shipped design. */

/* fix: in a flex column, auto side margins make children shrink to fit, so stacked
   panels came out at different widths. Pin them full width and let max-width centre. */
.hero--home>*{width:100%}

/* ---- vitrine: inscriptional roman, quiet, plate-led ---- */
[data-hero="vitrine"]{--f-display:"Marcellus",Georgia,serif}
[data-hero="vitrine"] h1,[data-hero="vitrine"] h2,[data-hero="vitrine"] h3{letter-spacing:.005em}
[data-hero="vitrine"] .foot-mark{letter-spacing:.02em}
[data-hero="vitrine"] .btn{border-radius:0}
[data-hero="vitrine"] .sec__title{font-size:clamp(23px,2.5vw,34px)}
[data-hero="vitrine"] .card__t{letter-spacing:.005em}

/* ---- broadsheet: didone, tight, ruled like a paper ---- */
[data-hero="broadsheet"]{--f-display:"Bodoni Moda",Didot,Georgia,serif}
[data-hero="broadsheet"] h1,[data-hero="broadsheet"] h2{letter-spacing:-.026em}
[data-hero="broadsheet"] .sec__head{border-top:1px solid var(--ink);padding-top:16px}
[data-hero="broadsheet"] .sec__title{font-size:clamp(26px,3.2vw,44px);line-height:1.02}
[data-hero="broadsheet"] .btn{border-radius:0}
[data-hero="broadsheet"] .card__t{font-size:var(--t-lead);letter-spacing:-.018em}

/* ---- diptych: light garamond, larger and airier ---- */
[data-hero="diptych"]{--f-display:"Cormorant Garamond",Garamond,Georgia,serif}
[data-hero="diptych"] h1,[data-hero="diptych"] h2,[data-hero="diptych"] h3{font-weight:300;letter-spacing:-.008em}
[data-hero="diptych"] .sec__title{font-size:clamp(28px,3.6vw,50px)}
[data-hero="diptych"] .card__t{font-size:var(--t-title);font-weight:400}
[data-hero="diptych"] .foot-mark{font-size:var(--t-lead)}

/* ---- card: inscriptional caps for titles, garamond for prose ---- */
[data-hero="card"]{--f-display:"Cinzel",Georgia,serif}
[data-hero="card"] h1,[data-hero="card"] h2{text-transform:uppercase;letter-spacing:.055em;
  font-size:clamp(19px,2.2vw,30px);line-height:1.3}
[data-hero="card"] h3,[data-hero="card"] .card__t,
[data-hero="card"] .lede,[data-hero="card"] .prose p{font-family:"EB Garamond",Georgia,serif}
[data-hero="card"] h3{text-transform:none;letter-spacing:.01em;font-size:var(--t-title)}
[data-hero="card"] .prose p,[data-hero="card"] .lede{font-size:var(--t-lead);line-height:1.62}
[data-hero="card"] .foot-mark{text-transform:uppercase;
  letter-spacing:.08em;font-size:var(--t-small)}
[data-hero="card"] .btn{border-radius:0}

/* ---- horizon: caslon display, monumental headings ---- */
[data-hero="horizon"]{--f-display:"Libre Caslon Display",Georgia,serif}
[data-hero="horizon"] h1,[data-hero="horizon"] h2{letter-spacing:-.02em;line-height:1}
[data-hero="horizon"] .sec__title{font-size:clamp(28px,3.8vw,54px)}
[data-hero="horizon"] .sec__head{align-items:flex-end}
[data-hero="horizon"] .btn{border-radius:0}

/* the switcher must clear the footer on every page */
body{padding-bottom:0}
.site-foot{padding-bottom:96px}

/* ---- hero fit: centred titles centre, and the artwork lands inside the first screen ---- */
[data-hero="vitrine"] .hero--home .hero__title,
[data-hero="diptych"] .hero--home .hero__title,
[data-hero="card"]    .hero--home .hero__title,
[data-hero="vitrine"] .hero--home .hero__sub,
[data-hero="diptych"] .hero--home .hero__sub,
[data-hero="card"]    .hero--home .hero__sub{margin-left:auto;margin-right:auto;max-width:min(22ch,100%)}
[data-hero="card"] .hero--home .hero__title{max-width:min(26ch,100%)}

[data-hero="vitrine"] .hero--home .hero__media{padding:clamp(22px,2.6vw,40px) var(--gut)}
[data-hero="vitrine"] .hero--home .hero__media img{max-height:min(40vh,392px)}
[data-hero="vitrine"] .hero--home .hero__head{padding-top:clamp(24px,2.6vw,36px)}
[data-hero="vitrine"] .hero--home .hero__title{font-size:clamp(28px,3.4vw,44px);margin:14px auto 12px}
[data-hero="vitrine"] .hero--home .hero__meta{padding-bottom:clamp(28px,3.2vw,44px)}

[data-hero="diptych"] .hero--home .hero__media img{height:min(38vh,372px);padding:clamp(16px,2vw,30px)}
[data-hero="diptych"] .hero--home .hero__head{padding-top:clamp(22px,2.6vw,38px)}
[data-hero="diptych"] .hero--home .hero__title{font-size:clamp(30px,3.8vw,52px);margin:14px auto 10px}
[data-hero="diptych"] .hero--home .hero__meta{padding-bottom:clamp(28px,3.2vw,46px)}

[data-hero="card"] .hero--home{padding:clamp(22px,2.6vw,42px) var(--gut)}
[data-hero="card"] .hero--home .hero__media{padding-top:clamp(20px,2.4vw,34px)}
[data-hero="card"] .hero--home .hero__media img{max-height:min(34vh,326px)}
[data-hero="card"] .hero--home .hero__head{padding-top:clamp(18px,2.2vw,28px)}
[data-hero="card"] .hero--home .hero__meta{padding-bottom:clamp(22px,2.6vw,38px)}

[data-hero="horizon"] .hero--home .hero__head{padding-top:clamp(26px,3vw,46px)}
[data-hero="horizon"] .hero--home .hero__title{font-size:clamp(34px,5.4vw,78px);margin-top:14px}
[data-hero="horizon"] .hero--home .hero__meta{margin-top:clamp(16px,1.8vw,24px);padding-top:16px}
[data-hero="horizon"] .hero--home .hero__media{margin-top:clamp(18px,2vw,28px);
  padding:clamp(20px,2.4vw,36px) var(--gut)}
[data-hero="horizon"] .hero--home .hero__media img{max-height:min(40vh,392px)}

[data-hero="broadsheet"] .hero--home{padding:clamp(26px,3vw,46px) 0 clamp(26px,3vw,44px)}
[data-hero="broadsheet"] .hero--home .hero__title{font-size:clamp(36px,6.2vw,92px)}
[data-hero="broadsheet"] .hero--home .hero__head{padding-bottom:clamp(18px,2vw,28px)}
[data-hero="broadsheet"] .hero--home .hero__media img{height:min(42vh,410px)}

/* The phone scrim that used to live here, at max-width:700 and in percentages, is folded
   into the max-width:860 rule above and restated in pixels. It was written for a real
   problem, 41% of the title area under 3:1 at 390x844, and it fixed that geometry; but
   percentages meant it was measured against a hero that is 592px tall on a 375x667 phone
   and 857px tall on a 430x932 one, so the same rule left the eyebrow at 3.13:1 on the
   shorter of the two. One rule in pixels covers both, and covers the 700 to 860 band the
   old one never reached. */

/* ---- touch targets: 44px on coarse pointers only, so the desktop rhythm is untouched ---- */
@media (pointer:coarse){
  .btn--quiet{min-height:44px}
  .brand{display:inline-flex;align-items:center;min-height:44px}
  .foot-facts a,.foot-base a{display:inline-flex;align-items:center;min-height:44px}
  .hswitch button{min-height:44px}
  .nav a{padding-top:10px;padding-bottom:10px}
}
@media (pointer:coarse){
  .statement cite,.credit a,.note a,.prose a,.sec__head a{min-height:44px;display:inline-flex;align-items:center}
  .lb__close,.lb__nav{min-height:44px;min-width:44px}
}

/* ---- the QR sheet exists to be printed ---- */
@media print{
  .site-head,.site-foot,.hswitch,.skip,.btn{display:none!important}
  body{background:#fff;font-size:11pt}
  .qr-card,.qr__item{break-inside:avoid;page-break-inside:avoid}
  a[href]::after{content:""}
  .wrap{max-width:none;padding:0}
}
@media (pointer:coarse){
  .card,.row,.qa a,.facts a,.statement a,figure a{min-height:44px}
  /* Only where an inline-link is a standalone control. A link inside a sentence stays
     inline: WCAG 2.5.8 exempts a target "in a sentence or whose size is otherwise
     constrained by the line-height of non-target text", and forcing one to inline-flex at
     44px pulls it out of the paragraph it belongs to. On /connect that turned the gallery's
     own address, mid-sentence, into a rigid box with a rule running the width of the line
     under it. The typography was paying for a rule that did not apply. */
  .facts .inline-link,.spec .inline-link,nav.caps .inline-link{
    display:inline-flex;align-items:center;min-height:44px}
  /* The service pages' own two standalone link sets, added 14 August. Neither is a link
     inside a sentence, so neither takes the exemption above: the cross-links are a list
     of six destinations and the card heading is the way into a service. They measured
     22px and 28px, under WCAG 2.5.8's 44. `width:fit-content` keeps the target the width
     of its words rather than the width of the column it sits in. */
  .plainlist a,.card__t--link a{display:inline-flex;align-items:center;min-height:44px;
    width:fit-content}
}

/* ---- archive: images the gallery has not yet captioned ---- */
.arch{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));
      gap:clamp(14px,1.8vw,26px)}
.arch__i{margin:0;background:var(--plate);border:1px solid var(--rule);
         padding:clamp(10px,1.1vw,16px)}
.arch__i img{width:100%;aspect-ratio:1;object-fit:contain}

/* ---- iPhone pass: 390 / 402 / 440 ---- */
@media (max-width:700px){
  /* iOS zooms the whole page when a focused field is under 16px */
  input,select,textarea{font-size:var(--t-base)}
  /* micro-labels are tracked uppercase, so they read small; give them back a step */
  .hero__eyebrow,.caps,.form__step,.arch figcaption{font-size:var(--t-meta)}
  .hero__dates{font-size:var(--t-meta)}
  .credit{font-size:var(--t-small)}
}
@media (pointer:coarse){
  .nav a{min-height:44px;display:inline-flex;align-items:center;padding-top:0;padding-bottom:0}
  .foot-base a{min-height:44px;display:inline-flex;align-items:center}
}

/* ---- the direction bar has to be fully reachable on a phone. A horizontal scroll
   inside it left the last buttons clipped, with no affordance that they were there. ---- */
@media (max-width:700px){
  .hswitch{left:8px;right:8px;transform:none;max-width:none;border-radius:22px;
           flex-direction:column;align-items:stretch;gap:6px;padding:9px 10px}
  .hswitch__l{display:block;text-align:center}
  .hswitch__set{flex-wrap:wrap;justify-content:center;overflow:visible}
  .hswitch button{flex:0 1 auto}
}
@media (pointer:coarse){
  /* a checkbox is 19px by default; grow the control itself rather than faking a hit area */
  input[type=checkbox],input[type=radio]{width:24px;height:24px;margin:10px 8px 10px 0}
  .field--check label,.field--check{min-height:44px;display:flex;align-items:center;gap:4px}
}

/* ------------------------------------------------------------------------------
   THE FIVE SANS CANDIDATES.

   Carole chose the Current direction on 4 August, so this layer changes the FACE and
   nothing else: no layout, no rules, no palette. It is deliberately orthogonal to
   [data-hero], so a face can be judged without the direction moving underneath it.

   Each sets the display face and the reading face together, because a heading face
   judged against the wrong body face is not the pairing that would ship.
   Review-only. When a face is locked, keep one block and delete the other four.
   ------------------------------------------------------------------------------ */
/* Ten faces, and every one a TRUE sans serif (Jake, 2026-08-04). The bar used to open on
   Faustina, which is a serif, and offered Syne, which is a display face rather than a
   text one. Neither belongs in a set someone is asked to read a whole gallery in.

   Each face carries its own weight and tracking rather than one shared pair of numbers.
   A geometric set at 600 and a grotesque at 600 are not the same colour on a page, and
   judging ten faces through settings tuned for one of them only proves that nine of them
   were set wrong. */

/* American grotesque. Editorial, square-shouldered, holds a long title. */
[data-type="archivo"]{--f-display:"Archivo",system-ui,sans-serif;--f-body:"Work Sans",system-ui,sans-serif}
[data-type="archivo"] h1,[data-type="archivo"] h2,[data-type="archivo"] h3{font-weight:600;letter-spacing:-.028em}

/* Slightly narrow. Sets a long exhibition title without shrinking it. */
[data-type="instrument"]{--f-display:"Instrument Sans",system-ui,sans-serif;--f-body:"IBM Plex Sans",system-ui,sans-serif}
[data-type="instrument"] h1,[data-type="instrument"] h2,[data-type="instrument"] h3{font-weight:600;letter-spacing:-.024em}

/* Nordic grotesque. Even colour, a little warmth in the round letters. */
[data-type="familjen"]{--f-display:"Familjen Grotesk",system-ui,sans-serif;--f-body:"Karla",system-ui,sans-serif}
[data-type="familjen"] h1,[data-type="familjen"] h2,[data-type="familjen"] h3{font-weight:500;letter-spacing:-.022em}

/* Newspaper grotesque. The most confident of the ten at large sizes. */
[data-type="schibsted"]{--f-display:"Schibsted Grotesk",system-ui,sans-serif;--f-body:"Work Sans",system-ui,sans-serif}
[data-type="schibsted"] h1,[data-type="schibsted"] h2,[data-type="schibsted"] h3{font-weight:600;letter-spacing:-.026em}

/* Geometric humanist, open and calm. Recedes behind the pictures. */
[data-type="manrope"]{--f-display:"Manrope",system-ui,sans-serif;--f-body:"IBM Plex Sans",system-ui,sans-serif}
[data-type="manrope"] h1,[data-type="manrope"] h2,[data-type="manrope"] h3{font-weight:600;letter-spacing:-.03em}

/* Pure geometric, set light. The airiest, closest to a catalogue. */
[data-type="outfit"]{--f-display:"Outfit",system-ui,sans-serif;--f-body:"Work Sans",system-ui,sans-serif}
[data-type="outfit"] h1,[data-type="outfit"] h2,[data-type="outfit"] h3{font-weight:300;letter-spacing:-.02em}

/* Low contrast geometric. Warmer than it looks, easy in long bios. */
[data-type="dmsans"]{--f-display:"DM Sans",system-ui,sans-serif;--f-body:"Karla",system-ui,sans-serif}
[data-type="dmsans"] h1,[data-type="dmsans"] h2,[data-type="dmsans"] h3{font-weight:500;letter-spacing:-.032em}

/* Humanist geometric. The most current-feeling of the set. */
[data-type="jakarta"]{--f-display:"Plus Jakarta Sans",system-ui,sans-serif;--f-body:"Work Sans",system-ui,sans-serif}
[data-type="jakarta"] h1,[data-type="jakarta"] h2,[data-type="jakarta"] h3{font-weight:600;letter-spacing:-.03em}

/* Humanist. More written than drawn, kindest to small text. */
[data-type="hanken"]{--f-display:"Hanken Grotesk",system-ui,sans-serif;--f-body:"IBM Plex Sans",system-ui,sans-serif}
[data-type="hanken"] h1,[data-type="hanken"] h2,[data-type="hanken"] h3{font-weight:600;letter-spacing:-.026em}

/* Neutral and contemporary. The quietest, which on a wall of art is an argument. */
[data-type="onest"]{--f-display:"Onest",system-ui,sans-serif;--f-body:"Karla",system-ui,sans-serif}
[data-type="onest"] h1,[data-type="onest"] h2,[data-type="onest"] h3{font-weight:600;letter-spacing:-.028em}

/* Each button wears its own face, so the bar shows the type rather than naming it. */
#tswitch button[data-t="archivo"]{font-family:"Archivo",system-ui,sans-serif}
#tswitch button[data-t="instrument"]{font-family:"Instrument Sans",system-ui,sans-serif}
#tswitch button[data-t="familjen"]{font-family:"Familjen Grotesk",system-ui,sans-serif}
#tswitch button[data-t="schibsted"]{font-family:"Schibsted Grotesk",system-ui,sans-serif}
#tswitch button[data-t="manrope"]{font-family:"Manrope",system-ui,sans-serif}
#tswitch button[data-t="outfit"]{font-family:"Outfit",system-ui,sans-serif}
#tswitch button[data-t="dmsans"]{font-family:"DM Sans",system-ui,sans-serif}
#tswitch button[data-t="jakarta"]{font-family:"Plus Jakarta Sans",system-ui,sans-serif}
#tswitch button[data-t="hanken"]{font-family:"Hanken Grotesk",system-ui,sans-serif}
#tswitch button[data-t="onest"]{font-family:"Onest",system-ui,sans-serif}

/* ------------------------------------------------------------------------------
   THE FACE BAR.

   Scoped to the id on purpose. .hswitch is styled in more than one place and the
   computed result did not match any single rule I could point at, so the bar that
   Carole actually uses states its own geometry and stops depending on which class
   rule wins. One row, scrolls sideways, 44px targets, clear of the review launcher.
   ------------------------------------------------------------------------------ */
/* Centred with auto margins, NOT with left:50% and a translate.
   A shrink-to-fit fixed element resolves its width against the space from its left edge
   to the containing block's right edge, so `left:50%` left it half the viewport to work
   with. On a 320px phone the bar sized itself to 152px and squeezed ten faces into 50px
   of scroller, which measured as "not wrapped" and was still unusable. Auto margins give
   it the whole width and centre it just the same. */
#tswitch{position:fixed;z-index:45;left:0;right:0;margin:0 auto;bottom:16px;
  /* transform is reset explicitly. The .hswitch rule above still sets translateX(-50%),
     and left un-reset it drags the bar half its own width to the left of centre, putting
     its right edge exactly on the midline at every width. That is the same "two rule sets
     fighting" this block was written to end, so it ends here rather than by editing the
     other one and hoping. */
  transform:none;
  width:max-content;max-width:calc(100vw - 20px);
  display:flex;flex-direction:row;flex-wrap:nowrap;align-items:center;gap:12px;
  padding:7px 8px 7px 15px;background:rgba(22,22,26,.94);
  backdrop-filter:saturate(1.4) blur(9px);border-radius:999px;
  box-shadow:0 18px 44px -22px rgba(0,0,0,.7)}
#tswitch .hswitch__l{flex:none;display:block;margin:0;line-height:1;
  font-family:var(--f-body);font-size:var(--t-micro);letter-spacing:var(--ctrack);
  text-transform:uppercase;color:rgba(255,255,255,.56);font-weight:500}
#tswitch .hswitch__set{display:flex;flex-direction:row;flex-wrap:nowrap;gap:3px;
  overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch}
#tswitch .hswitch__set::-webkit-scrollbar{display:none}
/* Sentence case, and each name set in its own face. Uppercase hides the very letters
   that tell two grotesques apart, which is most of what is being judged here. */
#tswitch .hswitch__set button{flex:none;min-height:44px;display:inline-flex;align-items:center;
  font-size:var(--t-meta);letter-spacing:0;text-transform:none;
  font-weight:500;color:rgba(255,255,255,.72);background:transparent;border:0;
  border-radius:999px;padding:0 12px;cursor:pointer;white-space:nowrap}
#tswitch .hswitch__set button:hover{color:#fff;background:rgba(255,255,255,.12)}
/* The face you are looking at is underlined, not filled. There is exactly ONE filled
   shape on this bar and it is the lock, so nothing competes with the thing that commits. */
#tswitch .hswitch__set button[aria-pressed="true"]{color:#fff;background:rgba(255,255,255,.1);
  box-shadow:inset 0 -2px 0 #fbfbfa}
#tswitch button:focus-visible{outline:2px solid #fff;outline-offset:2px}

/* The set is the only thing allowed to shrink, and it scrolls rather than wrapping. A
   bar that wraps grows upward into the page, which on a landscape phone eats the view it
   is meant to be showing. The fade says there is more without spending a control on it. */
#tswitch .hswitch__set{flex:1 1 auto;min-width:0;
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 14px,#000 calc(100% - 14px),transparent 100%);
  mask-image:linear-gradient(90deg,transparent 0,#000 14px,#000 calc(100% - 14px),transparent 100%)}

/* The decision. Filled, padlocked, behind a rule, and it never shrinks or scrolls away:
   whatever the window is doing, the one control that commits stays put and stays 44px. */
#tswitch .hswitch__rule{flex:none;width:1px;height:26px;margin:0;background:rgba(255,255,255,.22)}
#tswitch .hswitch__lock{flex:none;display:inline-flex;align-items:center;gap:7px;
  font-family:var(--f-body);font-size:var(--t-micro);letter-spacing:var(--ctrack);
  text-transform:uppercase;font-weight:600;color:#16161a;
  background:#fbfbfa;border:0;border-radius:999px;padding:0 16px;cursor:pointer;
  min-height:44px;white-space:nowrap;
  transition:background .18s var(--ease),color .18s var(--ease),transform .18s var(--ease)}
#tswitch .hswitch__lock:hover{background:#fff;transform:translateY(-1px)}
#tswitch .hswitch__lock:active{transform:translateY(0)}
#tswitch .hswitch__ico{flex:none;margin-top:-1px}
#tswitch .hswitch__lockshort{display:none}
/* Once a face is locked the button stops shouting. The decision is made, and a permanent
   invitation to re-make it is noise; it stays reachable, quietly. */
#tswitch[data-locked] .hswitch__lock{background:transparent;color:rgba(255,255,255,.82);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.34)}
#tswitch[data-locked] .hswitch__lock:hover{background:rgba(255,255,255,.14);color:#fff}
#tswitch[data-locked] .hswitch__l{color:rgba(255,255,255,.92)}

/* The width ladder. One row at every size; only the words get shorter. */
@media (max-width:900px){
  #tswitch .hswitch__lockfull{display:none}
  #tswitch .hswitch__lockshort{display:inline}
  #tswitch .hswitch__lock{padding:0 14px}
}
@media (max-width:700px){
  #tswitch{bottom:10px;gap:8px;padding:6px 7px 6px 11px;max-width:calc(100vw - 16px)}
  #tswitch .hswitch__l{display:none}
  /* Except when it is the only feedback there is: a lock in flight, or one already made.
     Hiding it then would leave the tap looking like it did nothing. */
  #tswitch[data-locked] .hswitch__l,#tswitch[data-say] .hswitch__l{display:block}
  #tswitch .hswitch__set button{padding:0 10px;font-size:var(--t-meta)}
}
@media (max-width:480px){
  #tswitch{gap:6px;padding:6px 6px 6px 8px;max-width:calc(100vw - 12px)}
  #tswitch .hswitch__set button{padding:0 9px;font-size:var(--t-label)}
  #tswitch .hswitch__lock{padding:0 12px;font-size:var(--t-micro);gap:5px}
  #tswitch .hswitch__rule{margin:0 1px}
  /* At this width the status line and the face set would fight for the same row, and the
     set is what she is here to use. */
  #tswitch[data-locked] .hswitch__l,#tswitch[data-say] .hswitch__l{display:none}
}
/* A landscape phone: almost no height, so the bar sits tighter to the edge. The 44px
   targets do not move, because that is what a thumb needs whatever the screen is doing. */
@media (max-height:520px){
  #tswitch{bottom:8px;padding:5px 6px 5px 10px}
  #tswitch .hswitch__l{display:none}
}

/* ================= v2 homepage modules =================
   Written to §9 of the v2 directive. Same system as the rest of the sheet: hairline
   rules, square corners, no shadow, the artwork on true white. Each module composes
   itself rather than passing through one shared card, which is what §7.1 asks for and
   §34 names as the failure to avoid. */

/* §9.3's identity line and §9.4's second current-exhibition entry lived here until the
   9 August meeting removed both from the page: the line restated what Visit, About and
   the footer already say, and the second entry repeated the hero a screen after it. */

/* ---- §9.5 the Highlight. Deliberately unlike the module above it: text leads, the
   image is subordinate and optional, and the whole block sits on plate so the change
   of ground does the separating rather than another border. ---- */
.hl__in{display:grid;grid-template-columns:1fr;gap:clamp(24px,3.4vw,52px);align-items:center}
.hl__in:has(.hl__media){grid-template-columns:1fr .82fr}
.hl__eyebrow{margin:0 0 12px}
.hl__title{font-size:clamp(24px,2.9vw,38px);max-width:20ch}
.hl__body .lede{margin-top:14px}
/* the highlight's second title line, holding the same 1.65 relationship the hero does */
.hl__sub{font-family:var(--f-display);font-size:clamp(15px,1.75vw,23px);line-height:1.3;
         letter-spacing:-.014em;color:var(--ink)}
.hl__text{font-size:var(--t-base);line-height:1.7;color:var(--ink-2);max-width:52ch;
          margin:18px 0 0;text-wrap:pretty}
/* The four facts an artist decides on, set as a ruled list rather than a paragraph so
   they can be read in one pass and so the column has something with vertical structure
   to stand against the card beside it. */
.hl__facts{margin:24px 0 0;padding:0}
.hl__facts>div{display:grid;grid-template-columns:minmax(9.5rem,auto) 1fr;gap:8px 20px;
               padding:11px 0;border-top:1px solid var(--rule)}
.hl__facts dt{font-family:var(--f-body);font-size:var(--t-label);letter-spacing:var(--ctrack);
              text-transform:uppercase;color:var(--muted);margin:0}
.hl__facts dd{margin:0;font-size:var(--t-base);line-height:1.5;color:var(--ink)}
.hl__date{margin:14px 0 0}
.hl__act{margin:24px 0 0}
.hl__media{margin:0;background:var(--plate)}
.hl__media img{width:100%;aspect-ratio:4/3;object-fit:contain}
/* --t-meta, not --t-label. A credit is metadata under a picture, which is what --t-meta
   exists for; --t-label is 11px and is drawn for uppercase two-word labels, not for a
   sentence naming a photographer. At 11px with line-height 1.35 it was the smallest
   reading matter on the site by some way. */
.hl__credit{font-family:var(--f-body);font-size:var(--t-meta);line-height:1.5;color:var(--muted);
            margin:clamp(10px,1vw,14px) 2px 2px;text-wrap:pretty}

/* The open call is the one highlight whose picture is a portrait card rather than a
   landscape photograph of a room. Cropping a tarot card to 4/3 cuts the figure off at
   the knees, and giving the picture the wider of the two columns leaves the terms, which
   are the thing an artist came to read, squeezed into the narrower one. So this variant
   inverts the ratio and shows the card whole, matted on white with its credit under it
   the way it would be labelled on a wall. */
/* Top-aligned, not centred. Against a 520px card, centring floats the eyebrow into the
   middle of the band with a hand's width of air above and below it and nothing to line
   up with. Aligned to the start, the label sits on the top edge of the mat and the block
   reads as one thing. */
.hl--open-call .hl__in:has(.hl__media){grid-template-columns:minmax(0,.56fr) minmax(0,1fr);
                                       align-items:start}
.hl--open-call .hl__body{padding-top:clamp(4px,.6vw,10px)}

/* 440, down from 520. The 9 August meeting asked for one home-page image to come down
   a step, and this is the one: a 936x1600 portrait plate that stood taller than every
   module around it, and taller still once the band beside it lost its paragraph and
   kept only the facts. At 440 the card's foot lands level with the facts list instead
   of running past it. */
.hl--open-call .hl__media img{width:auto;max-width:100%;height:auto;aspect-ratio:auto;
                              object-fit:contain;max-height:min(50vh,440px);margin:0 auto}

/* ---- §9.6 events. A date-led list. Someone scanning for "is anything on soon"
   reads dates, so the date is the first thing on the line and stays in one column. ---- */
/* ---- §9.8 the invitation to visit. The house does the persuading, so the photograph
   is given the larger half and the practical facts sit beside it as a definition list,
   which is what they actually are. ---- */
.sec--visit{padding:clamp(48px,5.8vw,84px) 0}
.sec+.sec--visit{padding-top:clamp(34px,3.9vw,56px)}
/* The photograph column was 1.18fr against 1fr and the picture ran larger than the
   invitation beside it. 0.83fr is the same picture at 70% of that width, which is the
   30% Jake asked for, and it puts the words first at the width people read at. */
.visit{display:grid;grid-template-columns:0.83fr 1fr;gap:clamp(30px,4.6vw,74px);align-items:center}
.visit__media img{width:100%;aspect-ratio:4/3;object-fit:cover;background:var(--sunk);display:block}

/* ---- the visit slideshow ----
   Four photographs: the door, then the three rooms behind it, in the order you meet
   them. A crossfade rather than a slide, because these are pictures of rooms and sliding
   them past each other reads like a widget; a dissolve reads like looking up.

   Everything here is built so the thing still works with the script absent or refused:
   the first slide is visible markup, the rest carry `hidden`, and the controls are real
   buttons that do nothing until wired. */
.vs{position:relative;overflow:hidden;background:var(--sunk)}
.vs__track{list-style:none;margin:0;padding:0;position:relative;aspect-ratio:4/3}
/* .22s, not .55s. DWELL in site.js is 2 seconds as of 1 September. The crossfade is
   deliberately NOT half the dwell: half a second of dissolve means no photograph is
   ever fully itself, and a request for a slower change is not a request for a longer
   blur. .22s stays put whichever way the dwell moves. */
.vs__s{position:absolute;inset:0;opacity:0;transition:opacity .22s var(--ease)}
/* This was `display:block`, which defeated the `hidden` attribute on every slide and is
   why deferring the reveal in site.js did nothing on its own: all seven photographs stayed
   in the layout and kept loading. The crossfade does still need both pictures in the
   layout, but only once the section has been approached, and by then `show` has taken
   `hidden` off all of them, so this override was buying nothing and costing 541KB. Before
   the reveal, `hidden` now means what it says, and a visitor with no JavaScript sees the
   one slide rather than seven stacked on top of each other. */
.vs__s[data-on]{opacity:1}
.vs__s img{width:100%;height:100%;object-fit:cover;
  /* A slow drift inwards over the dwell. 1.045 is small enough to read as the room
     settling rather than as a photograph being zoomed at you. */
  transform:scale(1.045);transition:transform 6.6s linear}
.vs__s[data-on] img{transform:scale(1)}

/* The controls sit over the picture and stay out of the way until wanted. They are
   always reachable by keyboard: focus brings them back at full opacity. */
.vs__arrow{position:absolute;top:50%;transform:translateY(-50%);z-index:2;
  width:44px;height:44px;display:grid;place-items:center;border:0;cursor:pointer;
  background:rgba(255,255,255,.82);color:var(--ink);
  opacity:0;transition:opacity .28s var(--ease),background .28s var(--ease)}
.vs__arrow--prev{left:10px}
.vs__arrow--next{right:10px}
.vs:hover .vs__arrow,.vs:focus-within .vs__arrow{opacity:1}
/* A phone has no hover, so the rule above never fires and the arrows stay invisible
   forever. The dots came off on 21 August at the gallery's request, so without this the
   only way to step the photographs by hand is gone on the device most visitors use. */
@media (hover:none){.vs__arrow{opacity:1}}
.vs__arrow:hover{background:#fff}
.vs__arrow:focus-visible{opacity:1;outline:2px solid var(--ink);outline-offset:2px}

/* A hairline that fills over the dwell. It is the only moving furniture, and it is the
   thing that tells you the picture is about to change rather than surprising you. */
.vs__bar{position:absolute;left:0;bottom:0;height:2px;width:100%;transform-origin:0 50%;
  transform:scaleX(0);background:var(--ink);opacity:.5;z-index:2}
.vs__bar[data-run]{transition:transform 2s linear;transform:scaleX(1)}

/* The row of rules under the photograph came off on 21 August at the gallery's request,
   "get rid of dashes at the bottom of picture". The arrows and the dwell bar stay, so the
   slideshow can still be stepped through by hand and still says when it is about to move.
   What is lost is the "which of four" marker; the live region still announces it. */

@media (prefers-reduced-motion:reduce){
  /* No autoplay at all in the script, and nothing here moves either: the picture
     changes when somebody asks for it and changes at once. */
  .vs__s{transition:none}
  .vs__s img,.vs__s[data-on] img{transform:none;transition:none}
  .vs__bar{display:none}
}
.visit__set{font-size:var(--t-body);line-height:1.7;color:var(--ink-2);max-width:46ch;margin:20px 0 0}
.visit__facts{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:22px 30px;margin:30px 0 0}
.visit__facts>div{border-top:1px solid var(--rule);padding-top:12px}
.visit__facts dt{font-family:var(--f-body);font-size:var(--t-label);letter-spacing:var(--ctrack);
                 text-transform:uppercase;color:var(--muted);font-weight:500;margin-bottom:6px}
.visit__facts dd{margin:0;font-size:var(--t-base);line-height:1.5;color:var(--ink)}
.visit__act{margin:32px 0 0}

/* ---- §9.9 gallery updates. The form itself lives in the footer's first row now
   (see .foot-join in the colophon section); what stays here is the anatomy of the
   fields, which is where it was written when the form was a page section and there
   is no reason for it to move house every time the form does. The visible label tier
   came off in the 9 August distilling: the labels live on as .vh text tied to their
   inputs by for/id, read aloud exactly as before, while the placeholder carries the
   visible word and the button carries the form's name. The placeholder holds full
   opacity because a browser's default washes it below AA contrast. ---- */
.signup__form input{min-height:48px;font:inherit;font-size:var(--t-base);color:var(--ink);
                    background:var(--paper);border:1px solid var(--rule-2);padding:11px 14px}
.signup__form input::placeholder{color:var(--muted);opacity:1}
.signup__form input:focus-visible{outline:2px solid var(--ink);outline-offset:1px}
.signup__form input[aria-invalid="true"]{border-color:var(--ink)}
.signup__status{margin:0;font-size:var(--t-minor);line-height:1.5;color:var(--ink);min-height:1.5em}
.signup__status:empty{min-height:0}

@media (max-width:1080px){
  .visit__facts{grid-template-columns:1fr 1fr}
}
@media (max-width:860px){
  /* Mobile is composed, not compressed: every split becomes one column. */
  .visit,.hl__in,.hl__in:has(.hl__media),
  .hl--open-call .hl__in:has(.hl__media){grid-template-columns:1fr}
  .hl__in:has(.hl__media) .hl__media{order:-1}
  /* The card is a portrait picture in a one-column stack, so it is held to a readable
     size and centred rather than run to the full width of the screen, where a tarot card
     a phone-width across would tower over the terms it is illustrating. 270, down from
     300, the same step down the desktop plate took on 9 August. */
  .hl--open-call .hl__media{max-width:min(270px,66vw);margin-left:auto;margin-right:auto}
  .hl--open-call .hl__media img{max-height:none}
  .hl--open-call .hl__body{padding-top:0}
  .visit__media{order:-1}
  .hl__title{max-width:none}
}
@media (max-width:540px){
  .visit__facts{grid-template-columns:1fr;gap:16px}
}

/* ---- WCAG 2.2 AA, 2.5.8 Target Size (Minimum) ----
   The sheet already grows every target to 44px on a coarse pointer. 2.5.8 asks for 24
   CSS px regardless of pointer, and the header links, the quiet buttons and the inline
   links in prose were landing at 20 to 23.6px on a mouse. The fix is padding, not a
   layout change: the type, weight and position are exactly where they were. */
.nav a{padding-top:4px;padding-bottom:5px}
.brand{display:inline-flex;align-items:center;min-height:26px}
.btn--quiet{min-height:26px;display:inline-flex;align-items:center}
/* Left inline on purpose, see the coarse-pointer note above: an inline-block cannot break
   across lines, so a long address in the middle of a sentence stopped wrapping and sat in
   the paragraph as a box. */
.facts .inline-link,.spec .inline-link,nav.caps .inline-link{
  padding-top:3px;padding-bottom:3px;display:inline-block}

/* The coarse-pointer rule has to be restated after the block above, or the 26px
   minimums just written would win on a phone by being later in the sheet. On touch
   the number is 44, and it stays 44. */
@media (pointer:coarse){
  .brand,.btn--quiet{min-height:44px}
  .facts .inline-link,.spec .inline-link,nav.caps .inline-link{padding-top:0;padding-bottom:0}
}

/* The sheet already grows a checkbox from its 19px default to 24px, but only on a
   coarse pointer. WCAG 2.2 AA 2.5.8 does not ask which pointer is in use, so the
   control is 24px everywhere. Same rule as the coarse block, same reasoning: grow
   the control, do not fake a hit area around it. */
input[type=checkbox],input[type=radio]{width:24px;height:24px;margin:6px 8px 6px 0}

/* A tick box is hit by its words as much as by the box, so the label is the target
   and it clears 44px on a thumb. */
@media (pointer:coarse){
  .check{min-height:44px;align-items:center}
}

/* ---- §9.1 the mobile menu's foot. Desktop already carries these facts in the
   footer, so the nav shows them only where the menu is a panel. ---- */
.nav__foot{display:none}
.nav__addr{display:block;font-family:var(--f-body);font-size:var(--t-meta);letter-spacing:0;
           text-transform:none;color:var(--ink);opacity:1;border-bottom:1px solid var(--rule-2);
           padding-bottom:6px}
.nav__hrs{display:block;font-family:var(--f-body);font-size:var(--t-meta);line-height:1.5;
          color:var(--muted);margin-top:8px}
@media (max-width:860px){
  .nav__foot{display:block;border-top:1px solid var(--rule);margin-top:8px;padding:16px 0 6px}
  .nav__addr{min-height:44px;display:flex;align-items:center;border-bottom:0}
}

/* ---- §10.1 item 11. Previous and next, at the end of an exhibition. A hairline
   above them, and nothing else: this is a way onward, not a third call to action. ---- */
.exnav{display:grid;grid-template-columns:1fr 1fr;gap:clamp(20px,3vw,44px);
       border-top:1px solid var(--rule);margin-top:clamp(34px,4vw,56px);padding-top:22px}
.exnav__a{display:grid;gap:7px;min-height:44px;align-content:start}
.exnav__a--next{text-align:right}
.exnav__t{font-family:var(--f-display);font-size:clamp(17px,1.6vw,22px);line-height:1.2;
          letter-spacing:-.014em;color:var(--ink)}
.exnav__a:hover .exnav__t{border-bottom:1px solid var(--ink)}
@media (max-width:540px){
  .exnav{grid-template-columns:1fr;gap:20px}
  .exnav__a--next{text-align:left}
}

/* ---- §17.1. `<picture>` is an inline box by default, and every image in this sheet
   is styled as a block that fills its container. Without this the wrapper introduces a
   line box, which shows up as a few stray pixels under every photograph and as a
   changed flex item where the image used to be the item itself. ---- */
picture{display:block}
picture>img{width:100%}
.brand picture,.foot-mark picture{display:inline-flex}
.brand picture>img,.foot-mark picture>img{width:auto}


/* ================= the work page's own bar =================
   Work pages only. It carries what the piece is and the two things a visitor might want
   to do about it, and it stays in the thumb zone on a phone, where this page converts or
   does not. While the ten-face review bar is present it sits above it; once a face is
   locked that bar leaves and this one drops to the edge on its own. */
.workbar{position:fixed;left:0;right:0;bottom:0;z-index:44;
  background:rgba(251,251,250,.97);backdrop-filter:saturate(1.3) blur(8px);
  border-top:1px solid var(--rule-2);padding:10px 0 calc(10px + env(safe-area-inset-bottom,0px))}
.workbar__in{max-width:var(--maxw);margin:0 auto;padding:0 var(--gut);
  display:flex;align-items:center;gap:16px;flex-wrap:nowrap}
.workbar__t{margin:0;min-width:0;flex:1 1 auto;overflow:hidden}
.workbar__t b{display:block;font-family:var(--f-display);font-size:var(--t-base);font-weight:600;
  line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.workbar__t span{display:block;font-family:var(--f-body);font-size:var(--t-meta);color:var(--muted);
  margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* Once the featured work is off screen the bar stops claiming to be about it: the
   named title and the price go, the ask stays, and the generic label takes their
   place. Two labels in the markup and one class deciding which is drawn, rather than
   script rewriting text a screen reader may already have announced. */
.workbar__t .wb-anon{display:none}
.workbar--anon .workbar__t .wb-named{display:none}
.workbar--anon .workbar__t .wb-anon{display:block}
.workbar__acts{display:flex;gap:8px;flex:none}
.workbar .btn{min-height:44px;padding:0 16px;font-size:var(--t-micro)}
/* The review chrome is fixed to the same edge. Clear it while it is there. */
body:has(#tswitch) .workbar{bottom:76px}
/* And the review LAUNCHER is fixed to the same corner, which the bar above did not
   account for. `.rv-launch` sits at bottom:86px with z-index 70; this bar sits at 76px
   with z-index 44, so on a work page the "Ask for a change" pill painted straight over
   Inquire: the one control the page exists to offer, covered on all thirteen work pages.
   review.js injects its own styles at runtime, so this is written to out-specify them
   rather than to out-order them. */
body:has(.workbar) .rv-launch{bottom:calc(76px + 65px + 14px)}
@media (max-width:700px){body:has(.workbar) .rv-launch{bottom:calc(64px + 62px + 10px)}}
@media (max-width:700px){
  body:has(#tswitch) .workbar{bottom:64px}
  .workbar__in{gap:10px;padding:0 14px}
  .workbar__t b{font-size:var(--t-small)}
  .workbar__t span{font-size:var(--t-label)}
  .workbar .btn{padding:0 12px;font-size:var(--t-micro)}
}
/* A landscape phone: the bar must not eat the artwork it is selling. */
@media (max-height:520px){
  .workbar{padding:5px 0 calc(5px + env(safe-area-inset-bottom,0px))}
  /* The bar gets tighter, the targets do not: 44px is what a thumb needs and a landscape
     phone is where the page is most likely held in one hand. The room comes out of the
     padding and the type instead. */
  .workbar__t b{font-size:var(--t-meta)}
  .workbar__t span{font-size:var(--t-micro)}
  .workbar .btn{padding:0 12px;font-size:var(--t-micro)}
}
/* Nothing on the page should end underneath it. The bar is emitted before the footer, so
   the footer is the element that needs the clearance. */
body:has(.workbar) .site-foot{padding-bottom:132px}
@media (max-width:700px){body:has(.workbar) .site-foot{padding-bottom:150px}}

/* The work you arrived from, shown on the inquiry page so context is visibly carried. */
/* The gallery asking its own question, in place of the browser's grey slab. Square,
   hairline, paper: the same language as everything else here, because a dialog that
   arrives in the operating system's clothes is the one moment a careful site stops
   looking like itself. */
.siteask{position:fixed;inset:0;z-index:120;background:rgba(22,22,26,.55);
  display:grid;place-items:center;padding:20px}
.siteask__panel{background:var(--paper);border:1px solid var(--rule-2);width:100%;
  max-width:440px;padding:26px;box-sizing:border-box;box-shadow:0 24px 60px rgba(22,22,26,.22)}
.siteask__t{font-family:var(--f-display);font-size:var(--t-title);line-height:1.2;margin:0 0 10px}
.siteask__b{font-size:var(--t-small);line-height:1.6;color:var(--ink-2);margin:0}
.siteask__i{width:100%;box-sizing:border-box;font:inherit;font-size:var(--t-base);margin-top:16px;
  padding:12px 13px;min-height:48px;border:1px solid var(--rule-2);background:var(--plate);
  color:var(--ink);border-radius:0}
.siteask__i:focus{outline:2px solid var(--ink);outline-offset:1px}
.siteask__row{display:flex;gap:10px;justify-content:flex-end;margin-top:22px;flex-wrap:wrap}
.siteask__row .btn{min-height:46px}
@media (max-width:520px){
  .siteask__panel{padding:20px}
  .siteask__row .btn{flex:1 1 auto;justify-content:center}
}

.askplate{display:flex;gap:18px;align-items:center;background:var(--plate);
  border:1px solid var(--rule);padding:16px;margin:0 0 26px}
.askplate img{width:104px;height:104px;object-fit:contain;background:var(--sunk);flex:none}
.askplate__k{font-family:var(--f-body);font-size:var(--t-micro);letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted);margin:0 0 6px}
.askplate__t{font-family:var(--f-display);font-size:var(--t-title);line-height:1.15;margin:0}
.askplate__a{font-family:var(--f-body);font-size:var(--t-small);color:var(--ink-2);margin:4px 0 0}
@media (max-width:560px){
  .askplate{gap:14px;padding:12px}
  .askplate img{width:78px;height:78px}
  .askplate__t{font-size:var(--t-lead)}
}

/* An event with no page of its own is a record, not a link: same shape, no affordance. */
.row--flat{cursor:default}
.row--flat:hover{background:transparent}
.row--flat .row__t{color:var(--ink)}

/* ================= tool chrome on a touch screen =================
   Measured with real coarse-pointer emulation, the two tools were already close: the Desk
   had nothing under 44px and the Studio had exactly two, its Undo button at 34px and the
   position search field at 24px. (A first pass at this counted 8 and 398, because the
   harness had set a phone viewport without enabling touch, so `pointer:coarse` never
   matched and none of the rules further up this file applied. A viewport is not a finger.)

   So this block finishes a job that was mostly already done, and it does it only where the
   pointer is actually coarse, leaving mouse density alone. The selectors carry one extra
   class each because theme.css loads before desk.css and studio.css, and a tie on
   specificity would go to whichever of those two came last. */
@media (pointer:coarse){
  .dk-body .railtoggle,.dk-body .dk__search,.dk-body .toolsw a,
  .dk-body .rail__item,.dk-body .dk__brand a{min-height:44px}
  .dk-body .toolsw a{display:inline-flex;align-items:center;padding-inline:10px}
  .st .st__undo1,.st .st__hide,.st .st__publish,.st .st__view,
  .st .st__top a,.st #posList button,.st #library button,
  .st .st__pgq input,.st #posQ{min-height:44px}
  .st .st__top a{display:inline-flex;align-items:center}
}

/* The Studio's one size below the site's 11px floor that is actually a control. Eleven is
   not a generous size, it is the smallest the rest of the site sets anything, and this is
   a button rather than a label.

   The other 441 elements under 11px are the pixel-dimension badges on the library
   thumbnails, "2500x3333" and the like. They are deliberately 10px and they stay: a
   dimension badge is glanceable metadata on a dense grid of 128 photographs, not reading
   text, and inflating all of them would cost the grid to fix nothing. Counting them as
   defects, as a first pass at this did, is how a legibility floor turns into churn. */
.st .st__view{font-size:var(--t-label)}

/* ---------------- BROWSING: the standing rail beside a grid of works
   Chosen 11 August over three quieter control bars. At 387 works by 99 artists the useful
   thing is seeing that 294 are available and 340 are paintings before touching anything,
   and a rail with counts is the only one of the four that says so at rest.

   Everything below degrades: with browse.js absent the rail is inert and every work is
   visible, which is the right failure for a gallery. The work never hides behind a
   control that might not run. */
.browse{display:grid;grid-template-columns:1fr;gap:30px}
@media (min-width:900px){
  .browse{grid-template-columns:206px 1fr;gap:0 46px;align-items:start}
  /* An exhibition checklist ships without the rail, 25 August. The 206px column has to
     go with it or the grid keeps a column of nothing and the works run narrow. */
  .browse--norail{grid-template-columns:1fr}
  .rail{position:sticky;top:calc(var(--hdr) + 18px)}
}
.rail{display:block;margin:0}
.rail__srch{display:block;margin-bottom:26px}
.rail__q{width:100%;border:1px solid var(--rule);background:var(--paper);color:var(--ink);
  font-family:var(--f-body);font-size:var(--t-small);padding:10px 12px;border-radius:0;
  -webkit-appearance:none;appearance:none;min-height:44px}
.rail__q::placeholder{color:var(--muted)}
.rail__q:focus-visible{outline:2px solid var(--ink);outline-offset:1px}
.rail__grp{margin-bottom:24px}
.rail__h{font-family:var(--f-body);font-size:var(--t-label);letter-spacing:var(--ctrack);
  text-transform:uppercase;color:var(--muted);font-weight:500;margin:0 0 8px}
.rail__list{list-style:none;margin:0;padding:0}
.rail__list li{margin:0}
/* 44px on coarse pointers, per the site's own tap-target rule, without opening the rows
   out so far on a mouse that the rail becomes a column of buttons. */
.fct{display:flex;width:100%;align-items:baseline;justify-content:space-between;gap:10px;
  background:none;border:0;padding:5px 0;font-family:var(--f-body);font-size:var(--t-small);
  color:var(--muted);text-align:left;cursor:pointer;line-height:1.45}
/* Keyed on WIDTH as well as pointer type. Keying it on `pointer:coarse` alone meant the
   44px target existed on a phone and not in a phone-width window, and the audit that
   measures a 390px viewport in a desktop browser was right to fail it: the layout is the
   phone layout at that width whatever is pointing at it. */
@media (pointer:coarse),(max-width:899px){.fct{min-height:44px;padding:9px 0}}
/* The count was #d2d1cb, which is 1.53:1 on this paper: measured, not guessed, and far
   under the 4.5 a 12.5px number has to clear. It is meant to be quieter than the label it
   follows, not invisible, and --muted is already the quiet step that clears at 5.76. The
   selected state keeps its own colour so the two are still told apart. */
.fct b{font-weight:400;font-size:var(--t-meta);color:var(--muted);
  font-variant-numeric:tabular-nums}
.fct:hover{color:var(--ink)}
.fct.is-on{color:var(--ink);box-shadow:inset 0 -1px 0 var(--accent,#8f2118)}
.fct.is-on b{color:var(--ink-2)}
.fct[disabled]{opacity:.38;cursor:default}
.fct:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
.rail__clear{background:none;border:0;padding:12px 0;min-height:44px;font-family:var(--f-body);
  font-size:var(--t-label);letter-spacing:var(--ctrack);text-transform:uppercase;
  color:var(--accent,#8f2118);cursor:pointer}
.rail__clear:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
.wk-none{margin:30px 0;color:var(--muted)}
.wk-more{margin:34px 0 0;text-align:center}
.vh{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
/* Without the script every work shows, including the ones the generator marked as beyond
   the first eight. The class is added by browse.js, so this only applies when it ran. */
.browse--live .wk[hidden]{display:none}
/* The one control that reveals the rest of a show. `.btn--quiet` sets min-height:0 by
   design, which is right for an inline text link and wrong for the button a visitor taps
   to see the other fourteen works. Scoped here rather than by loosening .btn--quiet,
   which would change every quiet button on the site to fix one. */
.wk-all{min-height:44px;padding:10px 2px}
/* Phone: the work leads, the controls fold.
   Stacked above the grid, eight facet groups put a screen and a half of controls between
   a visitor and the first painting. Search and availability stay out because they are the
   two questions somebody actually arrives with; type and sort fold behind one button. */
.rail__toggle{display:none;width:100%;align-items:center;justify-content:space-between;
  gap:10px;background:none;border:0;border-top:1px solid var(--rule);border-bottom:1px solid var(--rule);
  padding:13px 0;min-height:44px;font-family:var(--f-body);font-size:var(--t-label);
  letter-spacing:var(--ctrack);text-transform:uppercase;color:var(--ink);cursor:pointer}
.rail__toggle::after{content:"+";font-size:15px;letter-spacing:0;color:var(--muted)}
.rail.is-open .rail__toggle::after{content:"\2212"}
.rail__toggle:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
@media (max-width:899px){
  .rail__toggle{display:flex}
  .rail__more{display:none;padding-top:18px}
  .rail.is-open .rail__more{display:block}
  .rail__grp:first-of-type{margin-bottom:18px}
  /* Availability reads as one row of three at this width, not a stacked list. */
  .rail__grp:first-of-type .rail__list{display:flex;flex-wrap:wrap;gap:0 22px}
  .rail__grp:first-of-type .fct{width:auto;gap:6px}
}

/* ---------------- THE EXHIBITION SLIDESHOW HERO
   A show's flagship images belong in one place, shown one at a time at full size, rather
   than one on top and the rest in a two-up grid halfway down where neither is a hero nor
   a checklist.

   The plate rules are unchanged and deliberately so: the work is CONTAINED, never cropped,
   and the frame keeps exactly the height the single-image hero had, so adding a slideshow
   moved nothing else on the page. */
.hero--slides .hero__media{padding-bottom:clamp(16px,2.4vw,26px)}
.slides{position:relative}
.slides:focus-visible{outline:2px solid var(--ink);outline-offset:6px}
.slides__track{list-style:none;margin:0;padding:0;position:relative;
  height:min(66vh,620px);height:min(66dvh,620px)}
.slide{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  opacity:0;transition:opacity .7s var(--ease);pointer-events:none}
.slide.is-on{opacity:1;pointer-events:auto}
.slide img{max-width:100%;max-height:100%;width:auto;height:auto;object-fit:contain;
  margin:0 auto;display:block}
/* Without the script the first slide is simply the hero: the others stack behind it at
   zero opacity and nothing is lost, because every one of them is still in the document. */
.slides--live .slide{will-change:opacity}

.slides__nav{position:absolute;top:0;bottom:0;width:clamp(52px,9%,96px);border:0;
  background:none;cursor:pointer;opacity:0;transition:opacity .25s var(--ease);z-index:2}
.slides__nav--prev{left:0}
.slides__nav--next{right:0}
.slides__nav::after{content:"";position:absolute;top:50%;left:50%;width:13px;height:13px;
  border-right:1px solid var(--ink);border-bottom:1px solid var(--ink)}
.slides__nav--prev::after{transform:translate(-40%,-50%) rotate(135deg)}
.slides__nav--next::after{transform:translate(-60%,-50%) rotate(-45deg)}
.hero--slides:hover .slides__nav,.slides__nav:focus-visible{opacity:1}
.slides__nav:focus-visible{outline:2px solid var(--ink);outline-offset:-6px}
/* A phone has no hover to reveal them with, and a target that appears only on hover is a
   target a thumb can never find. */
@media (pointer:coarse){.slides__nav{opacity:1}}

.slides__bar{display:flex;align-items:center;justify-content:center;gap:16px;
  margin-top:clamp(14px,2vw,20px)}
.slides__dots{display:flex;align-items:center;justify-content:center;flex-wrap:wrap;
  gap:2px 6px;max-width:100%}
/* 44 wide as well as 44 tall. The mark inside stays 30px, so the row reads the same and
   the target is the size a thumb actually needs. */
.slides__dot{width:44px;height:44px;padding:0;border:0;background:none;cursor:pointer;
  position:relative;flex:0 0 auto}
.slides__dot::after{content:"";position:absolute;left:50%;top:50%;width:30px;height:1px;
  background:var(--hair);transform:translate(-50%,-50%);transition:background .25s var(--ease)}
.slides__dot.is-on::after{background:var(--ink);height:2px}
.slides__count{margin:0;font-family:var(--f-body);font-size:var(--t-label);
  letter-spacing:var(--ctrack);color:var(--muted);font-variant-numeric:tabular-nums;display:none}
.slides__dot:hover::after{background:var(--muted)}
.slides__dot:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
.slides__play{width:44px;height:44px;flex:0 0 44px;border:0;background:none;cursor:pointer;
  position:relative}
.slides__play::before{content:"";position:absolute;top:50%;left:50%;
  transform:translate(-50%,-50%);width:9px;height:11px;
  border-left:2px solid var(--muted);border-right:2px solid var(--muted)}
.slides--paused .slides__play::before{width:0;height:0;border:0;
  border-left:9px solid var(--muted);border-top:6px solid transparent;
  border-bottom:6px solid transparent}
.slides__play:hover::before{border-color:var(--ink)}
.slides__play:focus-visible{outline:2px solid var(--ink);outline-offset:2px}

/* Past about eight images a row of dots is wider than the screen it sits on, and on a
   phone that is true almost immediately. The count says the same thing in 40px. */
.slides__bar--many .slides__dots{display:none}
.slides__bar--many .slides__count{display:block}
@media (max-width:620px){
  .slides__track{height:min(52vh,420px);height:min(52dvh,420px)}
  .slides__dots{display:none}
  .slides__count{display:block}
}
/* The ladder the site's own hero rule asks for: a landscape phone gets a shorter frame
   rather than a hero that pushes everything else past the fold. */
@media (max-height:620px){.slides__track{height:min(58vh,420px);height:min(58dvh,420px)}}
@media (max-height:460px){.slides__track{height:min(62vh,300px);height:min(62dvh,300px)}}

@media (prefers-reduced-motion:reduce){
  .slide{transition:none}
  .slides__nav{transition:none}
}


/* ---------------- the accepted-artist form ----------------
   Carole's field list from 1 September, in the gallery's own form furniture. Only the
   pieces .form did not already have are here: a group heading, the two and three column
   rows, and the follow-up that opens under whichever delivery choice was made. */
.field>legend{display:block;padding:0;float:left;width:100%;
  font-family:var(--f-display);font-size:var(--t-minor);color:var(--ink);margin:0 0 14px}
.field>legend+*{clear:both}
.fld{display:block;min-width:0}
.fld2{display:grid;grid-template-columns:1fr 1fr;gap:14px}
/* Address line, then city wide with state and ZIP beside it: the two short answers do not
   deserve a row each, and on a phone City keeps the full width because a street name is
   the long one. */
.fld3{display:grid;grid-template-columns:2fr 1fr 1fr;gap:14px}
@media (max-width:560px){
  .fld2{grid-template-columns:1fr}
  .fld3{grid-template-columns:1fr 1fr}
  .fld3>:first-child{grid-column:1/-1}
}
/* The follow-up question, indented to sit under the choice that opened it. 33px is the
   checkbox plus its gap, so the question lines up with the words above it rather than
   with the control. */
.fld__then{margin:4px 0 16px 33px}
.fld__then label{display:block;font-family:var(--f-body);font-size:var(--t-small);
  color:var(--ink-2);margin:0 0 6px}
@media (max-width:420px){.fld__then{margin-left:0}}
/* A full hairline, not a 3px left stripe. The stripe was the one piece of borrowed
   grammar in the sheet; every other boundary here is a 1px rule, and the tinted ground
   plus the red ink already carry the meaning without an accent bar. */
.form__err{margin:22px 0 0;padding:12px 16px;border:1px solid #8f2118;
  background:var(--sunk);color:#8f2118;font-size:var(--t-minor);line-height:1.5}
.form__note{font-family:var(--f-body);font-size:var(--t-label);letter-spacing:var(--ctrack);
  text-transform:uppercase;color:var(--muted)}
/* What they told the gallery, read back. Not a receipt design: it is the same plate the
   form was in, so the page does not appear to change identity at the moment it succeeds. */
.done__grid{display:grid;grid-template-columns:auto 1fr;gap:10px 22px;margin:18px 0 0;
  font-size:var(--t-minor)}
.done__k{font-family:var(--f-body);font-size:var(--t-label);letter-spacing:var(--ctrack);
  text-transform:uppercase;color:var(--muted);padding-top:2px}
.done__v{color:var(--ink);margin:0}
@media (max-width:520px){
  .done__grid{grid-template-columns:1fr;gap:2px 0}
  .done__v{margin:0 0 12px}
}

/* Explicit, because `hidden` is only a default and this sheet already overrides it once
   (.vs__s[hidden] is left to the user agent now; see the note at the slide rules). Anything on this form
   that hides has to say so in a rule that outranks whatever it inherits. */
#accepted-form[hidden],#af-done[hidden],.fld__then[hidden],.form__err[hidden],
.form__note[hidden]{display:none!important}

/* 44px on every tick box row. `.checks .check` already had this and standalone `.check`
   never did, so the two rows on the Connect form and every row on the accepted-artist
   form came out at 37px: under the floor, and it is a form filled with a thumb. The
   label is the target, not the 19px box inside it, which is exactly why the label is the
   thing that has to be 44 tall. */
#accepted-form .check{min-height:44px;align-items:center}
#accepted-form .fld__then label{min-height:0}

/* ---------------- accepted artists, the gallery's board ---------------- */
.ac-list{list-style:none;margin:0;padding:0}
.ac-list li{padding:12px 0;border-bottom:1px solid var(--rule);font-size:var(--t-minor)}
.ac-list li:last-child{border-bottom:0}
.ac-card{background:var(--plate);border:1px solid var(--rule);padding:22px 24px;margin:0 0 16px}
.ac-card h3{font-size:var(--t-minor);margin:0 0 6px}
.ac-terms{color:var(--muted);font-size:var(--t-label);line-height:1.5}
/* The table scrolls inside its own box rather than pushing the page sideways. Six columns
   of an install sheet do not fit a phone and never will; what must not happen is the rest
   of the page moving with them. */
.ac-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
.ac-tbl{border-collapse:collapse;width:100%;min-width:640px;font-size:var(--t-base)}
.ac-tbl th,.ac-tbl td{text-align:left;padding:10px 14px;border-bottom:1px solid var(--rule);
  vertical-align:top}
.ac-tbl th{font-family:var(--f-body);font-size:var(--t-label);letter-spacing:var(--ctrack);
  text-transform:uppercase;color:var(--muted);font-weight:500}
/* Hanging day is the one time this site is printed, so the sheet is the only thing on the
   paper: no header, no footer, no navigation, no roster editor, and the table gets its
   full width back because nothing has to scroll on paper. */
@media print{
  body *{visibility:hidden}
  .ac-print,.ac-print *{visibility:visible}
  .ac-print{position:absolute;left:0;top:0;width:100%}
  .ac-print .btn,.ac-noprint{display:none!important}
  .ac-scroll{overflow:visible}
  .ac-tbl{min-width:0;font-size:11pt}
  .ac-tbl th,.ac-tbl td{padding:6px 8px}
}

/* ---------------- the accepted artist form's heading ----------------
   The letterhead, picked from a board of six on 1 September after the first version read
   as three type treatments doing two jobs. The show and its dates share one line above a
   rule; everything below the rule is the form addressing one person. Held to 46rem, the
   same measure as `.form` underneath, because the earlier block ran the full wrap width
   and the mismatch is what made a correctly aligned page look misaligned. */
.form-head{max-width:46rem}
.form-mark{font-family:var(--f-body);font-size:var(--t-small);color:var(--ink);line-height:1.45;
  margin:0 0 20px;padding:0 0 14px;border-bottom:1px solid var(--rule);
  display:flex;justify-content:space-between;align-items:baseline;gap:14px 28px;flex-wrap:wrap}
.form-mark span:last-child{color:var(--muted)}
/* On a phone the two halves stack and both go left. Pushed apart they read as a header row
   with a hole in the middle, which is a desktop idea surviving where it does not fit. */
@media (max-width:560px){.form-mark{display:block}.form-mark span:last-child{display:block;margin-top:3px}}
.form-title{margin:0 0 14px;max-width:20ch}
.form-lede{margin:0;max-width:54ch}
/* The one fact that belongs beside a question rather than in a header nobody rereads. */
.fld__note{font-size:var(--t-base);color:var(--muted);line-height:1.5;margin:14px 0 0;max-width:46ch}
