/* ==========================================================================
   Portfolio — one stylesheet for all four pages.

   Design rule: nothing on the page competes with the artwork.
   White ground, black text, one typeface, no shadows, no rounded corners,
   no gradients, no animation. When in doubt, remove.

   Sections below, in order:
     1. Settings      — colours, spacing, type sizes (change things here first)
     2. Reset
     3. Page frame    — header, navigation, footer
     4. Recent work   — index.html
     5. About         — about.html
     6. Archive       — archive.html
     7. Studio        — studio.html
     8. Lightbox      — the popup, shared by archive and studio
   ========================================================================== */


/* 1. SETTINGS =============================================================
   Almost every adjustment you'll want to make is in this block. Change a
   value once here and it updates across all four pages.
   ------------------------------------------------------------------------ */

:root {
  /* Colours */
  --paper:  #ffffff;   /* page background */
  --ink:    #111111;   /* main text */
  --muted:  #767676;   /* captions, secondary text */
  --rule:   #e3e1dc;   /* hairline dividers */
  --edge:   #edebe7;   /* the hairline around a photograph — barely there.
                          Make it darker to see it more, lighter to see it
                          less; #ffffff switches it off entirely. */

  /* TYPEFACES — two, with different jobs. They were drawn as a matched pair,
     which is why they sit together without fighting.

       --font   Space Grotesk. Anything you read as prose.
       --mono   Space Mono. Numbers, labels, and catalogue metadata.

     The rule for which is which: if it is something you READ, it is --font.
     If it is something you REFER TO — a number, a date, dimensions, a label —
     it is --mono. Keeping to that is what stops the two looking arbitrary.

     The names after each font are fallbacks, used only if the real fonts
     fail to load. The fonts themselves are linked in each page's <head>. */
  --font: 'Space Grotesk', ui-sans-serif, system-ui, Helvetica, Arial, sans-serif;
  --mono: 'Space Mono', ui-monospace, Menlo, Consolas, monospace;

  /* Type sizes. clamp(min, preferred, max) = scales with window width.
     Five sizes, and every piece of text on the site uses one of them.
     That restraint is most of what makes a site look coherent — adding a
     sixth is the usual way it quietly stops being coherent. */
  --size-name:  clamp(2rem, 6vw, 3.5rem);        /* your name in the masthead */
  --size-title: clamp(1.25rem, 2.4vw, 1.75rem);  /* project titles */
  --size-body:  clamp(1rem, 1.4vw, 1.125rem);    /* reading text */
  --size-small: 0.875rem;                        /* navigation, captions */
  --size-tiny:  0.75rem;                         /* numbers, labels */

  /* Spacing */
  --page-x:  clamp(1.25rem, 5vw, 4.5rem);  /* left/right page margin */
  --gap:     clamp(0.75rem, 1.6vw, 1.5rem); /* gap between paired images */
  --section: clamp(3.5rem, 9vw, 7.5rem);    /* gap between works */

  /* Text line length. Long lines are hard to read; this caps them. */
  --measure: 34rem;

  /* The tallest any single photograph is allowed to be, measured against the
     browser window rather than in fixed pixels — so a work fits the screen
     whatever size that screen is. 72vh leaves room for the caption beneath
     without scrolling. Raise it for bigger images, lower it for smaller. */
  --shot-max: 72vh;
}


/* 2. RESET ================================================================ */

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--size-body);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

img {
  display: block;
  width: 100%;
  height: auto;
}

a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
}

a:hover { border-bottom-color: var(--ink); }

/* Both kinds of list. Numbered lists (ol) need this as much as bulleted ones
   — otherwise the browser adds its own "1. 2. 3." beside the numbers we set
   ourselves, and indents the whole thing. */
ul, ol { list-style: none; margin: 0; padding: 0; }

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

/* Keyboard users must always be able to see what's focused. */
:focus-visible {
  outline: 1px solid var(--ink);
  outline-offset: 3px;
}


/* 3. PAGE FRAME =========================================================== */

.page {
  padding: clamp(1.5rem, 4vw, 3rem) var(--page-x) clamp(4rem, 8vw, 7rem);
  max-width: 100rem;
  margin: 0 auto;
}

/* Your name sits on its own line at a real size, with the navigation beneath
   it. Large type wants TIGHTER letter-spacing than small type — that is what
   the negative value does. It is also not uppercased: capitals at this size
   read as shouting. */
.masthead {
  padding-bottom: 1.125rem;
  border-bottom: 1px solid var(--rule);
  margin-bottom: var(--section);
}

.masthead__name {
  font-size: var(--size-name);
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1;
  margin: 0 0 0.875rem;
}

/* Present for screen readers and search engines, invisible on screen.
   Each page has a heading saying which page it is — but showing it would
   just repeat what the navigation above already tells you. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.masthead__name a { border-bottom: 0; }

/* Navigation: items separated by forward slashes, as on the Cavendish site. */
.nav {
  display: flex;
  flex-wrap: wrap;
  font-size: var(--size-small);
}

.nav li + li::before {
  content: "/";
  color: var(--muted);
  margin: 0 0.6em;
}

.nav a { border-bottom: 0; }
.nav a:hover { border-bottom: 1px solid var(--ink); }

/* The page you're currently on */
.nav a[aria-current="page"] { border-bottom: 1px solid var(--ink); }

.colophon {
  margin-top: var(--section);
  padding-top: 1.25rem;
  border-top: 1px solid var(--rule);
  font-family: var(--mono);
  font-size: var(--size-tiny);
  color: var(--muted);
}

.colophon p { margin: 0; }


/* ONE CAPTION STYLE, used under artwork on every page.
   Recent Work and Archive share it, so a caption looks identical wherever
   you meet it. Change it here and it changes everywhere. */

.caption {
  margin: 0.875rem 0 0;
  font-size: var(--size-small);
  line-height: 1.45;
}

/* The work's name is prose — it stays in the reading face.
   The medium, dimensions and year are catalogue data — they go mono. */
.caption__title { color: var(--ink); }

.caption__meta {
  font-family: var(--mono);
  font-size: var(--size-tiny);
  color: var(--muted);
}

/* An optional short text beneath a caption — for a work that has something
   to say. Works without one simply don't have this paragraph. */
.caption__text {
  margin: 0.75rem 0 0;
  max-width: var(--measure);
  font-size: var(--size-small);
  color: var(--muted);
}


/* 4. RECENT WORK — index.html ============================================= */

.work { margin-bottom: var(--section); }
.work:last-child { margin-bottom: 0; }

/* --- A ROW OF TWO OR THREE PHOTOGRAPHS OF ONE WORK ----------------------
   Order: the full frontal shot, then the texture, then a shot with a person
   in it for scale where one exists.

   All the images in a row end up exactly the SAME HEIGHT, with their widths
   varying according to their proportions — so a tall panel sits narrow beside
   a wide detail, and the row has no gaps in it.

   How: each image carries its own aspect ratio as --ar (width ÷ height), set
   on the <img> itself. flex-grow uses that number, so widths come out
   proportional to the ratios, which makes the heights equal. This is the same
   principle behind a justified row of thumbnails.
   ------------------------------------------------------------------------ */

/* The row carries --sum-ar: the aspect ratios of its images added together.
   aspect-ratio turns that into a height — the row is as tall as its own width
   divided by that sum, which is exactly the height at which the images sit
   side by side and fill the width with no gaps.

   max-height then caps it against the window. When the cap bites, the row gets
   shorter and the images shrink with it, keeping their proportions — rather
   than staying wide and padding themselves out with empty space. */
.work__row {
  display: flex;
  gap: var(--gap);
  align-items: flex-start;
  margin: 0;
  aspect-ratio: var(--sum-ar, 2);
  max-height: var(--shot-max);
}

.work__row img {
  height: 100%;
  width: auto;
  min-width: 0;
  flex: 0 1 auto;
  object-fit: contain;
}

/* A row holding one photograph. No aspect-ratio needed — the image simply
   scales to fit inside both caps, so a very tall panel comes down to fit the
   window instead of running past the bottom of it. */
.work__row--one {
  aspect-ratio: auto;
  max-height: none;
}

.work__row--one img {
  height: auto;
  width: auto;
  max-width: min(100%, 30rem);
  max-height: var(--shot-max);
}

/* A single photograph that should run the full width — an installation
   view, where the room is the point. Add this class beside work__row--one. */
.work__row--wide img { max-width: 100%; }

/* Captions here use the shared .caption style defined in section 3. */

/* --- WORK NUMBERS --------------------------------------------------------
   Numbers are ON right now so you can judge them against your real work.
   Don't like them? Change "block" to "none" on the line below and every
   number on the site disappears. Nothing else needs changing.
   ------------------------------------------------------------------------ */

.work-number {
  display: block;   /* <-- change to: none    to hide all work numbers */
  font-family: var(--mono);
  font-size: var(--size-tiny);
  letter-spacing: 0.06em;
  color: var(--muted);
  margin-bottom: 0.2rem;
}


/* 5. ABOUT — about.html ===================================================
   The portrait is the largest thing on the page, with the text beside it —
   the same proportions as an archive entry, so the two pages read as one site.

   The columns are PROPORTIONAL (1.15fr / 1fr), not fixed widths. That matters:
   proportional columns stretch to fill whatever width the window gives them.
   Fixed widths would leave the right side of a wide screen empty.
   ------------------------------------------------------------------------ */

.about {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}

.about__figure { margin: 0; }

/* The photo fills its column. max-height stops a tall portrait running off
   the bottom of the screen, and object-fit crops it to fit — biased towards
   the top, since that is usually where a face is.

   Don't want it cropped at all? Delete the max-height, object-fit and
   object-position lines and it will show whole, at whatever height it needs. */
.about__photo {
  width: 100%;
  max-height: 82vh;
  object-fit: cover;
  object-position: center 30%;
}

/* Capped for readability — long lines of text are tiring to read. */
.about__text { max-width: var(--measure); }

/* BIO / STATEMENT are labels, not headings you read — so they go mono. */
.about__text h2 {
  font-family: var(--mono);
  font-size: var(--size-tiny);
  font-weight: 400;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 0.75rem;
}

.about__text section + section { margin-top: 2.5rem; }
.about__text p { margin: 0 0 1rem; }
.about__text p:last-child { margin-bottom: 0; }


/* 5a. THE HAIRLINE AROUND EVERY PHOTOGRAPH ===============================
   A photograph on a white ground with a white background of its own has no
   edge — it dissolves into the page, while a darker picture beside it reads
   as a solid rectangle. One barely-visible line gives every picture the same
   boundary, so a row sits evenly whatever the pictures are.

   box-shadow rather than border, because a border would be added to the
   width and throw out the row arithmetic.
   ------------------------------------------------------------------------ */

.work__row img,
.works__shot,
.entry__lead {
  box-shadow: 0 0 0 1px var(--edge);
}


/* 5b. RECENT WORK — THE INDEX GRID ========================================
   One photograph per work, square, clickable. The picture is a texture shot:
   its job is to make someone want to look closer, not to explain the piece.
   The full story lives on the work's own page.

   Pictures are NOT cropped on disk. object-fit: cover fills the square from
   the middle of whatever photograph you point at, so you can swap a picture
   without re-cutting the file.

   To change how many sit in a row, change the 15rem below: a bigger number
   gives fewer, larger squares.
   ------------------------------------------------------------------------ */

.works {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  column-gap: var(--gap);
  row-gap: clamp(2.25rem, 4.5vw, 3.75rem);
  margin: 0 0 var(--section);
  padding: 0;
  list-style: none;
}

.works__item { margin: 0; }

/* The whole tile is the link — picture and caption together. */
.works__link {
  display: block;
  border-bottom: 0;
  color: inherit;
}

.works__shot {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  background: var(--rule);
}

.works__link:hover .works__shot { opacity: 0.72; }
.works__link:hover .caption__title { border-bottom: 1px solid var(--ink); }

.works .caption { margin-top: 0.75rem; }

@media (max-width: 34rem) {
  .works { grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr)); }
}


/* 5c. A SINGLE WORK — its own page ========================================
   Reached by clicking a square on Recent Work. The back link, then the
   photographs, then the caption, then the text.
   ------------------------------------------------------------------------ */

.workpage { margin-bottom: var(--section); }

/* Navigation across the top, above the photographs: back to the index on the
   left, the works either side of this one on the right. It used to sit at the
   foot of the page, which meant scrolling past everything to move on. */
.workpage__bar {
  margin-bottom: var(--section);
  font-family: var(--mono);
  font-size: var(--size-small);
}
.workpage__bar a { border-bottom: 0; color: var(--muted); }
.workpage__bar a:hover { color: var(--ink); }

/* Leaving the sequence gets its own line, and an UP arrow — a different
   direction from the sideways arrows below it, so the two kinds of move
   cannot be confused. */
.workpage__bar .workpage__back {
  display: block;
  color: var(--ink);
  margin: 0 0 0.9rem;
}

/* Moving along the sequence: one line, under a rule, previous at the left
   and next at the right. */
.workpage__steps {
  display: flex;
  justify-content: space-between;
  gap: var(--gap) 1.5rem;
  flex-wrap: wrap;
  border-top: 1px solid var(--rule);
  padding-top: 0.75rem;
}

/* The words "previous" and "next", quieter than the titles they label. */
.workpage__steps .lbl {
  color: #b3aea6;
  margin-right: 0.35rem;
}
.workpage__steps .lbl--next { margin: 0 0 0 0.35rem; }

.workpage__back {
  display: inline-block;
  font-family: var(--mono);
  font-size: var(--size-small);
  color: var(--muted);
  margin-bottom: var(--section);
  border-bottom: 0;
}
.workpage__back:hover { color: var(--ink); }

.workpage__head { margin: var(--gap) 0 0; }

/* The work's number, repeated from the index so the two agree. */
.workpage__head .work-number { margin-bottom: 0.35rem; }

/* On the index the number sits inside the caption, under the picture,
   so the photograph is the first thing read and the number is reference. */
.works .work-number { margin-bottom: 0.15rem; }

.workpage__title {
  font-size: var(--size-title);
  font-weight: 500;
  margin: 0 0 0.35rem;
}

.workpage__meta {
  font-family: var(--mono);
  font-size: var(--size-small);
  color: var(--muted);
  margin: 0;
  max-width: var(--measure);
}

/* The written text. Set for reading, not for scanning. */
.workpage__text {
  max-width: var(--measure);
  margin: 2rem 0 0;
  font-size: var(--size-body);
}
.workpage__text p { margin: 0 0 1rem; }
.workpage__text p:last-child { margin-bottom: 0; }

/* Moving between works at the foot of the page. */
.workpage__nav {
  display: flex;
  justify-content: space-between;
  gap: var(--gap);
  border-top: 1px solid var(--rule);
  padding-top: var(--gap);
  margin-top: var(--section);
  font-family: var(--mono);
  font-size: var(--size-small);
}
.workpage__nav a { border-bottom: 0; color: var(--muted); }
.workpage__nav a:hover { color: var(--ink); }
.workpage__nav span { color: var(--rule); }


/* A quotation inside a studio chapter — someone else's words, not yours.
   Indented and set smaller so a reader can see at a glance that the voice
   has changed. The attribution line underneath says whose it is.
   ------------------------------------------------------------------------ */

.entry__quote {
  margin: 1.25rem 0 0;
  padding-left: 1rem;
  border-left: 1px solid var(--rule);
  max-width: var(--measure);
}
.entry__quote p {
  margin: 0 0 0.75rem;
  font-size: var(--size-small);
  color: var(--muted);
}
.entry__quote p:last-of-type { margin-bottom: 0; }

.entry__cite {
  display: block;
  margin-top: 0.75rem;
  font-family: var(--mono);
  font-size: var(--size-tiny);
  color: var(--muted);
  font-style: normal;
}


/* 6. ARCHIVE — archive.html ===============================================
   A grid of pictures, then the full projects below. Both built from
   js/archive-data.js.
   ------------------------------------------------------------------------ */

/* --- The index is a grid of pictures ---
   Every project is a clickable image. One continuous grid, newest first —
   no year headings, no numbers, no rules. Each tile carries its own year
   underneath, which is enough to read the chronology by.

   JUSTIFIED ROWS. Each picture's width is set in proportion to its own shape
   (--ar, its width divided by its height), so every picture in a row comes
   out at exactly the same height and the row fills the page width to the
   edge. Nothing is cropped and no empty space is left around anything.

   It is the same principle as the photograph rows on Recent Work, which is
   why the two pages look related.

   You never type --ar here. js/lightbox.js sets it from the picture itself.
   ------------------------------------------------------------------------ */

.index { margin: 0 0 var(--section); }

.index__tiles {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(1.5rem, 3vw, 2.75rem) var(--gap);
}

.index__tile {
  display: block;
  text-align: left;
  border-bottom: 0;
  cursor: pointer;
  /* Both numbers are proportional to the picture's shape. That is what makes
     the widths come out in proportion, and so the heights come out equal.
     Change 15rem to make the pictures bigger or smaller — bigger means fewer
     per row. */
  flex-grow: var(--ar, 1);
  flex-basis: calc(var(--ar, 1) * 15rem);
  min-width: 7rem;
}

.index__tile img {
  width: 100%;
  height: auto;
  aspect-ratio: var(--ar, 1);
}

/* Invisible, and only ever lands on the last row. Without these, one or two
   pictures left over on the final row would stretch across the whole width. */
.index__fill {
  flex-grow: 9999;
  height: 0;
  margin: 0;
}

.index__caption {
  margin-top: 0.75rem;
  font-size: var(--size-small);
  line-height: 1.35;
  color: var(--muted);
}

.index__title { display: block; }

.index__yearsmall {
  display: block;
  font-family: var(--mono);
  font-size: var(--size-tiny);
  letter-spacing: 0.08em;
  margin-top: 0.2rem;
}

/* The image dims slightly, the title comes up to full black. No borders,
   no shadows, no zoom — the picture stays the loudest thing on the tile. */
.index__tile:hover img { opacity: 0.72; }
.index__tile:hover .index__title { color: var(--ink); }

/* --- One entry --- */

.entry {
  margin-bottom: var(--section);
  /* Stops an entry from sitting flush against the top of the window when you
     jump to it from the index. */
  scroll-margin-top: 2rem;
}

.entry:last-child { margin-bottom: 0; }

.entry__head {
  display: flex;
  align-items: baseline;
  gap: 1rem;
  padding-bottom: 0.875rem;
  border-bottom: 1px solid var(--rule);
  margin-bottom: clamp(1.25rem, 3vw, 2rem);
}

.entry__title {
  font-size: var(--size-title);
  font-weight: 500;
  letter-spacing: -0.01em;
  margin: 0;
}

/* Photo on the left, words on the right. Stacks on small screens. */
.entry__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: start;
}

/* A chapter with no photograph yet. The text takes the whole width instead
   of sitting in a narrow column beside an empty space. Delete this class from
   the <div class="entry__grid"> when a picture arrives. */
.entry__grid--nophoto { grid-template-columns: minmax(0, 1fr); }
.entry__grid--nophoto .entry__info { max-width: var(--measure); }

.entry__lead {
  display: block;
  width: 100%;
  cursor: zoom-in;
}

/* The caption under the lead photo uses the shared .caption style. */

/* Small thumbnails of the additional photos */
.entry__thumbs {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(5.5rem, 1fr));
  gap: 0.5rem;
  margin-top: 1rem;
}

/* Written to match both the Archive (where JavaScript wraps each thumbnail in
   a button) and the Studio (where you write the images by hand). */
.entry__thumb { display: block; width: 100%; cursor: zoom-in; }
.entry__thumbs img { aspect-ratio: 1 / 1; object-fit: cover; }
.entry__thumb:hover img,
.entry__thumbs img.zoomable:hover { opacity: 0.72; }

.entry__context {
  margin: 0 0 0.5rem;
  font-size: var(--size-small);
}

/* Date and place — catalogue data, so mono. */
.entry__meta {
  margin: 0 0 1.25rem;
  font-family: var(--mono);
  font-size: var(--size-tiny);
  color: var(--muted);
}

.entry__desc { margin: 0 0 1.5rem; }

.entry__links { font-size: var(--size-small); }
.entry__links li + li { margin-top: 0.35rem; }

/* Video, full width beneath the photo and text */
.entry__video {
  margin-top: clamp(1.5rem, 4vw, 3rem);
  aspect-ratio: 16 / 9;
}

.entry__video iframe {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

/* Hidden while the index is a sticky sidebar — you can already reach it from
   anywhere, so a "back to index" link would be clutter. It reappears on
   narrow screens, where the index sits at the top of the page instead. */
.entry__back {
  display: none;
  margin-top: 1.5rem;
  font-family: var(--mono);
  font-size: var(--size-tiny);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  border-bottom: 0;
}

.entry__back:hover { color: var(--ink); }


/* 7. STUDIO — studio.html =================================================
   A dated log of work in progress, newest entry first.

   Studio deliberately REUSES the archive's .entry classes above rather than
   having its own. Two reasons: the two pages then look like the same site by
   construction rather than by coincidence, and there is only one set of rules
   to maintain. The date sits where a project title sits on the archive.
   ------------------------------------------------------------------------ */

.studio__intro {
  max-width: var(--measure);
  margin: 0 0 var(--section);
}

.studio__intro p { margin: 0 0 1rem; }
.studio__intro p:last-child { margin-bottom: 0; }

/* Any image you can click to enlarge */
.zoomable { display: block; width: 100%; cursor: zoom-in; }


/* 8. LIGHTBOX — the popup, shared by archive.html and studio.html ==========
   Built by js/lightbox.js and added to the page automatically. It stays
   hidden until something is clicked.
   ------------------------------------------------------------------------ */

.lightbox[hidden] { display: none; }

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: var(--paper);
  display: grid;
  grid-template-rows: auto 1fr auto;
  padding: clamp(0.75rem, 2vw, 1.5rem) var(--page-x)
           clamp(1.25rem, 3vw, 2rem);
  overflow-y: auto;
}

.lightbox__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  font-size: var(--size-small);
  color: var(--muted);
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--rule);
}

.lightbox__count {
  font-family: var(--mono);
  font-size: var(--size-tiny);
}

.lightbox__close {
  font-family: var(--mono);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-size: var(--size-tiny);
}

.lightbox__close:hover { color: var(--ink); }

.lightbox__stage {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(0.5rem, 2vw, 2rem);
  min-height: 0;
  padding: clamp(1rem, 3vw, 2rem) 0;
}

.lightbox__figure {
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
  flex: 1;
}

.lightbox__figure img {
  width: auto;
  max-width: 100%;
  max-height: 72vh;
  object-fit: contain;
}

.lightbox__arrow {
  font-size: 1.5rem;
  line-height: 1;
  padding: 0.5rem;
  color: var(--muted);
  flex: none;
}

.lightbox__arrow:hover { color: var(--ink); }
.lightbox__arrow[disabled] { opacity: 0.2; cursor: default; }

.lightbox__caption {
  font-size: var(--size-small);
  line-height: 1.45;
  max-width: var(--measure);
  padding-top: 0.75rem;
  border-top: 1px solid var(--rule);
}

.lightbox__title { display: block; color: var(--ink); }

.lightbox__meta {
  display: block;
  font-family: var(--mono);
  font-size: var(--size-tiny);
  color: var(--muted);
}
.lightbox__text  { margin: 0.625rem 0 0; color: var(--muted); }

/* Stops the page behind the popup from scrolling while it's open */
body.is-locked { overflow: hidden; }


/* 8a. PLAY — play-somewhere-better-this-place.html ==========================
   A page with nothing on it but the photograph and one way back. The
   photograph is drawn by js/play.js onto the canvas; the page itself only
   has to fill the window and keep still.
   ------------------------------------------------------------------------ */

body.play {
  margin: 0;
  overflow: hidden;
  background: var(--paper);
  height: 100vh;
  height: 100dvh;
  overscroll-behavior: none;      /* no rubber-band or pull-to-refresh */
}

.play__stage {
  display: block;
  width: 100vw;
  height: 100vh;
  height: 100dvh;
  touch-action: none;             /* a finger moves the colonies, not the page */
  -webkit-user-select: none;      /* and does not select or magnify anything */
  user-select: none;
  -webkit-touch-callout: none;
  cursor: crosshair;
}

/* The way back, small and in the corner: the same voice as "↑ all works". */
.play__back {
  position: fixed;
  top: 1rem;
  left: 1rem;
  z-index: 1;
  font-family: var(--mono);
  font-size: var(--size-small);
  color: var(--muted);
  text-decoration: none;
  border-bottom: 0;
  background: var(--paper);
  padding: 0.2rem 0.4rem;
}
.play__back:hover { color: var(--ink); }

/* On the work page: the button that leads to the game. A plain bordered
   box in the catalogue face — square-cornered and flat, like everything
   else here — that fills in on hover so it is unmistakably something to
   press. */
.workpage__play {
  font-family: var(--mono);
  font-size: var(--size-small);
  margin: 1.75rem 0 0;
}

.workpage__button {
  display: inline-block;
  padding: 0.7rem 1.1rem;
  border: 1px solid var(--ink);
  color: var(--ink);
  line-height: 1;
}

.workpage__button:hover,
.workpage__button:focus-visible {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}


/* 9. SMALL SCREENS ========================================================
   Everything above is written for a wide window. These rules take over on
   phones and narrow windows.
   ------------------------------------------------------------------------ */

/* The link back up to the picture grid earns its place once a project is
   long enough that the grid has scrolled out of sight. */
@media (max-width: 60rem) {
  .entry__back { display: inline-block; }
}

@media (max-width: 46rem) {
  /* A row of photographs stacks instead of sitting side by side. Three images
     across a phone screen would be too small to read. */
  .work__row {
    flex-direction: column;
    aspect-ratio: auto;      /* the row is no longer one line of images */
    max-height: none;
  }
  .work__row img { flex: none; width: 100%; height: auto; max-height: 78vh; }
  .work__row--one img { width: 100%; max-width: 100%; }

  /* Photo above the text rather than beside it */
  .about { grid-template-columns: 1fr; }
  .about__photo { max-height: 62vh; }

  /* Archive: photo above the words */
  .entry__grid { grid-template-columns: 1fr; }

  /* Smaller target width on a phone, so the rows still hold two pictures
     rather than one enormous one. */
  .index__tile {
    flex-basis: calc(var(--ar, 1) * 8rem);
    min-width: 5rem;
  }

  .masthead { margin-bottom: clamp(2.5rem, 8vw, 4rem); }
  .lightbox__figure img { max-height: 60vh; }
}


/* 10. MOTION ==============================================================
   Jumping from the index to an entry glides rather than snapping, which
   makes it clear you moved down the same page rather than loading a new one.
   Switched off for anyone whose system asks for reduced motion.
   ------------------------------------------------------------------------ */

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}
