@font-face { font-family: 'Instrument Sans'; font-style: normal; font-weight: 400 600; font-display: swap;
  src: url(/fonts/instrument-sans-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: 'Instrument Sans'; font-style: normal; font-weight: 400 600; font-display: swap;
  src: url(/fonts/instrument-sans-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1E00-1E9F, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
/* David Hamilton — tokens.css (published to the canvas as site.css)
   The single source of design tokens and shared classes. Every board and page links it.
   Rules: four colours, the space scale below, the closed type set. Nothing else. */

:root {
  /* colour — four, plus the photo mat; no accent */
  --paper: #fffffc;     /* warm white */
  --ink: #121110;       /* warm black */
  --graphite: #6a6a66;   /* 5.4:1 on paper */
  --rule: #e6e5e1;       /* hairlines only */

  /* type */
  --sans: 'Instrument Sans', system-ui, sans-serif;   /* the one typeface, 400/500/600 (Nic, 28 Sep 2026: no serif) */
  --t-s: 13px; --t-m: 15px; --t-l: 20px;               /* the three sizes: small · reading · page title. Quiet, as artists' and estates' own sites (12–15; design audit 5, Nic 29 Sep: "big and cheap") */
  --e-s: 18px; --e-m: 20px; --e-l: 32px;               /* the editor's own larger set, for David */
  --e-radius: 0;         /* the editor's bar, toolbar and menus: square like the site (Nic, 29 Sep: no pills) */

  /* space scale: 8 · 16 · 24 · 32 · 48 · 64 · 96 · 160 (96 and 160: rows and sections, Nic 4 Oct: "give stuff more room and white space") */
  --s0: 4px;   /* inside a caption only: title → meta */
  --s1: 8px; --s2: 16px; --s3: 24px; --s4: 32px; --s5: 48px; --s6: 64px; --s7: 96px; --s8: 160px;

  /* layout */
  --margin: 72px;
  --gutter: 40px;
  --header: 56px;
  --header-phone: 52px;  /* phone header (also on the canvas phone boards) */
  --measure: 560px;      /* reading width: about 74 characters at 15 px (640 ran to 84, past a catalogue's 60–75, and crowded the About portrait; Nic, 30 Sep) */
  --logo: 32px; --logo-phone: 28px; --logo-footer: 20px;
  --thumb: 64px;         /* Index list thumbnail: the box each photo sits in, whole */
  --grid-h: 240px;       /* Index grid view: every photo this tall, whole (audit 5 fix 10) */
  --screen: calc(100svh - var(--header) - var(--s5) - var(--s3));   /* the tallest a photo is drawn: the window under the header, with air (772 at 900; site/rows.mjs › SCREEN) */
  --year-col: 128px;     /* CV and list rows: year column */
  --tap: 44px;           /* smallest tap target on phones */
  --underline: 3px;      /* underline and link-underline offset */
  --check: 24px;         /* editor checkbox */
  --focus: 2px;          /* keyboard focus ring */

  /* motion */
  --ease: cubic-bezier(.16, 1, .3, 1);
  --fast: 180ms;         /* hover, underline */
  --move: 400ms;         /* viewer crossfade, menu, CV sections, between pages */
  --slow: 700ms;
  --gentle: 1100ms;      /* photos and blocks arriving on scroll: a long, quiet fade */
  --ease-soft: cubic-bezier(.25, .1, .25, 1);   /* arriving on scroll: eases in and out, no snap (Nic, 30 Sep) */
}
/* The editor keeps its larger, calmer spacing (it is for David, not a showcase): the scale before the 28 Sep review. */
.editor { --s4: 48px; --s5: 72px; --s6: 96px; --measure: 680px; }
@media (max-width: 760px) {
  :root { --margin: 16px; --header: var(--header-phone); --thumb: 48px; --grid-h: 132px; --year-col: 88px; }
}

*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; background: var(--paper); color: var(--ink); font-family: var(--sans); -webkit-font-smoothing: antialiased; }
a { color: var(--ink); text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
img { display: block; }

/* page frame */
.page { background: var(--paper); color: var(--ink); font-family: var(--sans); display: flex; flex-direction: column; min-height: 100dvh; }   /* the footer at the foot of a short page */
.wrap { padding: 0 var(--margin); }
.grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gutter); }
.stack { display: flex; flex-direction: column; }

/* type — one family, three sizes: 20 (page title), 15 (reading, headings, names), 13 (captions, links, facts); no
   letter-spacing; 500 for names and headings, never bold. A heading is never smaller than the text it heads. The
   editor has its own, larger set. */
.t-title   { margin: 0; font-weight: 500; font-size: var(--t-l); line-height: 1.3; }                                /* page title, phone menu */
.t-tile    { margin: 0; font-weight: 500; font-size: var(--t-m); line-height: 1.4; }                                /* series and CV section names */
.t-work    { font-style: normal; font-weight: 500; font-size: var(--t-s); line-height: 1.45; }                       /* work titles, under photos and in lists */
.t-work-lg { margin: 0; font-style: normal; font-weight: 500; font-size: var(--t-m); line-height: 1.4; }            /* a work's or a show's own title */
.t-brand   { font-weight: 500; font-size: var(--t-m); line-height: 1; }                                              /* the name beside the mark */
.t-lead    { margin: 0; font-size: var(--t-m); line-height: 1.6; max-width: var(--measure); }                        /* intros, bio */
.t-intro   { margin: 0; font-size: var(--t-l); line-height: 1.5; text-wrap: pretty; }                                /* Home's biography, its headline (Nic, 4 Oct) */
.t-body    { margin: 0; font-size: var(--t-m); line-height: 1.6; }
.t-ui      { font-size: var(--t-s); line-height: 1.45; }                                                             /* nav, links, controls */
.t-meta    { font-size: var(--t-s); line-height: 1.45; color: var(--graphite); }
.t-label   { margin: 0; font-size: var(--t-m); font-weight: 500; line-height: 1.4; color: var(--ink); }              /* section headings: never smaller than the text they head */
.e-title   { margin: 0; font-size: var(--e-l); font-weight: 500; line-height: 1.2; }
.e-text    { font-size: var(--e-s); line-height: 1.45; }                     /* names, checkboxes, the status bar, errors */
.e-heading { margin: 0; font-size: var(--e-m); font-weight: 500; line-height: 1.3; }
.e-label   { font-size: var(--e-s); font-weight: 500; line-height: 1.4; color: var(--ink); }
.e-help    { font-size: var(--e-s); line-height: 1.5; color: var(--graphite); }
.e-link    { font-size: var(--e-s); line-height: 1.4; }

/* links: underline draws in. Links inside running text (.inline) are always underlined, so they can be seen. */
.u { padding-bottom: var(--underline); background: linear-gradient(var(--ink), var(--ink)) left bottom / 0 1px no-repeat; transition: background-size var(--fast) var(--ease); }
.u:hover, .u.on, a:hover > .u, button:hover > .u { background-size: 100% 1px; }
a.inline, .inline a { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: var(--underline); text-decoration-color: var(--graphite); transition: text-decoration-color var(--fast) var(--ease); }
a.inline:hover, .inline a:hover { text-decoration-color: var(--ink); }

/* a caption under a photo: the title (its year beside it, not bold), then its facts (site/html.mjs › caption) */
.caption { padding-top: var(--s1); display: flex; flex-direction: column; gap: var(--s0); }
.t-work .t-meta { font-weight: 400; }

/* lists: an ink rule marks the start of a list; hairlines between rows */
.list { border-top: 1px solid var(--ink); }
.row { display: grid; column-gap: var(--gutter); align-items: baseline; padding: var(--s2) 0; border-bottom: 1px solid var(--rule); }

/* controls */
/* filter: quiet text, the chosen one in ink and underlined; no boxes */
.chip { font-size: var(--t-s); line-height: 1.45; padding: var(--s0) 0; border: 0; background: none; color: var(--graphite); }
.chip:hover { color: var(--ink); }
.chip[aria-pressed="true"], .chip.on { color: var(--ink); text-decoration: underline; text-underline-offset: var(--underline); text-decoration-thickness: 1px; }
.btn { font-size: var(--e-s); line-height: 1; padding: var(--s2) var(--s3); border: 1px solid var(--ink); background: var(--paper); color: var(--ink); }
.btn.primary { background: var(--ink); color: var(--paper); }
.field { display: flex; flex-direction: column; gap: var(--s1); }
.field input, .field textarea, .field select { font: inherit; font-size: var(--e-m); line-height: 1.5; padding: var(--s1) 0; border: 0; border-bottom: 1px solid var(--ink); background: transparent; color: var(--ink); resize: vertical; }
@media (max-width: 760px) { .chip { min-height: var(--tap); } }

/* focus: one ring everywhere */
:where(a, button, input, textarea, select, [tabindex]):focus-visible { outline: var(--focus) solid var(--ink); outline-offset: var(--s0); }
:where(a, button, [tabindex]):focus:not(:focus-visible) { outline: none; }   /* no ring after a mouse click (design review 8) */
.field input:focus-visible, .field textarea:focus-visible { outline: 0; border-bottom-width: var(--focus); }

/* motion — one curve; opacity, and on scroll a gentle fade with a 4 px drift (Nic, 30 Sep; no tilt, no bounce); the mark steps, it never fades. Only entrances start
   invisible (photos on scroll, lead text). */
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes drop { from { opacity: 0; transform: translateY(calc(-1 * var(--s1))); } to { opacity: 1; transform: none; } }   /* CV lines as a section opens */
.xfade { transition: opacity var(--move) var(--ease); }            /* viewer: stacked photos, one at opacity 1 */
/* text: the lead fades in as one block (not paragraph by paragraph, Nic). Titles simply appear (no write-on: Nic, 28 Sep). */
.lead-in { animation: fade var(--slow) var(--ease) both; }
.mark { display: block; }
/* the mark is still: the traced woodcut, no animation (Nic, 5 Oct: "get rid of the logo animation") */
/* photos show as they load and stay still: never hidden waiting for a script or a scroll (Nic, 29 Sep) */
/* between pages: a soft cross-fade (browsers that support it) */
@view-transition { navigation: auto; }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: var(--move); animation-timing-function: ease; }

@media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition: none !important; animation: none !important; } }

/* Site layout on top of design/tokens.css. Tokens only: colours, space, type and motion come from there.
   Design review, 28 Sep 2026 (docs/audit/2026-09-28-DESIGN-REVIEW.md): a thin solid header, small page titles, the
   work near the top of every page, headings above their text (no empty label column), one-line footer. */

.skip { position: absolute; left: -999em; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.skip:focus { left: var(--margin); top: var(--s1); z-index: 20; background: var(--paper); padding: var(--s1); }
main { flex: 1; }
.col-7 { grid-column: 1 / span 7; }
/* A page's opening spread, one implementation (About, Foundry; Nic, 6 Oct: "the photos are in different placements"):
   the words in the first six columns, the photo from the seventh to the edge, both from the top; a phone shows the
   photo first. */
.spread { align-items: start; row-gap: var(--s5); }
.spread-text { grid-column: 1 / span 6; }
.spread-photo { grid-column: 7 / -1; min-width: 0; }
.portrait-col img { display: block; width: 100%; height: auto; }
.portrait-col .portrait { margin: 0; }

/* header: solid paper; a hairline appears once the page has moved (no blur, no fade: design review 2) */
.site-header { position: sticky; top: 0; z-index: 10; background: var(--paper); view-transition-name: header; }   /* stays put between pages */
.bar { height: var(--header); display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid transparent; transition: border-color var(--move) var(--ease); }
.site-header.scrolled .bar { border-bottom-color: var(--rule); }
.brand { display: flex; align-items: center; gap: var(--s2); min-height: var(--tap); }
.brand .mark { width: var(--logo); height: var(--logo); }
.foot-brand .mark { width: var(--logo-footer); height: var(--logo-footer); }
.nav { display: flex; align-items: center; gap: var(--s3); }
.nav > a, .nav-work > a { display: flex; align-items: center; line-height: 1; }
.burger { display: none; width: var(--s5); height: var(--s5); align-items: center; justify-content: flex-end; }
.menu { position: fixed; top: var(--header); left: 0; right: 0; height: calc(100dvh - var(--header)); overflow-y: auto; background: var(--paper); padding: var(--s4) var(--margin); display: flex; flex-direction: column; gap: var(--s2); animation: fade var(--move) var(--ease); }
.menu[hidden] { display: none; }
.menu > a { display: flex; align-items: center; min-height: var(--tap); }   /* a finger's size (audit 6 A7) */
.menu .series-list { display: grid; grid-template-columns: 1fr 1fr; column-gap: var(--s2); padding: 0 0 var(--s2) var(--s3); }   /* two columns: About and Contact stay on screen */
.menu .series-list a { display: flex; align-items: center; min-height: var(--tap); }
.nav-work { position: relative; display: flex; align-items: center; gap: var(--s0); }
.drop-btn { display: flex; align-items: center; justify-content: center; width: var(--s2); height: var(--s2); color: var(--graphite); }
.drop-btn svg { transition: transform var(--fast) var(--ease); }
.work-drop { display: none; position: absolute; top: 100%; left: calc(-1 * var(--s3)); padding: var(--s2) var(--s3); margin-top: var(--s1); background: var(--paper); border: 1px solid var(--rule); z-index: 20; animation: fade var(--fast) var(--ease); }
.work-drop::before { content: ''; position: absolute; left: 0; right: 0; bottom: 100%; height: var(--s2); }   /* keeps hover alive across the gap */
.nav-work:hover .work-drop, .nav-work.open .work-drop { display: block; }   /* keyboard: the arrow button opens it (not on focus, so Tab is not led through every series) */
.nav-work.shut .work-drop { display: none; }
.nav-work:hover .drop-btn svg, .nav-work.open .drop-btn svg { transform: rotate(180deg); }
.series-list { list-style: none; margin: 0; padding: 0; }
.work-drop a { display: flex; justify-content: space-between; gap: var(--s4); padding: var(--s0) 0; white-space: nowrap; }   /* name, then its years */

/* page rhythm: header → title 32 · title → content 24 · sections 64 apart */
.page-title { padding-top: var(--s4); padding-bottom: var(--s3); display: flex; justify-content: space-between; align-items: baseline; gap: var(--s3); }
.page-title .aside { display: inline-flex; align-items: center; gap: var(--s1); white-space: nowrap; }
.intro { padding-top: var(--s4); padding-bottom: var(--s4); }
.intro-text { padding-bottom: var(--s4); gap: var(--s2); }
.more-text > summary { padding-top: var(--s1); }
.more-text[open] > summary { display: none; }
.bio { gap: var(--s2); }
.section { padding-top: var(--s8); }
.cv-all { padding-top: var(--s6); }
.section-head { padding-bottom: var(--s3); display: flex; flex-direction: column; gap: var(--s1); max-width: var(--measure); }
.more { padding-top: var(--s5); }
.gap { gap: var(--s1); }

/* next series: one line above the footer */
nav.next { margin-top: var(--s8); }
.next-in { border-top: 1px solid var(--rule); padding: var(--s3) 0; display: flex; align-items: baseline; gap: var(--s2); }

/* about, foundry */
details > summary { list-style: none; cursor: pointer; }
details > summary::-webkit-details-marker { display: none; }
.cv-head { grid-template-columns: 1fr var(--s5) var(--s5); }
.cv-head::after { content: 'Show'; text-align: right; font-size: var(--t-s); color: var(--graphite); }
details[open] > .cv-head::after { content: 'Hide'; }
details[open] .cv-rows { animation: drop var(--move) var(--ease) both; padding-bottom: var(--s4); }
.cv-row { grid-template-columns: var(--year-col) minmax(0, var(--measure)) auto; justify-content: start; }   /* View work right after its line */
.cv-row .view { white-space: nowrap; }
.links { display: flex; flex-wrap: wrap; column-gap: var(--s2); padding-top: var(--s0); overflow-wrap: anywhere; }   /* a long address breaks only where it cannot fit (320 px) */
.two { grid-template-columns: 1fr 2fr; }
.casting { gap: var(--s2); max-width: var(--measure); }
.sources { list-style: none; margin: 0; padding: var(--s2) 0 0; display: flex; flex-direction: column; gap: var(--s0); }
.sources-head { padding-top: var(--s2); }

/* footer: one quiet line */
.site-footer { margin-top: var(--s8); }
.foot-in { border-top: 1px solid var(--rule); padding: var(--s3) 0 var(--s4); display: flex; flex-wrap: wrap; align-items: center; gap: var(--s1) var(--s4); }
.foot-in .foot-brand { gap: var(--s1); }
.foot-in .copy { margin-left: auto; }
.bio-action { padding-top: var(--s1); display: flex; gap: var(--s3); flex-wrap: wrap; }
nav.next + .site-footer, main:has(> nav.next:last-child) + .site-footer { margin-top: 0; }
nav.next + .site-footer .foot-in, main:has(> nav.next:last-child) + .site-footer .foot-in { border-top: 0; }

@media (max-width: 760px) {
  .nav { display: none; }
  .burger { display: flex; }
  .brand .mark { width: var(--logo-phone); height: var(--logo-phone); }
  .grid { display: flex; flex-direction: column; gap: var(--s3); }
  .page-title { padding-top: var(--s3); padding-bottom: var(--s2); flex-direction: column; gap: var(--s1); }
  .intro { padding-top: var(--s3); padding-bottom: var(--s3); }
  .cv-row { grid-template-columns: var(--year-col) minmax(0, 1fr); }
  .spread-photo { order: -1; }                                                       /* the photo before the words */
  .cv-row .view { grid-column: 2; }
  .foot-in { flex-direction: column; align-items: flex-start; gap: var(--s1); }
  .foot-in .copy { margin-left: 0; }
  /* tap targets: 44 px tall on phones */
  a.t-meta, .t-meta a, a.t-ui, .t-ui a, .caption a, .aside, .site-footer a, .project-facts h2 a, .links a, .sources a, .next-in a { display: inline-flex; align-items: center; min-height: var(--tap); }
}

/* the burger turns into a close mark while the menu is open */
.burger[aria-expanded="true"] .b-open, .burger:not([aria-expanded="true"]) .b-close { display: none; }
.edit-group { display: contents; }                                                /* words editable as one field (site/admin/page-edit.js); no box of their own */
.rich-list { margin: 0; padding-left: var(--s3); }                               /* a list David made in his words (site/rich.mjs) */
.rich-list li + li { margin-top: var(--s0); }
.intro-link { padding-bottom: var(--s4); margin: 0; }

/* Foundry (design audit 5 › Proposed Foundry page): the casting text opens the page; one large pour photo; the two
   commissions as project blocks, films and photos beside their words; the technique films. */
/* Chapters (Nic, 4 Oct: "editorial and pictorial in sections"): title and facts left, words beside at reading size,
   then the pictures across the full width; a wide space and a rule between chapters. */
.project.chapter, .project.chapter:first-child { display: flex; flex-direction: column; align-items: stretch; gap: var(--s6); padding: var(--s8) 0; border-top: 1px solid var(--rule); }
.chapter-head { align-items: start; row-gap: var(--s2); }
.chapter-title { grid-column: 1 / span 4; gap: var(--s1); }
.chapter-words { grid-column: 6 / -1; gap: var(--s2); max-width: var(--measure); }
.chapter-media { gap: var(--s7); }
.foundry-open + .foundry-projects { padding-top: var(--s6); }   /* the first chapter's rule and space follow */
/* The first chapter of a page opens under its title: no rule, no section's worth of space above it. */
:is(.projects, .ex-list) > .project.chapter:first-child { border-top: 0; padding-top: var(--s4); }
:is(.projects, .ex-list) > .project.chapter:last-child { padding-bottom: 0; }   /* the footer's own space follows, not twice (design audit, 6 Oct) */
.film-head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--s2); }
.works.films.even { display: flex; align-items: flex-start; gap: var(--gutter); }   /* two films at one height, each as wide as its shape */
.works.films.even > div { flex: var(--ar, 1.7778) 1 0; min-width: 0; }
@media (max-width: 760px) {
  .works.films.even { flex-direction: column; gap: var(--s5); }
  .works.films.even > div { flex: none; width: 100%; }
  .film-head { flex-wrap: wrap; }
}

/* arriving on scroll (site.js): hidden only once script marks it, then one gentle fade with a 4 px drift (Nic, 30 Sep:
   "fade in gently", not "clumsily slide up"): the whole row at once, on the soft curve, never its photos one by one */
@keyframes arrive { from { opacity: 0; transform: translateY(var(--s0)); } to { opacity: 1; transform: none; } }
/* A photo still loading when the page starts fades in when it arrives (site.js marks it; Nic, 4 Oct: the first screen
   too, since /#series opens on the photos). Links within a page glide to their place, below the sticky header. */
html { scroll-padding-top: var(--header); }
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }   /* no snapping: it was "too aggro"; a smooth glide only (Nic, 6 Oct) */
  img.loading { opacity: 0; }
  img.loaded { transition: opacity var(--slow) var(--ease-soft); }
}
.arrives { opacity: 0; }
.arrived { animation: arrive var(--gentle) var(--ease-soft) both; }

/* Home landing: whole photograph, normal scrolling, existing editable biography and contact. */
.landing { padding-top: var(--s4); padding-bottom: var(--s6); }
.landing-in { align-items: center; min-height: calc(100svh - var(--header) - var(--s4) - var(--s6)); row-gap: var(--s4); }
.landing-photo { grid-column: span 7; min-width: 0; }
.landing-figure { display: flex; width: fit-content; max-width: 100%; margin: 0 auto; }   /* the photo's own size, in the middle of its columns: no empty frame beside an upright photo (Nic, 6 Oct) */
.landing-figure img { width: auto; height: auto; max-width: 100%; max-height: calc(100svh - var(--header) - var(--s4) - var(--s6)); object-fit: contain; }
.landing-text { grid-column: 9 / -1; gap: var(--s3); }
.landing-text p { margin: 0; }
.landing-bio { gap: var(--s2); }
.landing-contact { display: flex; flex-wrap: wrap; gap: var(--s1) var(--s3); }   /* the email and Show phone on one line (Nic, 9 Oct) */
#series { scroll-margin-top: calc(var(--header) + var(--s3)); }
@media (max-width: 760px) {
  .landing-photo, .landing-text { grid-column: 1 / -1; }
  .landing-in { min-height: 0; }
  .landing-figure img { max-height: none; width: 100%; }
}

/* Photos and the works they show (site/works.mjs; design audit 5). Rows of one height that fill the width: each
   tile's width follows its shape (flex: --ar), so every photo in a row is as tall as the others and the row meets
   both edges; the rows are composed when the site is built. A row with a small source is drawn lower (--cap: its
   height at most) and stands at the left. A lead opens the page, large. Part of site.css (site/assets.mjs joins the files). */

.works.rows { display: flex; flex-direction: column; row-gap: var(--s7); }
.photo-row.plate { margin: var(--s6) 0; }
.works.sheets { --gutter: var(--s6); row-gap: var(--s7); }   /* drawings breathe: 64 between sheets, 96 between rows (site/works.mjs › KIND.sheets) */   /* a plate is a pause: twice the air of an ordinary row (with the row-gap, 96 px) */
.photo-row { display: flex; align-items: flex-start; gap: var(--gutter); max-width: calc(var(--sum) * min(var(--cap), var(--screen)) + (var(--n) - 1) * var(--gutter)); }   /* never taller than the screen */
.photo-row .tile { flex: var(--ar) 1 0; min-width: 0; margin: 0; }
.tile .frame { display: block; }
.tile .frame img { display: block; width: 100%; height: auto; }
.frame.trim { overflow: hidden; aspect-ratio: var(--ar); }                        /* a cleaned drawing: its added margin hidden (site/sheet-trim.mjs) */
.frame.trim img { width: var(--tw); max-width: none; margin: calc(-1 * var(--tt)) 0 0 calc(-1 * var(--tl)); }
.tile .caption { padding-top: var(--s1); }
a.frame:hover + figcaption .t-work { text-decoration: underline; text-underline-offset: var(--underline); text-decoration-thickness: 1px; }   /* the cue is the title, never a dimmed photo (Nic, 30 Sep) */
.drawing { mix-blend-mode: multiply; }                                            /* a scan's white becomes the paper */
.works.films { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s5) var(--gutter); }   /* films: two across, never 3 + 1 */
.film { margin: 0; }
.film video { display: block; width: 100%; height: auto; background: var(--ink); }

/* facts beside the photos: Commissions, Exhibitions and a work's own page (one layout) */
.project { border-top: 1px solid var(--rule); padding: var(--s5) 0 var(--s8); align-items: start; }
.project:first-child { border-top: 0; padding-top: 0; }
.project-facts, .work-facts { grid-column: 1 / span 3; gap: var(--s1); position: sticky; top: calc(var(--header) + var(--s3)); align-self: start; }
.project-facts .facts { gap: var(--s0); }
.project-facts .links { display: flex; flex-direction: column; gap: var(--s0); padding-top: 0; }
.project-photos, .work-photos { grid-column: 4 / span 9; }
.ex-group { padding-top: var(--s7); gap: var(--s3); }

/* one work: the bar, then its facts beside its photos, each whole and never taller than the screen. Its shape (--ar)
   and widest size (--w, source ÷ 1.5) are on the photo, so its space is kept before it loads (no jump). */
.work-page { padding-top: var(--s3); display: flex; flex-direction: column; gap: var(--s4); }
.work-bar { display: flex; justify-content: space-between; align-items: baseline; gap: var(--s2); }
.work-bar .t-ui a + a { margin-left: var(--s3); }
.work-photos { gap: var(--s5); }
.work-photo { margin: 0; display: flex; flex-direction: column; gap: var(--s1); }
.work-photo img { width: min(100%, var(--w), calc(var(--screen) * var(--ar))); height: auto; aspect-ratio: var(--ar); }
.work-photo.large img { width: min(100%, var(--w)); }                            /* large: not held to the screen's height */
.work-facts h1 { margin: 0; }
.work-notes { gap: var(--s2); padding-top: var(--s2); max-width: var(--measure); }
.work-page .film { width: min(100%, var(--measure)); }

@media (max-width: 760px) {
  .photo-row { flex-direction: column; gap: var(--s5); max-width: none; }            /* one per line on a phone, the full width */
  .works.rows { row-gap: var(--s5); }                                              /* and rows the same 48 apart: one even rhythm (design audit, 6 Oct) */
  .photo-row.plate { margin: var(--s2) 0; }                                          /* every photo is already full width: a smaller pause */
  .photo-row .tile { flex: none; width: 100%; }
  .works.sheets { --gutter: var(--s2); display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s4) var(--gutter); align-items: start; }
  .works.sheets .photo-row { display: contents; }                                  /* drawings: one flow two to a line, not the desktop rows */
  .works.films { grid-template-columns: minmax(0, 1fr); }
  .project { padding-bottom: var(--s5); align-items: stretch; }                  /* stacked: the photos take the full width */
  .project-facts, .work-facts { position: static; }
  .project-facts .links, .project-facts .facts { gap: 0; }
  .work-bar { flex-direction: column; }
  .work-photo img { width: min(100%, var(--w)); }
}

/* Index (/archive): one thin control line, then the list. Part of site.css (site/extras.mjs joins them). */
.controls { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s1) var(--s4); padding-bottom: var(--s2); }
.view-row { margin-left: auto; column-gap: var(--s3); }
.search input { font: inherit; width: calc(var(--thumb) * 2); padding: var(--s0) 0; border: 0; border-bottom: 1px solid var(--graphite); background: transparent; color: var(--ink); }   /* an edge that can be seen (3:1) */
.search input:focus-visible { outline: 0; border-bottom-color: var(--ink); }
.search input::placeholder { color: var(--graphite); }
.chips { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: var(--s2); row-gap: 0; }
.entries.list .entry { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gutter); padding: var(--s1) 0; border-bottom: 1px solid var(--rule); align-items: center; }
/* on the page's column lines: thumbnail 1, title 2–5, year 6–7, series 8–9, material 10–12 */
.entries.list .entry > :nth-child(2) { grid-column: 2 / span 4; }
.entries.list .entry > :nth-child(3) { grid-column: 6 / span 2; }
.entries.list .entry > :nth-child(4) { grid-column: 8 / span 2; }
.entries.list .entry > :nth-child(5) { grid-column: 10 / span 3; }
.entries.list .thumb { display: flex; width: var(--thumb); height: var(--thumb); align-items: flex-end; }   /* one box for every photo, whole inside it, on one line at its foot */
.entries.list .thumb img { display: block; max-width: 100%; max-height: 100%; width: auto; height: auto; }
.entries.list a.entry:hover .t-work { text-decoration: underline; text-underline-offset: var(--underline); text-decoration-thickness: 1px; }
.entries.grid-view { display: flex; flex-wrap: wrap; gap: var(--s4) var(--gutter); border-top: 0; }   /* the sheets idea for a list filtered as you type: every photo one height (--grid-h), whole, tops and captions aligned; the line ends where the last photo does */
.entries.grid-view .entry { display: flex; flex-direction: column; width: calc(var(--grid-h) * var(--ar)); max-width: 100%; min-width: 0; }
.entries.grid-view .entry > .t-meta:nth-of-type(n+3) { display: none; }
.entries.grid-view .thumb img { display: block; height: var(--grid-h); width: 100%; }
.entries.grid-view .t-work { padding-top: var(--s1); }
.entry[hidden] { display: none !important; }
.decade { padding-top: var(--s5); scroll-margin-top: calc(var(--header) + var(--s3)); }
.decade:first-of-type { padding-top: var(--s3); }
.list-head { padding-bottom: var(--s1); border-bottom: 1px solid var(--ink); }   /* a heading that opens a list: Index decades, Foundry CV lines */
.list-head + .list { border-top: 0; }
.entries.grid-view { padding-top: var(--s3); }
.decade[hidden] { display: none; }
.search input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }   /* no blue clear button: our own Clear */
.none { padding-top: var(--s3); display: flex; gap: var(--s2); align-items: baseline; }
.none[hidden] { display: none; }
@media (max-width: 760px) {
  .controls { flex-direction: column; align-items: stretch; }
  .view-row { margin-left: 0; }
  .search input { width: 100%; }
  .entries.list .entry { grid-template-columns: var(--thumb) 1fr auto; }
  .entries.list .entry > * { grid-column: auto; }

  .entries.list .entry > .t-meta:nth-of-type(n+3) { display: none; }
  .controls .chips { column-gap: var(--s2); }                                      /* wrap: whole words, nothing cut off */
}

/* Viewer (site/viewer.js): the photo fills the screen apart from one line above and one caption line below (design review 10–12) */
.viewer { position: fixed; inset: 0; z-index: 30; background: var(--paper); animation: fade var(--move) var(--ease); outline: 0; }   /* focused itself on opening: no ring */
.viewer[hidden] { display: none; }
.viewer-in { height: 100%; display: grid; grid-template-rows: var(--s5) minmax(0, 1fr) auto; }
.viewer-bar, .viewer-foot { display: flex; justify-content: space-between; align-items: center; gap: var(--s3); }
.viewer-foot { padding: var(--s1) 0 var(--s2); align-items: baseline; }
.viewer-foot .caption { flex-direction: row; flex-wrap: wrap; align-items: baseline; gap: 0 var(--s2); padding: 0; min-width: 0; }
.viewer-nav button { min-height: var(--tap); padding: 0 var(--s2); }
.viewer-nav button:last-child { padding-right: 0; }   /* Next lines up with × */
.viewer-nav { display: flex; gap: var(--s1); flex: none; }
.viewer-count { font-variant-numeric: tabular-nums; }
.viewer-stage { position: relative; overflow: hidden; touch-action: none; }   /* fingers move the photo (site/viewer.js), never the page */
.viewer-stage > img { position: absolute; inset: 0; margin: auto; max-width: 100%; max-height: 100%; width: auto; height: auto; opacity: 0; }
.viewer-stage > img.on { opacity: 1; }
.viewer-hit { position: absolute; top: 0; bottom: 0; width: 33%; background: none; border: 0; }
.viewer-hit.prev { left: 0; cursor: w-resize; } .viewer-hit.next { right: 0; cursor: e-resize; }
.viewable { cursor: zoom-in; }
@media (max-width: 760px) {
  .viewer-foot { flex-direction: column; align-items: stretch; gap: var(--s1); }
  .viewer-nav { justify-content: space-between; }
  .viewer-nav button:first-child { padding-left: 0; } .viewer-nav button:last-child { padding-right: 0; }
}
.viewer.instant .viewer-stage > img { transition: none; }   /* opening: the photo appears at once, no crossfade from the last one */
/* − + ×: three quiet marks, a finger's size, the × at the far right over Next */
.viewer-tools { display: flex; align-items: center; margin-right: calc(-1 * var(--s2)); }
.viewer-tool { min-width: var(--tap); min-height: var(--tap); font-size: var(--t-l); line-height: 1; color: var(--ink); }
.viewer-tool:disabled { color: var(--rule); cursor: default; }
/* Zoom: the full-size file over the photo, placed and sized by site/viewer.js; a tap goes back to the whole photo */
.viewer-full { position: absolute; inset: 0; background: var(--paper); cursor: grab; }
.viewer-full[hidden] { display: none; }
.viewer-full:active { cursor: grabbing; }
.viewer-full img { position: absolute; left: 0; top: 0; max-width: none; transform-origin: 0 0; user-select: none; -webkit-user-drag: none; }
.viewer-stage > img.on { cursor: zoom-in; }
.viewer-foot .caption > :empty { display: none; }   /* an untitled photo: no gap before the link */
