/* Nicolás Lapadula
   ------------------------------------------------------------------
   THE ONE RULE THIS FILE EXISTS TO ENFORCE: the interface is achromatic.
   Paper, ink, and grey. Every colour on screen comes from inside a frame.
   His painting is already at maximum saturation — anything saturated beside
   it either loses or wins, and both are wrong on an artist's site.

   The second rule: nothing here may read as a shop. No badges, no "available
   now", no button above the work. Galleries read this site, and a site that
   looks like it is selling costs him the exhibitions that make him worth
   buying. His words, 2026-09-02.
   ------------------------------------------------------------------ */

:root {
  --paper:      #F4F1EA;
  --paper-warm: #FBFAF7;
  --ink:        #0B0B0B;
  --ink-soft:   #5A574F;
  --soft-on-dark: #D6D1C8;   /* descriptions and labels on ink and colour bands */
  --rule:       #CFC9BC;   /* visible against paper — 1.19:1 was not */

  --measure: 34rem;
  --gutter: clamp(1.25rem, 4vw, 4rem);
  --step: clamp(3.5rem, 9vw, 8rem);

  --serif: "Instrument Serif", ui-serif, Georgia, "Times New Roman", serif;
  --sans: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;

  /* THE TYPE SCALE, ONE TOKEN PER ROLE. 2026-09-15.
     Ten roles, and every rule below points at one of them rather than carrying
     its own clamp -- the stylesheet had SEVENTEEN rendered sizes and twenty-seven
     family/size/weight/style/line-height/tracking/case combinations, measured at
     1363px, which is what made one family read as several systems.
     Each clamp is solved so it lands exactly on its desktop target at 1363px and
     exactly on its mobile target at 390px, which is why the phone overrides that
     used to re-state these sizes are gone rather than rewritten. */
  /* ONE HEADING SCALE (24/09, JP's unify brief): page openers and section
     heads are the same size, and it is the openers' size they share (JP: "go
     to 72"). 44px at 600px and below, ~57 on a tablet, 72 from 1024px up,
     reached smoothly, not in steps. */
  --t-h1:    var(--t-h2);
  --t-h2:    clamp(2.75rem, .274rem + 6.604vw, 4.5rem);  /* 44 -> 72, full size at 1024px */
  --t-h3:    clamp(1.75rem, 1.5rem + .7vw, 2rem);       /* 28 -> 32 */
  --t-lede:  clamp(1.125rem, 1rem + .4vw, 1.25rem);     /* 18 -> 20 */
  --t-body:  clamp(1.0625rem, 1rem + .2vw, 1.125rem);   /* 17 -> 18 */
  /* --t-quote (24 -> 26) retired 15/09: the artist statement and the pull
     quote were its only two users and both now take --t-body. A size token with
     no role left is how the scale grew to seventeen in the first place. */
  --t-title: clamp(1.25rem, 1.1rem + .4vw, 1.375rem);   /* 20 -> 22 */
  --t-label: .75rem;                                    /* 12, label only   */
  --t-meta:  .875rem;                                   /* 14, record/meta  */
  --t-nav:   .8125rem;                                  /* 13, nav + action */

  /* One easing for everything that moves. Exponential ease-out: fast départ,
     long settle — the curve a heavy thing follows, which is what a painting is. */
  --ease: cubic-bezier(.16, 1, .3, 1);
  --reveal: 900ms;
}

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

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

body {
  margin: 0;
  color: var(--ink);
  font: 400 1rem/1.65 var(--sans);
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; height: auto; display: block; }
a { color: inherit; }

/* The surfaces nobody draws. A browser ships its own blue for selection, its own
   caret, its own scrollbar — all of them from a design system that is not this
   one, and all of them chromatic on a site whose whole argument is that the only
   colour comes from inside a frame. */
::selection { background: var(--ink); color: var(--paper); }
html { caret-color: var(--ink); scrollbar-color: var(--rule) var(--paper); }
@supports selector(::-webkit-scrollbar) {
  ::-webkit-scrollbar { width: 10px; height: 10px; }
  ::-webkit-scrollbar-track { background: var(--paper); }
  ::-webkit-scrollbar-thumb { background: var(--rule); border: 3px solid var(--paper); }
  ::-webkit-scrollbar-thumb:hover { background: var(--ink-soft); }}



/* THE WORK PAGE'S H1, READ AND NEVER SEEN. Its head band was deleted 16/09 --
   a band whose whole content was the word "Work" -- but a page still owes a
   screen reader and a search engine one heading that names it. Off-canvas by
   the same method as the skip link, which is the only other element here that
   exists without being visible. Never `display: none`: that would take it out
   of the accessibility tree, which is the one place it is still needed. */
.h1-off { position: absolute; left: -9999px; top: 0; }

/* Skip link — a gallery of 100+ images is a long way past the navigation. */
.skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--ink); color: var(--paper); padding: .75rem 1rem;
}

:where(a, button, input, textarea, select):focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}

.wrap { width: min(78rem, 100%); margin-inline: auto; padding-inline: var(--gutter); }

/* ---------- type ---------- */

.display {
  font-family: var(--serif);
  font-weight: 400;
  line-height: 1.08;
  letter-spacing: -.02em;
  margin: 0;
  font-size: var(--t-h1);
  /* The browser distributes the lines instead of filling each one and leaving
     whatever is left on the last. At 390px this sentence otherwise drops
     "orderly." onto a line of its own. A manual <br> would fix the English and
     break the Spanish, which wraps at a different word. */
  text-wrap: balance;
}
.h2 {
  font-family: var(--serif);
  font-weight: 400;
  
  margin: 0;
}
.eyebrow {
  font: 500 0.6875rem/1.4 var(--sans);
  color: var(--ink-soft);
  /* margin set once by the header-group component further down */
}
.lede {    margin: 0; }
.prose { max-width: var(--measure); }
.prose p { margin: 0 0 1.1em; }
.prose p:last-child { margin-bottom: 0; }

/* The only "action" styling on the site: a ruled link, never a filled button.
   A button is a shop. A ruled link is a way through. */
.go {
  display: inline-block;
  font: 500 0.8125rem/1 var(--sans);
  
  text-decoration: none;
  padding-bottom: .5rem;
  border-bottom: 1px solid var(--ink);
}
.go:hover, .go:focus-visible { opacity: 1; }

/* ---------- masthead ---------- */

/* THE LANGUAGE SWITCH IS A SIBLING OF THE NAV, NOT A CHILD OF IT (JP, 17/09),
   so that a phone can show it while the nav panel is closed. That makes the
   masthead a three-item row, and `space-between` would have spread wordmark,
   links and language evenly across 78rem instead of keeping the links at the
   right-hand end. `flex-start` plus an auto margin on the nav pushes the nav
   and the language switch to the right AS A PAIR, which is what the two-item
   version used to do by accident. */
.masthead {
  display: flex; flex-wrap: wrap; gap: 1rem 2rem;
  align-items: baseline; justify-content: flex-start;
  padding-block: clamp(1.25rem, 3vw, 2rem);
}
.masthead > .nav { margin-inline-start: auto; }
.wordmark {
  
  text-decoration: none;
  white-space: nowrap;
}
.nav { display: flex; flex-wrap: wrap; align-items: baseline; gap: clamp(1rem, 2.5vw, 2rem); }
/* The language switch is no longer inside `.nav`, so it no longer inherits this
   rule by descent and has to be named. It is the same type at the same size,
   because it is the same row -- it simply lives one level up now so a phone can
   show it while the panel is shut. */
.nav a,
.nav-cities > summary,
.masthead > .lang {
  font: 400 0.875rem/1 var(--sans);
  text-decoration: none;
  padding-block: .35rem;
}
.nav a:hover, .nav a[aria-current="page"],
.nav-cities > summary:hover, .nav-cities > summary[aria-current],
.masthead > .lang:hover { color: var(--ink); }
.lang { font-variant-numeric: tabular-nums; }
/* It sits at the end of the link row, spaced like one more link in it. */
.masthead > .lang { margin-inline-start: clamp(1rem, 2.5vw, 2rem); }

/* ---------- the phone menu ---------- */
/* Four links and a language switch wrapped to THREE LINES on a phone, and a sticky
   bar three lines deep sits on top of every painting on the site. Below 48rem the
   bar is one line -- name, and a hamburger -- and the links drop out of it.

   No JavaScript: a checkbox and a sibling selector. The checkbox is invisible but
   not `hidden`, sized to cover the bars, so it takes the tap AND takes Tab, and
   Space opens the menu. The label is decoration. Above 48rem both vanish and the
   nav is exactly what it was. */
/* ---------- getting close to the painting ---------- */
/* THE OVERLAY IS BUILT BY THE SCRIPT, so none of this applies until a reader
   actually asks for it and nothing here costs a page that never opens one.
   `[hidden]` is honoured explicitly: `display:flex` below would otherwise beat
   the browser's own rule and the overlay would sit over every work page. */
.zoom[hidden] { display: none; }
.zoom {
  position: fixed; inset: 0; z-index: 100;
  display: flex; align-items: center; justify-content: center;
  padding: clamp(.5rem, 2vw, 2rem);
  /* NEARLY BLACK, NOT BLACK. A true black field makes a dark painting look as
     though it has no edge; a hair of light keeps the canvas a rectangle. */
  background: rgba(8, 8, 8, .94);
  overscroll-behavior: contain;
}
.zoom-img {
  max-width: 100%; max-height: 100%;
  object-fit: contain;
  cursor: zoom-in;
  transition: transform .25s ease;
  /* The browser's own pinch is better than anything scripted, so it is left
     alone rather than intercepted. */
  touch-action: pinch-zoom;
}
.zoom[data-zoomed="true"] .zoom-img {
  transform: scale(2.5);
  cursor: zoom-out;
}
@media (prefers-reduced-motion: reduce) { .zoom-img { transition: none; }}



/* A 44px TARGET, drawn rather than typed: the overlay has no type on it at all
   and a word in the corner would be the only thing competing with the work. */
.zoom-shut {
  position: absolute; inset-block-start: clamp(.5rem, 2vw, 1.5rem);
  inset-inline-end: clamp(.5rem, 2vw, 1.5rem);
  width: 44px; height: 44px;
  padding: 0; border: 0; border-radius: 50%;
  background: rgba(255, 255, 255, .10);
  cursor: pointer;
}
.zoom-shut::before, .zoom-shut::after {
  content: ""; position: absolute; inset-block-start: 50%; inset-inline-start: 25%;
  width: 50%; height: 1px; background: #fff;
}
.zoom-shut::before { transform: rotate(45deg); }
.zoom-shut::after  { transform: rotate(-45deg); }
.zoom-shut:hover, .zoom-shut:focus-visible { background: rgba(255, 255, 255, .20); }

/* THE CITY IN THE SPEC IS A LINK NOW, AND A LINE OF 13px TYPE IS A 17px TARGET
   -- under the 24px AA floor, on the one link a buyer on a phone is most likely
   to reach for. The hit area is grown with an absolutely positioned pseudo, the
   same device the inline note links use: the thumb gets 39px and the definition
   list keeps its spacing, because nothing about the box the eye sees changes.
   Padding would have worked and would have pushed every row of the spec apart. */
.spec a { position: relative; }
.spec a::after {
  content: "";
  position: absolute;
  inset-block: -.7rem; inset-inline: 0;
}

/* The photograph on a work page now says what it does. */
.shot { cursor: zoom-in; display: block; }

/* ---------- the cities menu ---------- */
/* SET LIKE A NAV LINK, BECAUSE IT IS ONE ITEM IN THAT ROW. The summary borrows
   the same rule as `.nav a` rather than inventing a size, so the bar still
   reads as one row of type; it is not an anchor, so it has to be named. */
/* IT IS NOT AN ANCHOR, SO IT INHERITS NOTHING. Every rule that sets the nav's
   type names `.nav a`, and a <summary> matches none of them -- so this label
   was set in a private copy of the type and drifted from the row it sits in:
   14px against 12px, weight 400 against 500, no uppercase, no letter-spacing,
   and a soft grey against full ink. Six differences in one word.
   The fix is not a better copy. The selector is added to each of the nav's own
   rules below, so the label cannot drift again; all that is left here is what
   is genuinely particular to a summary. */
.nav-cities > summary {
  padding-block: .35rem;
  cursor: pointer;
  list-style: none;                 /* the default triangle, in Firefox */
}
.nav-cities > summary::-webkit-details-marker { display: none; }
.nav-cities > summary::after {
  content: "";
  display: inline-block;
  width: .42em; height: .42em;
  margin-inline-start: .5em;
  border-inline-end: 1px solid currentColor;
  border-block-end: 1px solid currentColor;
  transform: translateY(-.15em) rotate(45deg);
}
.nav-cities[open] > summary::after { transform: translateY(.1em) rotate(-135deg); }

@media (min-width: 48rem) {
  /* A PANEL THAT HANGS OFF THE WORD, and the only absolutely positioned thing
     in this bar. It is held against the RIGHT edge of the summary: the menu is
     the last item before the language switch, so anchoring it left would run
     it off the side of the screen on a narrow laptop. */
  .nav-cities { position: relative; }
  .nav-cities-menu {
    position: absolute; inset-inline-end: 0; top: calc(100% + .5rem);
    z-index: 20;
    display: flex; flex-direction: column; gap: 0;
    min-width: 11rem;
    padding: .25rem 1rem;
    background: var(--paper);
    border: 1px solid var(--rule);
    box-shadow: 0 14px 28px rgba(11, 11, 11, .10);
  }
  .nav-cities-menu a { white-space: nowrap; padding-block: .6rem; }
  .nav-cities-menu a + a { border-block-start: 1px solid var(--rule); }}



@media (max-width: 47.99rem) {
  /* INSIDE THE PANEL IT IS AN ACCORDION, not a second floating layer over a
     panel that is already floating. The cities indent so the row reads as five
     children of one item rather than as five more pages. */
  .nav-cities > summary { border-block-end: 1px solid var(--rule); }
  .nav-cities-menu { display: flex; flex-direction: column; }
  .nav-cities-menu a { padding-inline-start: 1rem; }}



.nav-toggle, .burger { display: none; }

@media (max-width: 47.99rem) {
  /* gap: 0 on the ROW, and the breathing space moved onto the wordmark instead.
     A row gap sits between the checkbox and the icon too, and 16px of it was
     enough to pull the tap target off the drawing again after the first fix. */
  .masthead { flex-wrap: nowrap; align-items: center; gap: 0; }
  .masthead .wordmark { padding-inline-end: 1rem; }

  /* ONE HEIGHT ON A PHONE, and the shrink-on-scroll does not apply here. The tap
     target is 44px and must stay 44px, so the only thing left to give is the air
     around it: 10px instead of 20px takes the bar from 84px to 64px. A bar that
     changes height is also a bar that can fight the scroll position, which is the
     fault this file already carries a fix for. */
  .masthead, .masthead-bar:not([data-scrolled="false"]) .masthead {
    padding-block: .625rem;
  }

  /* The checkbox and the icon SIT ON TOP OF EACH OTHER BY CONSTRUCTION, both in
     flow, the icon pulled back over the box by exactly its own width. Positioning
     the box absolutely instead put the real tap area 12px off the drawn one -- the
     left of the icon did nothing and there was a live strip at the screen edge.
     Nothing here is a magic number, so nothing here can drift apart again. */
  /* ESPANOL IS ALWAYS TAPPABLE (JP, 17/09). It used to live inside the panel,
     so on a phone the only way to change language was to open the burger first
     -- one hidden tap in front of the thing a Spanish-speaking reader needs
     most, on a site whose two languages are deliberately level. It rides in the
     bar now, between the wordmark and the burger, and it is the SAME element
     the desktop row uses.

     The auto margin moves HERE, off the checkbox. Whichever item carries it
     eats all the free space and lands everything after it at the right-hand
     edge, so the language switch and the burger end up adjacent with the gap in
     front of them rather than between them. */
  /* IT IS A SIBLING OF THE MENU LINKS, NOT A HEADLINE (JP, 17/09). In the bar it
     was inheriting the DESKTOP row's 14px at weight 400 while the links inside
     the panel are 12px at weight 500 -- so the one word visible with the menu
     shut was the largest and lightest thing on the bar, and it sat beside a
     signature at 36px arguing with it. Same face, same case, same tracking as
     the panel links, one step smaller than them at 11px, because the mark is
     what the bar is for and this is a way out of the language you are in.
     THE TARGET DOES NOT SHRINK WITH THE TYPE. Type size and target size are
     independent: the padding grows to .55rem so the tap stays 28.6px, over the
     24px floor, which the 11px text on its own would not clear. */
  .masthead > .lang {
    order: 1;
    margin-inline-start: auto;
    font-size: .6875rem;
    font-weight: 500;
    letter-spacing: .065em;
    padding-block: .55rem;
    padding-inline-end: .75rem;
    white-space: nowrap;
  }
  .nav-toggle {
    display: block; flex: none; order: 2;
    width: 2.75rem; height: 2.75rem;
    margin: 0;
    opacity: 0; cursor: pointer; position: relative; z-index: 2;
  }
  .burger {
    display: flex; flex-direction: column; justify-content: center; align-items: center;
    gap: 5px; width: 2.75rem; height: 2.75rem; flex: none; order: 3;
    margin-inline-start: -2.75rem;
    pointer-events: none;   /* the box underneath takes the tap */
  }
  .burger span {
    display: block; width: 22px; height: 2px; background: var(--ink);
    transition: transform 200ms var(--ease), opacity 120ms var(--ease);
  }
  .nav-toggle:checked ~ .burger span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
  .nav-toggle:checked ~ .burger span:nth-child(2) { opacity: 0; }
  .nav-toggle:checked ~ .burger span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
  .nav-toggle:focus-visible ~ .burger { outline: 2px solid var(--ink); outline-offset: 3px; }

  /* The panel hangs off the BAR, not the header, so it spans the full width even
     though the header is held inside the 78rem column. `.masthead-bar` is sticky,
     which is enough to make it the containing block. */
  .nav {
    display: none;
    position: absolute; inset-inline: 0; top: 100%;
    flex-direction: column; align-items: stretch; gap: 0;
    padding: .25rem clamp(1rem, 5vw, 2rem) .75rem;
    background: var(--paper);
    border-block-start: 1px solid var(--rule);
    box-shadow: 0 14px 28px rgba(11, 11, 11, .10);
  }
  .nav-toggle:checked ~ .nav { display: flex; }
  .nav a, .nav-cities > summary {
    font-size: 1rem; padding-block: .8rem;
    border-block-end: 1px solid var(--rule);
  }
  .nav a:last-child { border-block-end: 0; }}



@media (prefers-reduced-motion: reduce) {
  .burger span { transition: none; }}


/* No negative margins and no 100vw: the figure is simply not inside the column.
   Both bleed tricks measured 4vw past the viewport on each side at every width
   -- 388.8px of image in a 360px screen -- because a percentage margin resolves
   against the padded column, not the page. Sitting outside .wrap cannot drift. */
.hero-figure {
  margin: 0 0 clamp(2rem, 5vw, 4rem);
  /* The entrance scales the painting from 1.08, and an unclipped transform
     widens the PAGE while it settles: measured 388.8px of image in a 360px
     viewport, a real sideways scroll for the second and a half it lasts.
     Clipping here contains it; the effect is unchanged. */
  overflow: clip;
}
@media (max-width: 40rem) {
  .hero-figure img { height: min(62svh, 34rem); }}



/* Padding on ONE side only. Two stacked sections each adding var(--step) put
   16rem of dead space between them at 1440 — measured, not guessed. */
section { padding-block: 0 var(--step); }
/* The last section closes on the standard band value, not on 1.2x an older,
   larger step token -- that produced 147px against every other band's 72. */
section:last-of-type { padding-bottom: clamp(3rem, 5.3vw, 4.5rem); }
/* `.section-head .h2 { margin-bottom: .75rem }` removed 15/09 — it was owner
   number two of the heading-to-subtitle gap. See the header-group component. */

/* ---------- the grid ----------
   Fixed-ratio frames. Every caption lands on the same line, which the current
   site never manages — its rows are ragged because each cell is its own height. */

/* Twelve identical squares is a catalogue. A room is not hung that way, and a
   painter's proportions are part of the work: a 253 x 150 and a 30 x 30 are
   different objects and the page should say so. Twelve columns, and each work
   claims a span and a vertical offset from its own shape. */
.grid {
  display: grid;
  gap: clamp(2rem, 4.5vw, 4.5rem) clamp(1.25rem, 2.5vw, 2rem);
  list-style: none; margin: 0; padding: 0;
}
/* NO PLATE UNDER A PHOTOGRAPH (JP, 15/09). Every image on the site was one of
   two things: a painting, which sits on the band with nothing behind it, or a
   photograph, which sat on a warm-white card with a padded border. Two
   treatments for one job. The card is gone; `overflow: hidden` stays, because
   it is what clips the rise on hover. */
/* NO CLIPPING. `overflow: hidden` belonged to a padded cell that cropped an
   oversized image; with the cell gone it only ate the top 8px of the rise and
   opened a gap under the photograph, so the lift read as the image shrinking.
   A painting lifts clear of the band and so does a photograph. */
.frame { display: block; }
.frame img { display: block; }

.cap { margin-top: 1.1rem; }
.cap-meta {
    color: var(--ink-soft);
  margin: .35rem 0 0; font-variant-numeric: tabular-nums;
}
.cap-where { display: block; }

/* --- SOLD OR AVAILABLE ----------------------------------------------------
   JP, 22/09: "que se distinga, y muy distinguido" -- in the WORK'S OWN ficha
   tecnica, behind the photograph. It was tried on every plate of the hang first
   and taken back off within the hour: a word repeated down a grid of ninety
   paintings is a shop shelf, and the same word in the row of facts a buyer
   opened the page to read is just a fact. It replaces the Location row there,
   because the city never was a separate fact from availability.

   CAPS HERE, AND ONLY HERE. The note on `.cap-meta` argues against capitals
   and is right about a sixty-character label -- but this is one word, which is
   the four-word eyebrow case that note exempts, and one word in caps is what
   makes it readable across a page at a glance instead of read line by line.

   THE TWO STATES ARE DIFFERENT SHAPES, NOT DIFFERENT COLOURS. Sold is a solid
   block, available is an outline, so the two are told apart in greyscale, at a
   glance, and by a reader who cannot separate the hues. Both are built
   from `currentColor`, which is the rule this stylesheet already runs on: the
   bands alternate ink and paper, and a component that NAMES a colour is correct
   on one ground and wrong on the other. The solid state cannot inherit that way
   -- it needs the band's own background as its text colour -- so it is the one
   thing declared per band, just below. */
.spec .state + .state-where { margin-left: .55rem; }
.state {
  font-family: var(--sans);
  font-size: .75rem; line-height: 1; font-weight: 600;
  text-transform: uppercase; letter-spacing: .1em;
  padding: .42em .7em .38em; border: 1px solid currentColor;
  white-space: nowrap;
}
.state--free { background: transparent; }
.state--sold { background: currentColor; }
/* The solid one, once per ground. `color` here is the PILL'S TEXT, painted in
   whatever the band behind it is, while `background: currentColor` above takes
   the colour the band gives it. */
.band--paper .state--sold, .state--sold { color: var(--paper); background: var(--ink);
                                          border-color: var(--ink); }
.band--ink .state--sold { color: var(--ink); background: var(--paper);
                          border-color: var(--paper); }
/* The city sits BESIDE the word, never inside it: it is information, not a
   state, and putting it in the pill would give a Caracas work a wider badge
   than a Miami one for no reason a reader could name. It stays a link -- the
   reader who likes this painting is the one asking what else is near them. */
.state-where { font-family: var(--sans); font-size: .8125rem; }

/* The group heading on /obra. Set as a heading rather than a label: a serif at
   reading size above a rule tells you what you are looking at without the
   all-caps tracking that makes a gallery page read like a storefront aisle. */
.group-head {
  font-family: var(--serif); font-weight: 400;
   margin: 0 0 clamp(1.5rem, 3vw, 2.5rem);
  padding-bottom: .85rem; border-bottom: 1px solid var(--rule);
}

.section-foot { margin-top: clamp(2rem, 4vw, 3rem); }
/* NO PLATE HERE EITHER (15/09). The detail page mounted its painting on a warm
   card with up to 40px of padding -- the biggest white border on the site, on
   every one of the 131 work pages, while the gallery that sent the reader here
   showed the same painting with nothing behind it. */
.work-figure { margin: 0; }
.work-figure img { margin-inline: auto; }
/* Tabular figures so 150 x 100 and 253 x 150 align down the column: a spec
   list with proportional numerals reads as prose about a painting, not as its
   measurements. */
.spec { margin: 0; font-size: var(--t-meta); font-variant-numeric: tabular-nums; }
.spec div { display: flex; gap: 1rem; justify-content: space-between;
            padding-block: .7rem; border-bottom: 1px solid var(--rule); }
.spec dt { color: var(--ink-soft); }
.spec dd { margin: 0; text-align: right; }
.work-note { font-size: .8125rem; color: var(--ink-soft); margin: 1.25rem 0 0; }

/* The ask sits BELOW the work, always. Never above it, never floating. */
.ask { margin-top: 2rem; }

/* THE YEAR COLUMN IS THE SPINE. Fixed width, tabular figures, unbroken from 2018
   to 2026. Every entry hangs off the same left edge, which is the difference
   between a record and a list of sentences that happen to start with a date. */
/* 48rem, not 52: measured at 1440 the entry line ran 78 characters, past the 75
   where the eye starts losing the return sweep. At 48rem it reads 72. */
.cv { max-width: 48rem; }
.cv-head {
  font-family: var(--serif); font-weight: 400;
   
  margin: clamp(2.5rem, 5vw, 4rem) 0 0;
  padding-bottom: .85rem; border-bottom: 1px solid var(--ink);
}
.cv-head:first-child { margin-top: 0; }
.cv-list { list-style: none; margin: 0; padding: 0; }
.cv-row {
  display: grid;
  grid-template-columns: 4.5rem minmax(0, 1fr);
  gap: 0 1.25rem;
  padding: .95rem 0;
  border-bottom: 1px solid var(--rule);
  /* 16px floor even on the narrowest phone: these are the lines a curator
     actually reads, and 15px is where a record starts to feel like fine print. */
  font-size: var(--t-meta);
  line-height: 1.5;
}
.cv-year {
  font-variant-numeric: tabular-nums;
  color: var(--ink-soft);
  letter-spacing: .01em;
}
.cv-entry { display: block; }
/* THE SHOW'S NAME AND ITS VENUE, TOLD APART BY INK RATHER THAN BY FACE.
   The name used to be serif italic inside an otherwise sans record -- 14px, but
   a fifth treatment all the same, and the one the review names last. The two
   facts still carry different weights of attention: the name is full-strength
   ink, the venue under it is the quieter ink. No bold anywhere; bold in a serif
   this light is a different typeface wearing the same name. (15/09) */
.cv-name { font-family: var(--sans); font-style: normal; font-size: 1em; display: block; }
.cv-venue { display: block; color: var(--ink-soft); margin-top: .15rem; }
.cv-venue--solo { margin-top: 0; color: var(--ink); }

/* A RECORD ENTRY THAT IS ALSO A LINK. The four films joined the record 16/09,
   and they are the only rows in it a reader can open. Underlined on the same
   offset the rest of the site's links use, so the row still reads as a record
   line and not as a button. */
.cv-link {
  color: inherit;
  /* 24px OF TARGET, NOT 21px. The film rows are the only lines in the record a
     reader can tap, and at the record's 14px type a bare block runs 21px --
     under the 24px AA floor, on both phone widths and in both languages. The
     padding buys the height and the matching negative margin gives it back to
     the layout, so the row rhythm is unchanged and only the target grows.
     Type size is not target size: the type here was never the problem. */
  display: block;
  padding-block: .15rem;
  margin-block: -.15rem;
  text-decoration: underline;
  text-underline-offset: .22em;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--rule);
}
.cv-link:hover, .cv-link:focus-visible { text-decoration-color: currentColor; }
/* An undated row still holds the year column, so the entries below Press line
   up with the four lists above instead of starting 60px to their left. */
.cv-year--none::before { content: "B"; }
.cv-note { font-size: .875rem; color: var(--ink-soft); margin: 1.25rem 0 0; max-width: 42ch; }

@media (max-width: 30rem) {
  /* The spine collapses on a narrow phone: a 4.5rem column plus a venue name is
     under 20 characters of entry, which breaks every line into three. */
  .cv-row { grid-template-columns: minmax(0, 1fr); gap: .35rem; }
  .cv-year { order: -1; font-size: .8125rem; }}



/* ---------- steps ---------- */

/* THE STEPS ARE BODY COPY, and they used to be 16px only because nothing said
   otherwise and the body inherits 16px. Beside paragraphs at 18px that reads as
   a deliberate third size for text that is doing exactly the same job as the
   paragraph above it -- the review's last type finding. (15/09) */
.steps { list-style: none; counter-reset: s; margin: 0; padding: 0; max-width: 40rem; }
.steps li {
  counter-increment: s; position: relative;
  font-size: var(--t-body); line-height: 1.6;
  padding: 1.1rem 0 1.1rem 3rem;
  border-bottom: 1px solid var(--rule);
}
.steps li::before {
  content: counter(s);
  position: absolute; left: 0; top: 1.1rem;
  font: 400 1rem/1.65 var(--serif); color: var(--ink-soft);
}

/* Prev / next / back, as one line at the foot of a work. The titles are the
   point: "Anterior" alone asks the reader to gamble, the name of the next
   painting is a reason to keep going. */
.work-nav {
  display: grid; gap: 1.5rem 2rem; align-items: end;
  grid-template-columns: 1fr;
  margin-top: var(--step); padding-top: clamp(1.5rem, 3vw, 2.5rem);
  border-top: 1px solid var(--rule);
}
@media (min-width: 48rem) {
  .work-nav { grid-template-columns: 1fr auto 1fr; }
  .work-nav .go { justify-self: center; }
  .work-nav-next { text-align: right; }}


/* THUMBNAIL BESIDE THE LABEL, mirrored on the next side so both thumbnails sit
   on the outside and the two labels face the middle. `contain`, never `cover`:
   a crop is a framing decision, and the one rule this hang runs on is that
   nobody but the painter makes those. The box is fixed so the row does not
   jump between a tall canvas and a wide one; the work floats inside it. */
.work-nav-side {
  text-decoration: none; max-width: 18rem;
  display: flex; align-items: center; gap: .875rem;
}
.work-nav-thumb { flex: 0 0 72px; width: 72px; height: 72px; display: block; }
.work-nav-thumb img {
  width: 100%; height: 100%; object-fit: contain; object-position: center;
  display: block;
}
.work-nav-text { display: block; min-width: 0; }
.work-nav-next { margin-left: auto; justify-content: flex-end; }
.work-nav-dir {
  display: block; font-size: .75rem; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-soft);
}
.work-nav-title {
  display: block; font-family: var(--serif); font-size: 1.25rem;
  line-height: 1.2; margin-top: .35rem;
  transition: opacity .3s var(--ease);
}
.work-nav-side:hover .work-nav-title { opacity: .55; }

/* ---------- footer ---------- */

/* ONE COLOUR PER PAGE, AND ONLY HERE. Nico's request, JP confirmed 2026-09-14,
   naming five: verde oscuro, morado, azul eléctrico, amarillo vivo, naranja.

   IT DOES NOT REOPEN THE ACHROMATIC RULE, it draws its boundary. The interface
   is grey and paper because his painting is already at maximum saturation, and
   a coloured chrome competes with the only thing a gallery is looking at. The
   footer is the one band with no work in it -- it is where the reader has
   finished looking -- so colour there is the first thing on the page that is
   not fighting a painting. Nothing above it moves.

   FIVE COLOURS, FIVE PAGES, ONE EACH, assigned so the page carrying the most
   work carries the quietest ground and the page asking for a reply carries the
   loudest. A work page inherits obra's, because it is obra.

   EVERY PAIR IS MEASURED, not chosen by eye -- contrast-check.py asserts 4.5:1
   on the small print, which is the text most likely to fail. Orange and yellow
   take near-black; the three dark grounds take white. There is no opacity on
   any of this text: dropping a 4.8:1 pair to 70% is how a footer that passed
   the check stops passing on the screen. */
/* The palette only. Background and colour are applied further down, in the one
   `.foot` block that survives the cascade -- setting them here as well would
   put two rules in the file claiming to decide the same thing, which is what
   broke this in the first place. */
/* The colour block is the separation. A rule on top of it draws a seam. */
.foot:not([class*="foot--"]) { border-top: 1px solid var(--rule); }
/* HOME WAS ELECTRIC BLUE until 24/09 -- JP: "i hate that blue". Ochre, the
   warm ground of the commissions clip, 7.49:1 against white. */
.foot--index    { --foot-bg: #724E00; --foot-fg: #FFFFFF; } /* ocre */
/* `obras` is the collection key a single work page carries, `obra` the index.
   Both are the same place to a reader, so both take the same ground. */
.foot--obra,
.foot--obras    { --foot-bg: #0E3B2E; --foot-fg: #FFFFFF; } /* verde oscuro   */
.foot--artista  { --foot-bg: #4A1E6E; --foot-fg: #FFFFFF; } /* morado         */
/* Darkened from #E2521B on 2026-09-14. That orange was the one pair in the set
   that only reached 4.5:1 -- it passed, and every other footer cleared 7:1, so
   one page was quietly the weakest thing on the site. This is the LIGHTEST
   orange that clears 7:1 against white, so it gives up the least hue to get
   there: still 17 degrees, still 0.96 saturation, just darker. */
.foot--encargos { --foot-bg: #A23207; --foot-fg: #FFFFFF; } /* naranja        */
.foot--contacto { --foot-bg: #0B3A45; --foot-fg: #FFFFFF; } /* amarillo vivo  */
/* CITIES IS A PAGE IN THE NAVIGATION NOW, so it is a page with a ground. It used
   to wear `obra`'s green, because a city page tells the rest of the site it IS
   Work seen through one city -- which is right for the nav and for the
   structured data, and wrong for the one band whose job is to say where you
   are. Burgundy is the gap in the set: the five were blue, green, purple,
   orange and yellow, and nothing was warm and dark. */
.foot--ciudad   { --foot-bg: #7A1230; --foot-fg: #FFFFFF; } /* burdeos        */
/* THE FOOTER READS TOP TO BOTTOM: his name, then where to go, then how to reach
   him, then the small print. Four things in the order a reader wants them, and
   no labels over any of them -- an address is recognisable as an address.

   THE PAGES AND THE CONTACTS ARE THE TWO HALVES (JP, 17/09). `space-between`
   with wrap put them at opposite ends of a 78rem band with a metre of nothing
   between, which reads as two unrelated footers. They are columns now: the
   pages stack on the left, the address and the accounts on the right, and both
   collapse to one column on a phone. `auto-fit` rather than a fixed pair, so
   the single-column case needs no second rule. */
/* IT READS IN LINES NOW, NOT IN COLUMNS (JP, 17/09). Six pages stacked and an
   address and three accounts stacked beside them made a footer 443px tall on a
   laptop and 495px on a phone -- a second page under every page, and on a phone
   it was taller than the screen it ended. Ten items that each take one line make
   ten lines; the same ten in rows take three.

   It is flex and not the old grid because the two halves are no longer equal
   columns: the pages want the width they need and the contact details want the
   rest, and on a phone they simply stack. `auto-fit` columns cannot express
   that without a second rule per breakpoint. */
.foot-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 1rem 3rem;
  margin-top: 2.25rem;
}
/* THE PAGES ARE A ROW. They were a column on the argument that a reader down
   here is choosing rather than scanning -- true of the destination, not of the
   shape. Six links wrapping across the width are read exactly as easily and
   cost a sixth of the height. The row gap is 0: the padding on each link is
   already what makes the target, and a second gap on top of it reopens the
   height this is closing. */
.foot-nav {
  display: flex; flex-wrap: wrap;
  align-items: baseline; gap: 0 1.5rem;
}
/* The address and the three accounts sit on one line and wrap to two when they
   have to, rather than being four stacked lines by construction. */
.foot-reach {
  display: flex; flex-wrap: wrap;
  align-items: baseline; gap: 0 1.5rem;
}
@media (max-width: 48rem) { .foot-grid { margin-top: 1.75rem; }}


/* Footer links were 20–23px tall, under the 24px WCAG 2.2 minimum target size.
   Padding rather than font-size: the footer is meant to be quiet, and a thumb
   does not care how big the letters are. */
/* TYPE SIZE AND TARGET SIZE ARE INDEPENDENT. Moving the footer to the shared
   13px navigation role took these links from 35px tall to 30px -- still over
   the 24px AA floor, but smaller for no reason a reader benefits from. The
   padding buys the height back without reopening the type scale. Measured, not
   estimated: 13px x 1.4 line-height + 2 x .5rem = 34px. */
.foot a { text-decoration: none; display: inline-block; padding-block: .5rem; }
.foot .eyebrow { color: inherit; }
.foot-small { font-size: var(--t-nav); line-height: 1.5; color: inherit; margin: 1.5rem 0 0; }
/* THE CREDIT RUNS ON, IN ONE TYPE SIZE (JP, 21/09). It was given a line of its
   own earlier the same day, on the argument that running on after "All rights
   reserved" makes it read as part of Nicolás's copyright. Seen on the page, the
   break is what rings the bell: a short line alone under a footer is a line the
   eye stops on, which is the opposite of what a credit on someone else's site
   should do. It goes back inline -- same 13px, same colour, same sentence
   rhythm as the copyright beside it. Nothing here sets a size, deliberately:
   any rule at all would be a second type for one string. */
.social { display: flex; flex-wrap: wrap; gap: 1rem; font-size: .875rem; }

/* THE FOUR MARKS IN THE FOOTER (JP, 17/09).
   Masks, not images and not inline SVG, for the reason the signature above them
   is a mask: this footer travels through the palette every twelve seconds, so
   each mark has to change colour four times a minute. An <img> cannot inherit a
   colour, and inline SVG would put the same paths into all 272 pages twice. A
   mask painted with `currentColor` follows any ground and stays one cached file.
   `-webkit-mask` ships beside it or Safari draws a coloured rectangle.

   THE TARGET IS THE LINK, NOT THE DRAWING. The mark is 20px, which is under the
   24px floor on its own; the padding carries the link to 40px square, and the
   row keeps its 1rem gap so two marks are never closer than 16px. Type size and
   target size are independent, and an icon is the case where forgetting that
   costs the most -- there is no text to make the box big by accident. */
.reach {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.5rem; height: 2.5rem;
  padding: 0;
}
.icon {
  display: block;
  width: 1.25rem; height: 1.25rem;
  background-color: currentColor;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center;  mask-position: center;
  -webkit-mask-size: contain;     mask-size: contain;
}
.icon--mail      { -webkit-mask-image: url("assets/icons/mail.86f31d6a.svg");      mask-image: url("assets/icons/mail.86f31d6a.svg"); }
.icon--instagram { -webkit-mask-image: url("assets/icons/instagram.f1ba337b.svg"); mask-image: url("assets/icons/instagram.f1ba337b.svg"); }
.icon--tiktok    { -webkit-mask-image: url("assets/icons/tiktok.ecd7c8c4.svg");    mask-image: url("assets/icons/tiktok.ecd7c8c4.svg"); }
.icon--youtube   { -webkit-mask-image: url("assets/icons/youtube.8033ce15.svg");   mask-image: url("assets/icons/youtube.8033ce15.svg"); }

/* THE UNDERLINE IS WRONG UNDER A DRAWING. `.foot a` and `.social a` grow a rule
   on hover, which is right for a word and reads as a stray line under a 20px
   mark. These lift instead -- the same 8px rise every photograph on the site
   uses when the pointer arrives, so the footer answers a pointer the way the
   rest of the site does. */
.reach::after { display: none; }
.reach .icon { transition: transform 200ms var(--ease), opacity 200ms var(--ease); }
.reach:hover .icon, .reach:focus-visible .icon { transform: translateY(-2px); }
@media (prefers-reduced-motion: reduce) {
  .reach .icon { transition: none; }
  .reach:hover .icon, .reach:focus-visible .icon { transform: none; opacity: .72; }}


/* The row was spaced for words. Four 40px boxes sit closer without crowding, and
   the address is no longer a line of its own above them. */
/* 8px BETWEEN BOXES, NOT 4. The marks are 40px targets, which clears the 24px
   floor on its own -- but this file already holds an 8px minimum between
   adjacent targets, found the hard way on the rooms grid, and four icons in a
   row is exactly the case it was written for. */
.foot-reach { gap: 0 .5rem; }
.social { gap: .5rem; }

/* ---------- NOTHING ARRIVES ----------
   The work used to be uncovered on scroll -- the frame wiping open while the
   painting settled back from a slight overscale -- and everything else rose
   quietly behind it. JP killed all of it on 2026-09-04: it read as childish,
   and the pictures were already there.

   So the page is simply finished. No entrance, no stagger, no clip, nothing on
   the hero. What stays is HOVER: a work answers when you put the mouse on it,
   and a link draws its rule. That is state, not performance, and it is the only
   movement left on the site.

   The script that drove the entrance is gone with it -- there is now no
   JavaScript on this site at all, so there is no `.js` class and nothing to
   guard against its absence. */

@media (prefers-reduced-motion: reduce) {
  /* REDUCED MOTION IS LESS MOVEMENT, NOT LESS FEEDBACK. This used to kill every
     transition on the page with one !important, which took the hover and focus
     states down with it -- a reader who asks for calm got a site where nothing
     acknowledges being touched. Movement goes; the rules that draw themselves
     under a link stay, because they are state, not motion. */
  *, *::before, *::after { animation: none !important; }
  /* Duration, not removal: the rule under a link still appears and the outline
     still lands, they simply arrive rather than travel. */
  *, *::before, *::after { transition-duration: .01ms !important; }
  .work a:hover .plate img, .work a:focus-visible .plate img,
  .split-plate a:hover .plate img, .aside-work a:hover img,
  .shot:hover img, .shot:focus-visible img,
  .work-nav-side:hover, .work-nav-side:focus-visible { transform: none !important; }
  /* A COLOUR BAND WITH ITS ANIMATION KILLED IS AN INK BAND AGAIN. The rule
     above already drops the background back to `var(--ink)`, but the three
     text tokens are NOT animated, so without this a reader who asks for calm
     would get today's black ground wearing the lighter tiers the colours
     needed -- legible, but not the design. Reduced motion should land on what
     the site looks like now, not on a third version of it. */
  .band--cycle {
    color: var(--paper);
    --ink-soft: var(--soft-on-dark);
    --rule: #34322D;
  }
  .band--cycle a, .band--cycle .go { color: var(--paper); border-bottom-color: var(--paper); }}


/* THE LEAN IS GONE, AND THE <em> STAYS (second-pass review, 15/09).
   "my own way" used to lean, on the argument that it was the half of the
   sentence that is his rather than descriptive. The review's verdict is that
   the site had three visual treatments of one serif -- upright display,
   leaning display, leaning quotation -- doing a single job between them, and
   that the character has to come from the work rather than from repeated
   italics. The ELEMENT is deliberately left in the template: it still carries
   the emphasis for anything reading the markup, it just stops rendering as a
   second typeface. Reversing the direction is this one line. */
/* <em> IS ITALIC BY DEFAULT IN EVERY BROWSER, so removing a rule is not how
   the lean comes off -- it has to be overridden. This was first written as
   `.hero-line em`, and `.hero-line` turns out to be a dead class: it is
   declared twice in this stylesheet and used in no template, so the headline
   went on leaning and the check went on reporting it.
   Scoped to HEADINGS only. Emphasis inside a paragraph is ordinary emphasis and
   still leans; what the review removes is the serif display italic that was
   reading as a second typeface. */
.display em, .h2 em,
.group-head em, .cv-head em { font-style: normal; }



/* --- SECTION HEADINGS ---------------------------------------------------- */
.h2 {
  font-size: var(--t-h2);
  line-height: 1.08;
  letter-spacing: -.02em;
  /* THE LINES ARE EVENED OUT, THE SAME WAY `.display` AND `.h1` ALREADY DO IT
     (JP, 16/09). A heading that runs past one line otherwise fills the first
     line and drops whatever is left onto the second -- "Begin with a photograph
     of the wall, and the story you have in" / "mind." -- and a one-word second
     line reads as a mistake. This is the ROLE, not that one heading: every h2
     on the site that wraps now splits evenly, in both languages, which a manual
     <br> could never do because English and Spanish break at different words.
     `.h2--name` opts out further down: his name is allowed to break where it
     likes. */
  text-wrap: balance;
}

/* PHONE CAP. At the spec's 4rem floor a section heading measured 91px tall on a
   390px screen: "Society inside the canvas" took most of the viewport before a
   word of explanation, so the type outweighed the paintings -- the one thing
   the brief forbids. Capped so the heading announces the section and the work
   stays the loudest thing on screen. */
/* The phone cap that used to live here is gone: --t-h1 and --t-h2 reach their
   44px and 36px floors at 390px on their own, so a second set of sizes for the
   same two roles would be the accumulation this pass exists to remove. */

.group-head, .cv-head {
  font-size: var(--t-h3);
  line-height: 1.15;
  letter-spacing: -.015em;
}

/* --- ROLE 2: THE LEDE. One per section, always under the heading. --------- */
/* THE SUPPORTING SENTENCE, AND IT IS NOW A ROLE RATHER THAN A POSITION.
   This selector list used to end with four `p:first-child` clauses, which meant
   that being the first paragraph in any prose block silently promoted it to
   20px: the artist page's biography opened at 20px/30 and continued at 18px/29
   for no reason anyone had chosen, and the review read that as a fourth text
   treatment. A subtitle now has to SAY it is a subtitle -- `.lede`, `.hero-sub`
   or `.group-sub` in the markup -- and every paragraph of a biography shares
   one body size. (Second-pass review, 15/09.) */
.lede, .group-sub {
  font-family: var(--sans);
  font-size: var(--t-lede);
  font-weight: 400;
  line-height: 1.5;
  letter-spacing: -.01em;
  color: var(--ink-soft);
  max-width: 40rem;
}


.group-sub { margin: 0 auto; }

/* ============================================================================
   THE HEADER GROUP — ONE OWNER FOR EACH GAP (second-pass review, 15/09)

   A label, a heading and the sentence that supports it are one component, and
   the two gaps inside it are set HERE and nowhere else. Before this pass the
   same heading-to-subtitle relationship rendered at 0px on four pages, 12px on
   three, 20px on three and 44px on one, because `.eyebrow` carried a bottom
   margin, `.section-head .h2` carried another, centred prose wrappers carried a
   third and `.said--center` a fourth. Nothing was wrong with any single rule;
   there were simply four of them for one gap.

   THE RULE FOR ANYONE EDITING THIS LATER: a heading never carries a bottom
   margin and a subtitle never carries a top margin of its own. The gap belongs
   to the pair, so it is set on the pair with an adjacent-sibling selector. If a
   gap here looks wrong, change the token -- do not add a margin somewhere else,
   which is exactly how the four owners accumulated.
   ========================================================================= */
:root {
  --gap-label: .75rem;   /* 12px — label to heading, same on both           */
  --gap-sub:   1.25rem;  /* 20px — heading to its supporting sentence       */
  --gap-group: 2rem;     /* 32px — the whole header group to its content    */
}
@media (max-width: 48rem) {
  :root {
    --gap-sub:   1rem;     /* 16px */
    --gap-group: 1.75rem;  /* 28px */
  }}



/* 1 — LABEL TO HEADING. The eyebrow owns it, because a label is always above
       the thing it labels and never below anything. */
.eyebrow { margin: 0 0 var(--gap-label); }

/* THE GROUP LABEL IS THE HEADING'S FIRST LINE, NOT A CAPTION ABOVE IT (JP,
   17/09). "Paintings" was an `.eyebrow` -- 11px sans, soft ink -- sitting over
   "In colour" at the h2's 40px serif, so two halves of one name were set as two
   different things. Same face, size, leading and tracking as `.h2`, and no
   colour of its own so it inherits whatever the head it belongs to is using,
   including on the colour group's travelling band.

   NOT the `.h2` class. `.section-head .h2` increments the section counter and
   prints the number, so sharing the class would number the label too. The type
   is copied deliberately; there is no second scale here to keep in step. */
.h2-line { display: block; }

/* .group-label retired 24/09: the label and the series are now ONE h2. */
.group-label-retired {
  font-family: var(--serif);
  font-weight: 400;
  font-size: var(--t-h2);
  line-height: 1.08;
  letter-spacing: -.02em;
  margin: 0;
}

/* 2 — HEADING TO SUPPORTING SENTENCE. Set on the pair. Every heading class the
       site uses is listed against every subtitle role it can take; a subtitle
       has to declare itself as one (`.lede`, `.group-sub`, `.hero-sub`), which
       is the other half of removing the `p:first-child` promotion. */
.display + .lede, .display + .group-sub,
.h2 + .lede,      .h2 + .group-sub,
.group-head + .lede, .group-head + .group-sub,
.cv-head + .lede,    .cv-head + .group-sub {
  margin-top: var(--gap-sub);
}



/* 3 — THE GROUP TO ITS CONTENT. */
.section-head { margin-bottom: var(--gap-group); }

/* --- ROLE 3: BODY -------------------------------------------------------- */
.prose p { font-size: var(--t-body); line-height: 1.6; letter-spacing: -.005em; max-width: 38rem; }

/* --- ROLE 4: SMALL CAPS. Captions, labels, links. ------------------------- */
.cap-meta, figcaption.cap-meta {
  font-family: var(--sans);
  /* A GALLERY LABEL IS NOT SET IN CAPITALS. These run to sixty-odd characters --
     "Acrílico sobre lienzo · 150 x 120 cm · 2026 / Currently in Caracas" -- and
     uppercase removes the ascenders and descenders a reader recognises words by,
     which is affordable on a four-word eyebrow and not on a full label under
     every painting. Sentence case, one size up from 12px, and the technique
     keeps the capitalisation Nico typed. The eyebrows stay uppercase: they are
     labels of two or three words, which is what the case is for. */
  font-size: var(--t-meta);
  font-weight: 400;
  line-height: 1.5;
  letter-spacing: .005em;
  text-transform: none;
}


.eyebrow{
  font-size: var(--t-label);
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: .08em;
  text-transform: uppercase;
}


/* NAVIGATION AND TEXT ACTIONS ARE ONE ROLE, and a slightly larger one than a
   label: they are targets, not captions. A single tracking, so `.go` no longer
   states a third value for the same thing. */
.go, .nav a, .nav-cities > summary, .wordmark, .lang, .foot a, .social a {
  font-size: var(--t-nav);
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: .06em;
}
.go { text-transform: uppercase; }

.nav a, .nav-cities > summary, .lang {
  font-size: .75rem;
  font-weight: 500;
  letter-spacing: .065em;
  text-transform: uppercase;
  color: var(--ink);
}
.wordmark {
  font-family: var(--sans);
  font-size: var(--t-nav);
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
}

/* --- HIS LOGO (JP, 17/09) -------------------------------------------------
   "NLA | Nicolas Lapadula", the mark and the name both drawn in his own hand.
   It replaces a typeset wordmark in the bar and opens the footer.

   A MASK, NOT AN IMAGE, AND THAT IS THE WHOLE REASON THIS IS CSS. The footer
   moves through the palette every twelve seconds and the masthead sits on
   paper, so one file has to be able to be white in one place and near-black in
   the other. An <img> cannot inherit a colour, and inlining 21KB of path into
   all 272 pages twice each is 11MB of duplicated drawing. A mask painted with
   `currentColor` follows any ground, stays one cached file, and needs no
   second rule for the cycle.

   `-webkit-mask` is not optional -- Safari shipped the prefixed property years
   before the unprefixed one, and without it this is a coloured rectangle where
   a signature should be. Both are declared, unprefixed last. */
.logo {
  display: block;
  background-color: currentColor;
  -webkit-mask: url("assets/nla-logo.b6c5c038.svg") no-repeat center / contain;
  mask: url("assets/nla-logo.b6c5c038.svg") no-repeat center / contain;
  /* The artwork is 2983.0128 x 635.27. Declaring the ratio means a height alone
     sizes it and there are never two numbers to keep in step. */
  aspect-ratio: 2983.0128 / 635.27;
  flex: none;
}

/* THE NAME IS STILL IN THE MARKUP, it is simply not on the screen: the logo
   draws his name as artwork, and artwork is invisible to a crawler and to a
   screen reader. Not `display:none` -- that would hide it from both as well.
   The 1px clipped box is the technique that keeps it announced and findable. */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* IN THE BAR: sized by HEIGHT, because the bar's height is the constraint and
   the ratio solves the width. 4.7:1 is a long mark, so it is kept modest --
   the masthead is furniture and the paintings are the page. */
.wordmark { display: inline-flex; align-items: center; align-self: center; }
/* IT IS BIGGER THAN THE ROW IT SITS IN, AND THE ROW DOES NOT MOVE (JP, 17/09).
   24px was still reading as a smudge -- this mark is 4.7:1, so height is the only
   thing that makes his handwriting legible, and the bar's height is set by the
   nav links at 28px. The negative margins are what separate the two: the drawing
   renders at 36px and CONTRIBUTES 28px to the line, so it overhangs its own line
   box by 4px top and bottom and the bar stays exactly where it was. Measured
   either side of the change: 92.0px before, 92.0px after.
   -4px is not a magic number, it is (36 - 28) / 2. Change the height and this
   changes with it. */
.logo--nav { height: 2.25rem; margin-block: -0.25rem; }
/* On a phone the bar is 64px and its content is the 44px tap target, so 36px
   fits inside it with room and needs no negative margin at all. */
@media (max-width: 48rem) { .logo--nav { height: 2.25rem; margin-block: 0; }}



/* IN THE FOOTER: his name, at the top of the band, large enough to read as a
   signature on the page rather than as a second piece of navigation. Capped in
   WIDTH as well as height so it never runs the full width of a wide screen --
   a 4.7:1 mark at 78rem would be a banner, which this is not. */
.foot-logo { display: block; width: fit-content; }
.logo--foot { height: 2.5rem; max-width: 100%; }
@media (max-width: 48rem) { .logo--foot { height: 1.9rem; }}



/* AN ARTWORK'S NAME IS NOT METADATA. The spec set titles at 12px uppercase --
   the same treatment as the measurements -- which files the name of a painting
   under the same heading as its dimensions. It stays in the serif, which is
   what makes a caption read as a wall label instead of a product listing. */
.cap-title {
  font-family: var(--serif);
  font-size: var(--t-title);
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: -.01em;
  text-transform: none;
  margin: 0;
}

/* --- SECTION NUMBERS ----------------------------------------------------- */
main { counter-reset: sec; }
.section-head .h2{ counter-increment: sec; }


.section-head .h2::before{
  display: block;
  font-family: var(--sans);
  font-size: .75rem;
  font-weight: 500;
  line-height: 1;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 1.25rem;
}



/* 4:5 plate. Portrait, because nine of the twelve works are. The painting is
   CONTAINED, never cropped -- a cropped painting is the one thing an artist's
   site may not do -- and the paper it sits on is the mount. */
/* THE PHOTOGRAPH IS ITS OWN SHAPE. The 4:5 cell and its padding existed to
   make unequal photographs share a card; with the card gone there is nothing
   to make them share, and a fixed cell would letterbox a wide mural again.
   `width`/`height` on the img keep the space reserved, so nothing shifts. */
.frame img { width: 100%; height: auto; }

/* On a phone the works stack one per screen, so there is no row to close and
   nothing to compare a work against. Scaling there only makes small work hard
   to see, so each one takes the plate it needs. */
@media (max-width: 40rem) {
  .frame { aspect-ratio: auto; }
  .frame img { width: 100%; }}



/* ==========================================================================
   THE EDITORIAL HOME PAGE — 2026-09-02, from JP's render.

   Everything above this block still governs the other four pages. This block
   adds the bands, the hang and the split sections the home page needs, and
   overrides the earlier grid only where the render replaces it.
   ========================================================================== */

/* --- BANDS ---------------------------------------------------------------
   The page is a stack of full-bleed bands, alternating paper and ink. This is
   the whole structural idea: a site with no colour of its own still needs a
   rhythm, and value gives it one without a single coloured pixel entering the
   interface. The dark bands also separate the ARGUMENT from the HANG, so a
   curator reading only the type never scrolls through anything that sells. */

/* 72px at 1363, 48px at 390 -- the two ends of the spacing spec, solved rather
   than picked. It was 123px top AND bottom, so every junction between two
   sections cost 246px of nothing before a reader reached the next thing. The
   paintings did not get smaller to buy that back; the emptiness around them
   did. */
.band { padding-block: clamp(3rem, 5.3vw, 4.5rem); }

.band--paper { background: var(--paper); color: var(--ink); }

.band--ink {
  background: var(--ink);
  color: var(--paper);
  /* The rule and the soft ink both have to be redefined, not merely inherited:
     #5A574F on near-black measures 2.7:1 and #CFC9BC is a hairline meant for
     paper. Redefining the tokens on the band keeps every child correct without
     a single component knowing which ground it is on.
     24/09: the soft tier on every dark ground is ONE token, #D6D1C8 (12.95:1 on
     ink), the value the colour band already needed -- JP's unify brief. */
  --ink-soft: var(--soft-on-dark);
  --rule: #34322D;
}
.band--ink a { color: var(--paper); }
.band--ink .go { border-bottom-color: var(--paper); }

/* --- THE COLOUR BAND ------------------------------------------------------
   An ink band that carries the footer's palette instead of ink, and moves
   through it AS THE READER SCROLLS PAST. JP, 2026-09-15.

   IT IS DRIVEN BY THE READER, NOT BY A CLOCK. A timed cycle has to guess how
   long the band is on screen: too slow and a reader scrolling past sees one
   slow drift inside a single colour and reads it as nothing happening, too
   fast and it pulls at someone trying to read the paragraph. `view()` runs
   whole turn across the time the band is crossing the viewport, so every
   reader sees it exactly once at their own scrolling speed, and it settles
   when they stop to read.

   YELLOW IS NOT IN THE CYCLE, and that is measured, not taste. #FFD400 puts
   body text at 1.27:1 and the soft tier at 1.77:1. The footer can flip to
   dark text at the yellow because it has ONE text tier and a hard cut. A band
   has THREE and it cross-fades, so there is no frame where the flip is safe:
   the best any text colour can do against the orange-to-yellow midpoint is
   4.28:1. Dark colours only, white text, no compromise at any frame.

   ALL THREE TEXT TIERS ARE REDEFINED. This is the part that breaks silently
   if it is left out -- the band's tokens are tuned for near-black, and the
   worst frame of the cycle is the orange. Measured across the whole cycle,
   not at the stops:

     body and links  #F4F1EA -> #FFFFFF   6.21:1 -> 7.01:1
     --ink-soft      #A8A296 -> #D6D1C8   2.76:1 -> 4.61:1  (FAILED before)
     --rule          #34322D -> #8A8479   1.00:1 -> 1.89:1  (VANISHED before)

   #D6D1C8 is the DARKEST tone that clears AA across every frame, so the soft
   tier is only slightly quieter than the body here rather than genuinely
   soft. That tier largely does not survive a colour ground; it is the price.

   NEVER PUT THIS ON A BAND THAT CARRIES A PAINTING. Five of the twelve ink
   bands hold an image, the home page's investigation band among them -- and
   that one holds the single monochrome work precisely because black is the
   only ground that does not fight it. A moving colour behind a painting is
   the one thing this effect must not do. */
/* THE BLOCK ABOVE DESCRIBED THIS RULE; IT DID NOT EXIST (found 17/09). The
   class had never been applied to an element, so nothing ever exercised it:
   the tier values were written in the comment, the reduced-motion FALLBACK was
   implemented, and the animated state -- the one the comment is about -- had
   no `animation` and no tier overrides at all. A band given the class would
   have rendered as a plain ink band wearing near-black tokens. Prose cannot
   fail; only a rule can.

   IT LIVES INSIDE `no-preference` ON PURPOSE. The reduced-motion block ~370
   lines above sets these same three tokens back to their ink values, and a
   media query adds no specificity -- so an unconditional rule down here would
   simply out-order it and hand a reader who asked for calm the colour-ground
   tiers on a black band. Each state declares its own; neither can reach the
   other. */
@media (prefers-reduced-motion: no-preference) {
  .band--cycle {
    animation: band-cycle 12s linear infinite;
    color: #FFFFFF;
    --ink-soft: #D6D1C8;
    --rule: #8A8479;
  }
  .band--cycle a { color: #FFFFFF; }
  .band--cycle .go { border-bottom-color: #FFFFFF; }

  /* IN COLOUR TAKES ITS COLOURS FROM THE PAINTING ABOVE IT (JP, 17/09). The
     group whose subject is colour was cycling the site's page colours, which
     are the same four everywhere and have nothing to do with the work on that
     page. These five are JP's, given 17/09; see the keyframes for which two
     ship exactly as he wrote them and which three had to come down in
     lightness to carry white type.
     ANIMATION-NAME ONLY. `animation` is a shorthand, so restating it here would
     silently reset the 12 seconds and the timing declared above, and the band
     would drift out of step with every footer on the site. */
  .band--cycle-obra { animation-name: obra-cycle; }
  /* EACH CITY TAKES ITS COLOURS FROM ITS OWN PHOTOGRAPH (JP, 22/09). */
  .band--cycle-barcelona { animation-name: city-barcelona; }
  .band--cycle-caracas   { animation-name: city-caracas;   }
  .band--cycle-madrid    { animation-name: city-madrid;    }
  .band--cycle-miami     { animation-name: city-miami;     }
  .band--cycle-panama    { animation-name: city-panama;    }
  .band--cycle-encargos  { animation-name: encargos-cycle; }}

/* COMMISSIONS, FROM ITS HERO CLIP (JP, 22/09): the ochre ground, the painting's
   blue, its red, the room's shadow -- sampled from the clip's last frame and
   deepened to white-safe. Worst frame across every transition 7.31:1. */
@keyframes encargos-cycle {
  0%,100% { background-color: #724E00; }
  25%     { background-color: #395B69; }
  50%     { background-color: #9F2C04; }
  75%     { background-color: #2A2118; }
}

/* A CITY HERO PAINTS ITSELF ON (JP, 22/09). The paintings' heroes are clips of
   the work being painted; a city's is a photograph, and it sat there static. So
   on load the script in base.html lays the photograph down in broad bristled
   strokes, top to bottom, in about two seconds, and then leaves it alone.
   HIDDEN ONLY WHILE A SCRIPT IS PAINTING IT. `html.js` is set in the head and
   `is-painting` by the painter itself; if the painter never starts, the
   failsafe fades the photograph in at 1.5s, and with scripting off or reduced
   motion none of this applies at all. */
@media (prefers-reduced-motion: no-preference) {
  .js [class*="hero-figure--ciudad-"]:not(.is-painted) .hero-still {
    opacity: 0; animation: paint-failsafe .4s 1.5s forwards;
  }
  .js [class*="hero-figure--ciudad-"].is-painting .hero-still { animation: none; }}
@keyframes paint-failsafe { to { opacity: 1; } }
.paint-canvas {
  position: absolute; inset: 0; width: 100%; height: 100%;
  z-index: 2; pointer-events: none; display: block;
}

/* CARACAS SHOWS MORE OF ITSELF (JP, 22/09): el Avila, the cloud on it and the
   park under it only read together, so this band is taller than the others on a
   wide screen -- 46vw, never past 82% of the screen's height. At 1440x900 that
   shows 69% of the photograph's height instead of 52%. */
@media (min-width: 40.01rem) {
  .hero-figure.hero-figure--ciudad-caracas img { height: min(max(clamp(340px, 56vh, 620px), 46vw), 82vh); }}

/* THE COMMISSIONS HERO SHOWS THE ROOM (JP, 22/09, second pass). The first
   pass aimed a crop at the canvas and cut the sofa away, and the sofa is the
   point: it is what says this is a work made FOR a space. So:
   - THE CLIP ITSELF IS CROPPED, not the band. The canvas sat 5% right of
     centre in the generated frame; 262px came off its left edge (2560 -> 2298)
     so the canvas is at exactly 50%, under the centred "Commissions" heading.
   - ON A WIDE SCREEN THE BAND TAKES THE CLIP'S OWN SHAPE, 1920x1204, capped at
     88% of the screen's height -- at 1440x900 that shows 88% of the frame,
     canvas, wall, sculpture and sofa.
   TWO CLASSES, ON PURPOSE: `.hero-figure img` further down the file sets
   `object-position: center` and a height at the same one-class weight, and the
   later rule wins -- so a one-class version of this was silently ignored. */
.hero-figure.hero-figure--encargos img, .hero-figure.hero-figure--encargos video { object-position: 50% 40%; }
@media (min-width: 40.01rem) {
  /* THE SOFA STAYS IN, WHOLE (JP, 22/09: "if you need to go back to the bigger
     hero, it's fine -- just make sure it looks nice"). Measured on the frame,
     the sofa runs from 83% to 100% of its height, so any band shorter than the
     frame cut it; fitting the band to the screen showed only its back. So the
     band is the frame MINUS its top 9% -- wall above the canvas, which starts at
     12.2% -- at full width: 57.06vw tall, bottom-aligned. On a 1440x900 laptop
     that is the screen; on wider screens the sofa's base is a short scroll. */
  .hero-figure.hero-figure--encargos img { height: calc(100vw * 1204 / 1920 * .91); }
  .hero-figure.hero-figure--encargos img, .hero-figure.hero-figure--encargos video { object-position: 50% 100%; }}

/* THE CITY PALETTES (JP, 22/09). Four colours per city, read out of that city's
   hero photograph by median-cut quantising and then DEEPENED -- same hue, a
   little more saturation, less light -- until white type clears 7:1. Sampled
   at 60 steps across every transition: the worst frame on any city is 7.11:1.
   Ordered so each step moves far enough to be seen (channel distance 79-190).
   Four stops over the shared 12 seconds is 3s a colour. */
@keyframes city-barcelona {           /* roofs, park, sandstone, shadow */
  0%,100% { background-color: #7A3522; }
  25%     { background-color: #2F4A3A; }
  50%     { background-color: #724E3B; }
  75%     { background-color: #1F2A33; }
}
@keyframes city-caracas {             /* el Ávila, the park's shade, cloud, the lawn */
  0%,100% { background-color: #2E5192; }
  25%     { background-color: #16280F; }
  50%     { background-color: #4A4F90; }
  75%     { background-color: #335E17; }
}
@keyframes city-madrid {              /* sky, stone, gold, slate */
  0%,100% { background-color: #295982; }
  25%     { background-color: #5C564E; }
  50%     { background-color: #7A4E22; }
  75%     { background-color: #2F4052; }
}
@keyframes city-miami {               /* dusk, sunset, mauve, night */
  0%,100% { background-color: #404D8C; }
  25%     { background-color: #8A4520; }
  50%     { background-color: #6F4C66; }
  75%     { background-color: #203467; }
}
@keyframes city-panama {              /* sea, palms, deep water, cloud */
  0%,100% { background-color: #0E5985; }
  25%     { background-color: #285C2C; }
  50%     { background-color: #0E3F4F; }
  75%     { background-color: #49585F; }
}

/* THE CITY HEAD is only a name and a line, so it takes less height than a band
   that carries a hang. */
.city-head { padding-block: clamp(2rem, 3.5vw, 3rem); }
.city-head .group-head { margin-bottom: 0; padding-bottom: 0; border-bottom: 0; }
.city-pdf { margin: 1.5rem 0 0; }
/* THE STATEMENT NOW FOLLOWS THE RECORD (Nico, 01/10), two paper bands in a row,
   so a rule and its own top padding keep them two sections, as on .city-more. */
.band.band--paper.band--after-record { border-top: 1px solid var(--rule); padding-top: clamp(3rem, 5.3vw, 4.5rem); }

/* THE OTHER CITIES, AS PICTURES. A rule and its own top padding, because two
   paper bands in a row otherwise lose the space between them. */
.band.band--paper.city-more { border-top: 1px solid var(--rule); padding-top: clamp(3rem, 5.3vw, 4.5rem); }
.city-cards {
  list-style: none; margin: 1.25rem 0 2.5rem; padding: 0;
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1.25rem;
}
@media (max-width: 48rem) { .city-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; }}
.city-card { display: block; color: inherit; text-decoration: none; }
.city-card img {
  display: block; width: 100%; aspect-ratio: 3 / 2; height: auto;
  object-fit: cover; object-position: center;
  transition: opacity .3s ease;
}
.city-card:hover img, .city-card:focus-visible img { opacity: .85; }
.city-card-name {
  display: block; padding-block: .75rem .25rem;
  text-transform: uppercase; letter-spacing: .08em; font-size: .9rem;
}
/* A PHOTOGRAPH UNDER A LICENCE THAT ASKS TO BE NAMED says so where it is used. */
.city-credit { margin: 2.5rem 0 0; font-size: .75rem; color: var(--ink-soft); }
.city-credit a { color: inherit; }
.city-card:hover .city-card-name, .city-card:focus-visible .city-card-name { text-decoration: underline; text-underline-offset: .3em; }



/* THREE GROUNDS, NOT FOUR -- THE BLUE IS OUT (JP, 17/09). It was the loudest
   and the most saturated of the five page colours, and as the first stop it was
   also where the cycle sat whenever it was not mid-turn, so a reader met the
   blue and inferred the rest. Green, purple and orange are the three that read
   as one family; the blue read as a brand colour arriving on top of them.

   THE FLOOR DOES NOT MOVE. Measured across 201 samples of each transition, the
   worst frame of the three-colour cycle is identical to the four-colour one --
   7.01:1 white, 4.61:1 soft tier, both at the orange itself. The blue sat at
   7.30:1 and was never the constraint, so removing it costs nothing and the
   tier values below stand unchanged.

   The blue is NOT retired from the site: `index` still takes it as its static
   footer ground under reduced motion, and it is still the home page's colour in
   `.foot--index`. It is out of the TRAVELLING set only. */
/* JP'S FIVE, AT THE DEPTH WHITE TYPE NEEDS (JP, 17/09 -- replaces the set
   sampled from Tumulto earlier the same day).

   HE GAVE FIVE: #03092c #441307 #e3c725 #d74512 #307160. Two carry white type
   as they are and ship untouched -- the navy at 19.46:1 and the dark red at
   15.65:1. THREE DO NOT, and the yellow is not a near miss: white on #e3c725
   measures 1.69:1, which is type nobody can read. #d74512 is 4.42:1 and #307160
   is 5.74:1, both under the 7.01:1 this site already holds everywhere else.

   So those three keep their HUE and their SATURATION and come down in lightness
   only: #e3c725 -> #605510, #d74512 -> #99310D, #307160 -> #285D4F. His colours,
   deep enough to read on. This is a readability decision and not a taste one,
   and it is one line to reverse if he wants the literal five.

   IN HUE ORDER RATHER THAN THE ORDER GIVEN, so the cycle travels the short way
   round the wheel -- 12deg, 16deg, 51deg, 164deg, 231deg. The listed order goes
   yellow, then orange, then back out past both, which reads as a stumble rather
   than as a turn.

   THE STOPS ARE NOT THE TEST. A cross-fade spends nearly all its time between
   two colours: on the site's own cycle the worst frame is the orange STOP at
   7.01:1. Sampled 201 frames of each of the five transitions here -- worst
   anywhere is 7.46:1 white and 4.91:1 on the soft tier, against the 7.01 and
   4.61 that are live. Five stops over the same 12 seconds is 2.4s a colour. */
@keyframes obra-cycle {
  0%   { background-color: #441307; }  /* his #441307, exactly            */
  20%  { background-color: #99310D; }  /* his #d74512, deepened           */
  40%  { background-color: #605510; }  /* his #e3c725, deepened           */
  60%  { background-color: #285D4F; }  /* his #307160, deepened           */
  80%  { background-color: #03092C; }  /* his #03092c, exactly            */
  100% { background-color: #441307; }
}

@keyframes band-cycle {
  0%     { background-color: #0E3B2E; }  /* obra     verde oscuro */
  33.33% { background-color: #4A1E6E; }  /* artista  morado       */
  66.67% { background-color: #A23207; }  /* encargos naranja      */
  100%   { background-color: #0E3B2E; }
}

/* THE SCROLL TIMELINE IS GONE -- EVERYTHING IS ON THE CLOCK (JP, 17/09).
   A band used to turn as the reader scrolled past it while the footer turned on
   a 12-second timer, and the argument for the split was that a reader is moving
   at one and stationary at the other. In practice it made the SAME effect behave
   two different ways on one page, so the colour read as a reaction to scrolling
   in one place and as a property of the site in the other -- and a reader who
   stopped mid-band simply froze it on a colour nobody chose.

   One driver now: `animation: band-cycle 12s linear infinite`, declared once
   above and shared by every colour band and every footer. Four seconds a colour.
   Nothing here overrides it. */

/* The statement sits directly under the hero, so it opens tighter than a band
   that follows type. */
/* The compact band: 64px at 1363, 40px at 390, and symmetric. It used to open
   on 82px and close on 109px, which made the page's opening argument sit in a
   deeper hole than any section below it. */
.center { text-align: center; }
.center .display,
.center .h2 { margin-inline: auto; }

/* --- FULL BLEED ----------------------------------------------------------
   OUTSIDE the wrapper, never escaping it with a negative margin: the margin
   trick measured 4vw past the viewport on both sides at every width. */
.bleed { width: 100%; margin: 0; }
.bleed img { display: block; width: 100%; height: auto; }

/* --- SECTION HEADS -------------------------------------------------------
   Label left, heading right, one rule under both. The number is information —
   it says how far through the page you are — so it is set as data, not as
   decoration, and it shares a baseline with the heading it names. */
.rule-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem 2rem;
  padding-bottom: clamp(1.25rem, 2.5vw, 2rem);
  border-bottom: 1px solid var(--rule);
  margin-bottom: clamp(2.5rem, 5vw, 4.5rem);
}
.rule-head .h2 { margin: 0; }
/* CENTRED, AND THE COUNT STAYS WITH ITS LABEL (15/09). `space-between` threw
   the label to the far left of the band and the number to the far right, with
   a metre of nothing between them, while every other heading on the site was
   centred. They are one caption; they sit together, on the same axis as the
   rest. */
.rule-head--split {
  border-bottom: 0; padding-bottom: 0;
  justify-content: center;
  gap: 1rem;
  margin-bottom: clamp(2rem, 4vw, 3.5rem);
}

/* The earlier pass numbered sections with a generated ::before. The render puts
   the number in the eyebrow itself, where it can sit beside the heading rather
   than stacked above it, so the generated one comes off. */
.section-head .h2::before{ content: none; }



/* --- THE HANG ------------------------------------------------------------
   Works stand on a SHARED BASELINE, ragged at the top, which is how a wall is
   actually hung and the only way a row closes without cropping anything. The
   caption sits under the baseline, so all three captions align even though no
   two works are the same height.

   The width of each work comes from build.py `wf`, solved from its real square
   metreage and its photograph's aspect. Three works to a row, so a work never
   has to carry more than a third of the column and the 800px files hold. */
.hang {
  display: grid;
  align-items: end;
  /* Row 64px, column unchanged. The row value is the ONE place vertical space
     between works is decided: the card no longer pads, and the gap between two
     separate row containers below matches it, so a wrapped row and a new row
     are the same distance apart instead of 80px plus two lots of padding. */
  row-gap: 4rem;
  column-gap: clamp(1.5rem, 3vw, 2.5rem);
  list-style: none;
  margin: 0 0 4rem;
  padding: 0;
}
.hang:last-of-type { margin-bottom: 0; }

.work { display: flex; flex-direction: column; justify-content: flex-end; }
.work a { text-decoration: none; color: inherit; display: block; }

/* The plate is only an alignment device: the image sits on its bottom edge and
   grows upward. No fixed ratio, so nothing is ever cropped to fit. */
.plate { display: flex; align-items: flex-end; }
.plate img {
  display: block;
  width: calc(var(--w, 1) * 100%);
  height: auto;
  max-width: 100%;
  transition: transform 1.1s var(--ease);
}

.work .cap, .room .cap, .studio-shot .cap {
  margin-top: 1rem;
  padding-top: .75rem;
  border-top: 1px solid var(--rule);
}
/* THE HELD LINE. An empty `.cap-meta` collapses to nothing -- an empty block
   has no line box -- so it is given the meta line's own height and nothing
   else. It carries no text and `aria-hidden`, so it is a spacer to the eye and
   does not exist to a screen reader. */
.cap-meta--hold { min-height: calc(var(--hold-lines, 1) * 1lh); }

/* THE BASELINE, HELD BY THE GRID INSTEAD OF BY COUNTING LINES (23/09).
   Everything above reserves caption lines by predicting how many there will
   be, and a prediction breaks the moment a line WRAPS: the Spanish captions
   are longer ("Impresión 3D sobre acrílico", "Actualmente en Caracas"), so at
   1024px eight rows of es/obra.html stood 21px out -- one line -- while every
   English row was level. Measured, not guessed.

   Subgrid removes the prediction. Each work spans two rows of its hang and
   shares them with its neighbours: row one is as tall as the tallest plate and
   every photograph sits on its floor; row two is as tall as the longest
   caption and every rule starts at its top. The images line up whatever the
   captions say, in either language. Browsers without subgrid keep the old
   flex behaviour, which is where the held lines still earn their place. */
@supports (grid-template-rows: subgrid) {
  .hang .work, .hang .work > a {
    display: grid;
    grid-row: span 2;
    grid-template-rows: subgrid;
    row-gap: 0;
  }
  .hang .work > a > .plate { align-self: stretch; }
  .hang .work > a > .cap { align-self: start; }
}

/* --- SPLIT SECTIONS ------------------------------------------------------
   A vertical rule, name on one side, facts on the other. The rule is the whole
   device; it does the work a box would otherwise do, and costs nothing. */
.split-rule {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 5rem);
}
/* GAP ZERO, AND THE MARGINS OWN THE SPACING (15/09). This carried a 48px flex
   gap on top of the eyebrow's own 12px bottom margin, which is why the label
   sat 60px above his name here and 12px above every other heading on the site.
   The column still pushes `.eyebrow--foot` to the bottom with `margin: auto`,
   which needs no gap to work. */
.split-rule-name {
  display: flex;
  flex-direction: column;
  gap: 0;
}
/* The body column's gap is the body-to-action relationship, and the brief
   gives that one 24px on both desktop and mobile. It was 40px at this width. */
.split-rule-body {
  border-left: 1px solid var(--rule);
  padding-left: clamp(2rem, 5vw, 5rem);
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}
.split-rule-body .prose p { max-width: 34rem; }
.eyebrow--foot { margin: auto 0 0; }

/* His name is the one place on the page a heading may run to two lines on
   purpose, so it is allowed to break where it likes. */
.h2--name { text-wrap: initial; }

/* THE HOME PAGE'S CLOSE IS `.split-rule` AGAIN (JP, 16/09). The centred
   one-column variant that replaced it on 15/09 is gone with its markup; only
   the portrait below is specific to this section.

   HIS PHOTOGRAPH, IN THE NAME COLUMN. `margin-top: auto` is deliberate and it
   is what `.eyebrow--foot` used to do alone: the column is a flex stack, so the
   picture is pushed to the bottom and its top edge lands wherever his name
   ends. It never stretches -- a portrait scaled to match a column of text is a
   portrait cropped by a paragraph length, which changes with the language. */
/* IT FILLS THE NAME COLUMN (JP, 16/09). Capped at 22rem it was already flush
   with the left edge of his name -- measured at nine widths, all of them 0px
   off -- but it stopped 183px short of the right, and against a 535px column of
   type that reads as a picture pushed inboard. Filling the column puts BOTH
   edges on the text, which is what "aligned" is being asked for here. */
.close-portrait {
  margin: var(--gap-group) 0 0;
  max-width: 100%;
}
.close-portrait img {
  width: 100%;
  height: auto;
  display: block;
}
/* The rule pushes the location line to the bottom of the column when there is
   no portrait; with one, the portrait is the last thing and takes that job. */
.split-rule-name:has(.close-portrait) .eyebrow--foot { margin: 0; }

/* THE TWO-PORTRAIT SPLIT (JP, 02/10). The studio portrait is the floor; the
   portrait at his wall sits on top, cut by `--x` from the left, so moving the
   line uncovers one room and covers the other. Everything is achromatic, like
   the rest of the interface: a white line and a white knob with a dark ring,
   readable on the near-black studio wall and on the white mural alike, because
   the ring carries the edge on white and the fill carries it on black. */
.reveal-stage {
  position: relative;
  overflow: hidden;
  cursor: ew-resize;
  touch-action: pan-y;
  user-select: none;
  -webkit-user-select: none;
}
.reveal-stage img { -webkit-user-drag: none; pointer-events: none; }
.reveal .reveal-top {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  clip-path: inset(0 0 0 var(--x));
}
.reveal-line {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--x);
  width: 2px;
  margin-left: -1px;
  background: #fff;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .35);
  pointer-events: none;
}
.reveal-knob {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 44px;
  height: 44px;
  margin: -22px 0 0 -22px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 0 2px #141414, 0 4px 14px rgba(0, 0, 0, .35);
}
/* Two chevrons, pointing out: the knob says "this goes both ways" without a word. */
.reveal-knob::before,
.reveal-knob::after {
  content: "";
  position: absolute;
  top: 50%;
  width: 8px;
  height: 8px;
  margin-top: -4px;
  border: solid #141414;
  border-width: 0 0 2px 2px;
}
.reveal-knob::before { left: 11px; transform: rotate(45deg); }
.reveal-knob::after { right: 11px; transform: rotate(-135deg); }
.reveal.is-gliding .reveal-top { transition: clip-path 1s cubic-bezier(.65, 0, .35, 1); }
.reveal.is-gliding .reveal-line { transition: left 1s cubic-bezier(.65, 0, .35, 1); }
/* The range is the keyboard's and the screen reader's way in. It is invisible
   but focusable, and focus draws a ring on the photograph, which is what moves. */
.reveal-range {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  overflow: hidden;
}
.reveal { position: relative; }
.reveal:has(.reveal-range:focus-visible) .reveal-stage { outline: 2px solid #141414; outline-offset: 3px; }


/* THE BODY SETS ON THE MIDDLE OF THE COLUMN BESIDE IT (JP, 16/09). The name
   column is taller than the text, because it carries a photograph; top-aligned,
   the three lines of type ended a picture-height above the bottom of the band
   and the section read as two columns of different lengths rather than one
   row. Centring is scoped to `--close`: `.split-rule` is used elsewhere on the
   site where the two columns are the same height and centring would do nothing
   but risk a change nobody asked for. */
.split-rule--close .split-rule-body { justify-content: center; }
/* THE SAME HEADING, NOW AT THE TOP OF ITS BAND (16/09). `.h2--close` carried a
   large top margin because it was the second half of a section and needed
   separating from the first; opening the band it needs none -- the band's own
   padding is the space above it. */
.h2--open { margin-top: 0; }

.display--record {
  font-family: var(--sans);
  font-size: var(--t-lede);
  font-weight: 400;
  line-height: 1.5;
  letter-spacing: -.01em;
  color: var(--ink-soft);
  margin: 0;
  text-wrap: balance;
}
/* THE WRAPPER, NOT ONLY THE PARAGRAPH. `.prose` is 34rem wide and the
   paragraph inside it had `margin-inline: auto` -- which centres a paragraph
   inside a 34rem box that was itself flush against the left of a 1139px band.
   The text was centred; the column it sat in was 594px off-centre, in both
   languages, which is what reads as the section being crooked. */
.prose--center { margin-inline: auto; }
.prose--center p { margin-inline: auto; max-width: 34rem; }
/* THE CENTRED PROSE IS THE HEADER GROUP'S CONTENT, so the gap above it is the
   site's group-to-content token, not a private clamp. It carried its own
   20px from before the type system existed, which read as a heading-to-
   subtitle gap under a heading that has no subtitle. Only the home page's
   investigation band matches this selector, in both languages. (15/09) */
.center .prose { margin-top: var(--gap-group); }

.section-foot { margin: clamp(1.5rem, 3vw, 2.5rem) 0 0; }
/* SUBTITLE TO ACTION IS 24px ON BOTH WIDTHS, and it is a RELATIONSHIP, so it
   is declared once here rather than as a third per-band override. `.band--
   statement` and the hero panel each carry their own copy of this value
   because the generic 40px reached them first; the commissions close was
   the third context to need it, which is the point at which a private
   override becomes a rule. Higher specificity than `.section-foot`, so it
   wins wherever the two actually meet. (15/09) */
.group-sub + .section-foot { margin-top: 1.5rem; }
@media (max-width: 34rem) {
  .hang {  gap: clamp(2rem, 6vw, 3rem); }
  .plate img { width: 100%; }
  .split-rule { grid-template-columns: minmax(0, 1fr); gap: 2rem; }
  .split-rule-body { border-left: 0; border-top: 1px solid var(--rule); padding-left: 0; padding-top: 2rem; }
  .eyebrow--foot { margin-top: 0; }}



/* --- EDITORIAL HOME, second pass ------------------------------------------ */

/* THE STATEMENT BREAKS ONTO TWO LINES ON PURPOSE. One line puts the roman and
   the italic on the same rule and the lean stops reading as a shift in voice;
   two lines give "my own way" a line of its own, which is what the render
   draws and what the sentence actually does. */
/* RESTORED 15/09. Deleted when the second-pass review folded the headline into
   an ivory panel beside the painting; JP reversed that the same day, so the
   band that carries the line is back and needs its own quieter padding again --
   it is a sentence under a picture, not a chapter. */
.band--statement { padding-block: clamp(2.5rem, 4.7vw, 4rem); }
/* An action under the sentence is the brief's 24px, the same on both widths.
   Inside a statement band it was picking up `.section-foot`'s generic 40px. */
.band--statement .section-foot { margin-top: 1.5rem; }
/* 15ch WAS AN ENGLISH MEASURE (JP, 16/09). At 72px it comes to 497px, which
   holds "A work that begins with the space." on two lines and pushes "Una obra
   que comienza en el espacio." onto three -- the same heading, set differently
   in the two languages, because Spanish runs longer for the same sentence and
   nothing here was reading in Spanish when the number was chosen.

   19ch is the widest that still keeps every one of these headings on TWO lines
   rather than collapsing a short one onto one: measured across both languages,
   the English encargos heading becomes a single line at about 800px, so the
   measure has to stay well under that. Character units, not pixels, so it
   tracks the type size on a phone as it always did. */
.band--statement .display { max-width: 19ch; }
.band--statement .display em { display: block; }

/* THREE COUNTED LINES, ONE FACT EACH. The record band is the only place on the
   page where numbers carry the argument alone, and three sentences wrapped
   into two lines read as a paragraph rather than as a list. */

/* THE FOOT IS THE LAST BAND. It used to take the ink like the others, so the
   page ended on his name rather than on furniture.

   SINCE 2026-09-14 IT TAKES ONE COLOUR PER PAGE (Nico's ask, JP confirmed), and
   ink is only the fallback for a page with no colour assigned. This block is
   where the footer colour actually broke: it sits ~480 lines BELOW the
   `.foot--` palette and set `background: var(--ink)` outright, so every footer
   painted ink and the five colours never appeared on screen once. The palette
   was correct, the class was on the element, and the later declaration won.
   `--foot-bg` now carries ink as its own fallback instead, so there is one
   place that decides and nothing downstream to override it. */
.foot {
  background: var(--foot-bg, var(--ink));
  color: var(--foot-fg, var(--paper));
  --ink-soft: #A8A296;
  --rule: #34322D;
  border-top: 0;
  /* SMALLER (JP, 15/09). It was clamp(3rem, 6vw, 5rem) -- 80px top and bottom at
     1363px, more than a major content section gets, for a colour band holding an
     address, three links and a copyright line. The footer is the quietest thing
     on the site and should take the least room of anything that is not a rule. */
  padding-block: clamp(2rem, 3.5vw, 3rem);
  margin-top: 0;
}

/* --- THE FOOTER MOVES THROUGH THE PALETTE (JP, 16/09) ---------------------
   The same three grounds, on the same keyframes, as the colour band: green,
   purple, orange. Not a second set of colours to keep in step with the first --
   `band-cycle` is re-used exactly as it is, which is why the footer and the
   band can never drift apart, and why dropping the blue moved both at once.

   TIME, NOT SCROLL. The band turns as the reader scrolls past it; a footer is
   the last thing on the page and a reader is usually stationary by the time
   they reach it, so scrolling would leave it frozen on one colour. 12 seconds
   for the full circuit -- four per colour now the blue is out, which is quick
   enough to notice without becoming the thing you watch.

   EVERY FRAME IS WHITE-SAFE, AND THAT IS WHY THESE THREE. Computed across 201
   samples of each transition: the worst point in the whole cycle is 7.01:1
   against white, at the orange itself. The stops ARE the extremes --
   an sRGB interpolation between any two of them is darker than both -- so no
   mid-turn colour can drop below a stop that already passes. The yellow of the
   contact footer is deliberately NOT in this set: it is the one ground on the
   site that needs near-black type, and a cycle that has to change its text
   colour halfway round is a cycle that fails somewhere.

   REDUCED MOTION KEEPS THE PAGE'S OWN COLOUR. The global reduced-motion rule
   turns the animation off, and the footer falls back to `--foot-bg` -- the
   ground that page has always had, contact included, with its own text colour.
   Nothing is lost by asking for calm; the colour simply stops travelling. */
/* ---------------------------------------------- A CYCLE PER PAGE (JP, 21/09)
   Every footer used to run the SAME three grounds, so the one band that was
   supposed to say which page you were on said the same thing on all of them.
   The five per-page colours existed but only a reader who had turned motion
   off ever saw them. Six cycles now, and each one OPENS ON ITS OWN PAGE'S
   COLOUR -- `0%` is the ground that page has always had, so arriving on a page
   shows you its colour and then takes you somewhere.

   THE RULES THESE HAD TO SATISFY, both measured rather than judged:

   1. WHITE AT EVERY FRAME, NOT JUST AT THE STOPS. A 12s cycle spends almost
      all its time BETWEEN the colours someone chose, and sRGB interpolation
      can pass somewhere neither stop warned about. All six were sampled at 60
      steps per transition against white: the worst frame anywhere in the six
      is 7.01:1, at the orange, which is the same floor the single cycle had.

   2. THE MOVEMENT HAS TO BE VISIBLE. Three shades of one hue clears contrast
      easily and reads as nothing happening. Measured as the channel distance
      between consecutive stops: the shipping cycle's smallest step was 153,
      and no cycle here steps less than that. The first draft of this -- each
      page travelling inside its own hue family -- scored 18 on `obra` and was
      thrown away.

   3. NO CYCLE CHANGES ITS TEXT COLOUR HALFWAY ROUND. That rule is why the
      contact yellow was left out of the original set and it is why it is still
      out: it is the one ground that needs near-black. Contact keeps its yellow
      as its reduced-motion ground and travels through dark grounds like the
      rest, which is exactly what it did before.

   `band-cycle` itself is untouched -- `.band--cycle` on the Work page heading
   still uses it, and these are additions beside it rather than an edit to it. */
/* THE ELECTRIC BLUE LEFT HOME, COMMISSIONS AND CONTACT (JP, 24/09). The other
   three footers keep it; he named these three. Re-measured with the same two
   rules: worst frame 7.49 / 7.01 / 7.01:1 against white, smallest step 153 / 153
   / 191. Home loses the orange as well, because ochre-to-orange is a step of 83
   and reads as nothing happening. */
@keyframes foot-index {
  0%,100% { background-color: #724E00; }  /* ocre */
  33.33%  { background-color: #4A1E6E; }
  66.67%  { background-color: #0E3B2E; }
}
@keyframes foot-obra {
  0%,100% { background-color: #0E3B2E; }  /* verde oscuro */
  33.33%  { background-color: #4A1E6E; }
  66.67%  { background-color: #A23207; }
}
/* THE BLUE LEFT THE ARTIST PAGE TOO (JP, 02/10: "i dont like it", asked for
   yellow). A true yellow needs near-black type, which rule 3 forbids, so it is
   the ochre -- the darkest yellow white type reads on, 7.49:1. Orange left with
   it: ochre beside orange is a step of 83 and reads as nothing happening.
   Steps 198 / 165 / 153. */
@keyframes foot-artista {
  0%,100% { background-color: #4A1E6E; }  /* morado */
  33.33%  { background-color: #724E00; }  /* ocre */
  66.67%  { background-color: #0E3B2E; }  /* verde oscuro */
}
@keyframes foot-encargos {
  0%,100% { background-color: #A23207; }  /* naranja */
  33.33%  { background-color: #4A1E6E; }
  66.67%  { background-color: #0E3B2E; }
}
@keyframes foot-contacto {
  0%,100% { background-color: #0B3A45; }  /* verde azulado */
  33.33%  { background-color: #A23207; }
  66.67%  { background-color: #702C91; }  /* violeta */
}
@keyframes foot-ciudad {
  0%,100% { background-color: #7A1230; }  /* burdeos */
  33.33%  { background-color: #0B3A45; }
  66.67%  { background-color: #1536F5; }
}

@media (prefers-reduced-motion: no-preference) {
  .foot {
    /* The shorthand sets the timing for every footer AND names a fallback. The
       per-page names come AFTER it, further down this block, and that order is
       load-bearing: `animation` is a shorthand, so it RESETS `animation-name`,
       and `.foot--index` and `.foot` have identical specificity. Written above
       this rule, the six page cycles were silently overwritten by the fallback
       and all seven page types cycled green-purple-orange exactly as before --
       the CSS was valid, the build passed, and only sampling the rendered
       colour on each page showed it. */
    animation: band-cycle 12s linear infinite;
    /* The cycle never visits a light ground, so the type is white throughout --
       including on `contacto`, whose static yellow needs near-black and whose
       animated state never shows it. `.foot a` and `.foot-small` inherit. */
    color: #FFFFFF;
  }

  /* AFTER the shorthand, never before it -- see the note above. */
  .foot--index              { animation-name: foot-index;    }
  .foot--obra, .foot--obras { animation-name: foot-obra;     }
  .foot--artista            { animation-name: foot-artista;  }
  .foot--encargos           { animation-name: foot-encargos; }
  .foot--contacto           { animation-name: foot-contacto; }
  .foot--ciudad             { animation-name: foot-ciudad;   }}


/* Both inherit, so they follow the ground the footer is actually on. On yellow
   that is near-black; hard-coding paper here made every link on the contacto
   footer white on yellow. */
.foot a { color: inherit; }
.foot .foot-small { color: inherit; }

/* The hang's own captions keep their rule on ink as well as on paper: both are
   redefined by the band, so nothing here needs to know which ground it is on. */

/* --- EDITORIAL HOME, third pass ------------------------------------------- */

/* CONSECUTIVE BANDS OF THE SAME GROUND SHARE ONE GAP. Two paper bands in a row
   each contributed a full pad, so the seam between them opened to roughly
   twice the space of every other seam and read as a missing section. */
.band--paper + .band--paper { padding-top: 0; }
/* The band under the full-bleed hero opens on the COMPACT value, the same one
   `.band--statement` uses: it was 82px, which is neither of the two numbers the
   rest of the page is built from. */
.bleed + .band { padding-top: clamp(2.5rem, 4.7vw, 4rem); }

/* The record lines break at the full stop, not at whatever width the column
   happens to be. */
.display--record { max-width: none; }
.display--record span { display: block; }

/* The document ends on ink, so the ground beyond the last band does too --
   otherwise an over-scroll on a phone, or any viewport taller than the page,
   shows a strip of paper under a dark footer. */
html { background: var(--ink); }
body { background: var(--paper); }

/* THE MONOCHROME WORK CARRIES THE INVESTIGATION BAND. It replaces two
   paragraphs of argument, so it is set at reading size rather than at gallery
   size -- large enough to be looked at, small enough that the band still reads
   as a statement and not as a second hang. */
.aside-work a { display: block; text-decoration: none; color: inherit; }
.aside-work img {
  display: block;
  width: 100%;
  height: auto;
  transition: transform 1.1s var(--ease);
}
.aside-work .cap {
  margin-top: 1rem;
  padding-top: .75rem;
  border-top: 1px solid var(--rule);
}

@media (max-width: 34rem) {
  .aside-work { max-width: 100%; }}



/* --- EDITORIAL HOME, fifth pass ------------------------------------------- */

/* THE HANG CENTRES. Each work sits centred in its own column and its label
   centres under it, so six works of six different widths still read as one
   row rather than as six left edges that happen to share a baseline. */
.work { align-items: center; text-align: center; }
.work a { width: 100%; }
.plate { justify-content: center; }
.work .cap { width: 100%; }

/* The monochrome work on the ink band takes the same treatment: its label is a
   wall label under a hung work, and a hung work is centred under it. */
.aside-work .cap { text-align: center; }

/* HIS OWN WORDS, AND THEY ARE NOW SET LIKE WORDS (second-pass review, 15/09).
   This was serif italic at 26px, the most expressive treatment on the site,
   reserved for an attributed statement. The review's finding is that reserving
   it was not enough: a leaning serif at 26px beside an upright serif at 72px
   and an upright sans at 18px is a third reading treatment, and the quotation
   is read, not announced. It takes the body role now.
   WHAT IT KEEPS is everything that is not typography -- the measure, so it
   still sets as a spoken line rather than a paragraph, the full-strength ink
   that separates it from supporting copy, and its attribution in the markup.
   Meaning survives the treatment coming off; that was the brief's condition. */
.said {
  font-family: var(--sans);
  font-style: normal;
  font-size: var(--t-body);
  line-height: 1.6;
  letter-spacing: -.005em;
  /* NO ABSOLUTE COLOUR. This was `var(--ink)`, which is #0B0B0B, and it worked
     only for as long as the quotation lived on a paper band. The 15/09
     restructure moved the home page's artist section onto ink, and the sentence
     rendered black on black at 1.00:1 -- invisible, and caught by
     contrast-check rather than by reading the rule.
     Inheriting is the fix AND the rule: `.band--ink` already redefines the
     foreground for everything inside it, so a component that inherits is
     correct on both grounds and a component that names a colour is correct on
     one. Full strength is what separates it from supporting copy, and
     inheriting gives it full strength on whichever ground it lands. */
  max-width: 44ch;
  margin: 0;
  text-wrap: balance;
}

/* HIS VOICE (JP, 02/10). The home page's quotation in the display face's italic,
   larger than body and inside curly quotes, so it reads as Nico speaking rather
   than as one more line of the site describing him. The face is the one his name
   is set in, which ties the words to the name above them. */
.said--voice { margin: 1.5rem 0 0; }
.said--voice p {
  margin: 0;
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(1.5rem, 1.1rem + 1.2vw, 2.125rem);
  line-height: 1.25;
  letter-spacing: 0;
  text-wrap: balance;
}

/* --- THREE ACROSS, AS WIDE AS THREE ACROSS CAN GO -------------------------
   THE ARITHMETIC, because it is the whole answer: `.wrap` is 78rem, so at 1440
   the column is about 1120px and each of three works gets a third of it minus
   the gaps -- 351px. There is no slack inside that. The images were already at
   100% of their track, so "make them bigger" and "keep three across" pull
   against each other, and two across was the only route to +56%.

   Three across is back at JP's instruction. The hang now takes a container of
   its own, wider than the reading column and with tighter gaps, which is every
   pixel three columns can have on a 1440 screen: 435px a work, +24%. The text
   above it keeps the narrower measure, because a line of prose 1300px long is
   unreadable and a painting 1300px wide is not. */
.wrap--hang {
  width: 100%;
  padding-inline: clamp(1.25rem, 3vw, 3rem);
}
.wrap--hang .hang {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.5rem, 2.2vw, 2rem) clamp(1.25rem, 1.8vw, 1.5rem);
}

/* --- THE HERO COMES DOWN BY HALF -----------------------------------------
   It was full-bleed: 1440 wide and 878 tall at desktop, which is most of a
   screen before a word is read. Halving the HEIGHT without cropping means
   halving the width, so it stops touching the edges and becomes a plate on
   paper -- 720px and 439px tall, exactly half.

   The painting is still whole. Cropping it to a shorter band would have kept
   the full bleed and is the one thing an artist's site may not do. */

/* The two-column rule above belongs to the version that traded three across for
   size. Three across is back at JP's instruction, so it is overridden here
   rather than deleted, and the wider container is what buys the size instead. */
.hang { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 52rem) { .hang { grid-template-columns: repeat(2, minmax(0, 1fr)); }}


/* TWO ACROSS ON A PHONE TOO (JP, 24/10: one per row ran for ever). */
@media (max-width: 34rem) { .hang { grid-template-columns: repeat(2, minmax(0, 1fr)); }}


.hero-figure img {
  width: 100%;
  height: clamp(340px, 56vh, 620px);
  object-fit: cover;
  object-position: center;
}

/* A HERO THAT IS NOT CROPPED (JP, 16/09). Commissions opens on a photograph of
   a canvas hanging on a wall, and the whole argument of that picture is the
   whole canvas -- a band of fixed height cut a third of its height away and the
   page opened on a painting with its top and bottom missing.

   NO HEIGHT, NO `object-fit`, NO CROP AT ANY WIDTH. The figure is capped by
   WIDTH and the picture keeps its own proportions, so what a reader sees at
   390px is what they see at 1920px. 68rem holds it to about 607px tall on a
   laptop, inside the range the cropped heroes occupy, and it comes down with the
   viewport from there. */
.hero-figure--whole { max-width: min(100%, 68rem); margin-inline: auto; }
.hero-figure--whole img { width: 100%; height: auto; object-fit: fill; }

/* The label sits on the paper under the band, never on the painting: type over
   a painting is a poster, and a poster is a thing being sold. */

@media (max-width: 34rem) {
  .hero-figure img { height: clamp(280px, 46vh, 420px); }
  /* EXCEPT THE ONE THAT IS NOT CROPPED. This phone rule sets a height, and a
     height is a crop -- it took the uncropped commissions hero from 1.79:1 back
     to 1.01:1 and cut the canvas in half again on the one screen where a reader
     is closest to it. `auto` is the whole point of that hero and it has to be
     restated here, because this rule is more specific than the one that set it. */
  .hero-figure--whole img { height: auto; }}



/* HIS FULL STATEMENT, UNDER THE THESIS. `.said` is a left-set line in the home
   page's split column; here it sits centred under a centred display line, so
   it takes the axis of the thing above it. The measure stays his, not the
   prose measure — it is a sentence he said, not body copy. */
/* THE COUNTS ARE THE HEADING HERE. On the home page the record band carries a
   label and a link either side of a rule; on this page the CV underneath is
   the link, so the eyebrow sits directly above the counts and needs the gap a
   rule used to hold open. */
/* THE PAINTING BESIDE THE PROFILE. It takes the home page's plate wholesale --
   no ratio box, no crop, its caption under a hairline -- so the one image on
   this page is hung the way every image in the hang is. */
.split-plate { margin: 0; }
.split-plate a { display: block; text-decoration: none; color: inherit; }
.split-plate .plate { display: flex; align-items: flex-end; }
.split-plate .plate img { display: block; width: 100%; height: auto; transition: transform 1.1s var(--ease); }
.split-plate .cap { margin-top: 1rem; padding-top: .75rem; border-top: 1px solid var(--rule); }
/* Removed 15/09: a fifth private value for label-to-heading, on one element.
   `.eyebrow` owns that gap for the whole site now. */


/* ==========================================================================
   THE INNER PAGES, ON THE HOME PAGE'S GRAMMAR — 2026-09-03.

   Obra, encargos, contacto and every work page were rebuilt out of the bands
   the home page already had, so almost nothing new is needed here. What is
   below exists because three things on those pages have no equivalent on the
   home page: a painting shown whole rather than cropped, a gallery label under
   it, and a list of delivery facts that are sentences rather than counts.
   ========================================================================== */

/* THE WORK, ALONE ON ITS BAND. The old layout put the specification list beside
   the painting from 56rem up, so a table of measurements sat level with the
   canvas's centre and the eye had two things to read at once. The painting now
   has the column to itself and the label sits underneath, which is where a
   gallery puts it. Capped at 68rem: past that a 3000px photograph is being
   shown larger than the wall it hangs on, and the page stops being a page. */
.work-figure--alone {
  margin: 0 auto;
  max-width: min(68rem, 100%);
}
.work-figure--alone img { width: 100%; height: auto; }

/* THE LABEL. Title on the left, facts on the right, divided by the same rule
   the split sections use. It stacks on a phone with the title first, because
   the one thing a reader wants under a painting is its name. */
.work-label {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 3rem);
  margin-top: clamp(2rem, 4vw, 3.5rem);
  padding-top: clamp(1.5rem, 3vw, 2.5rem);
  border-top: 1px solid var(--rule);
  max-width: min(68rem, 100%);
  margin-inline: auto;
}
@media (min-width: 48rem) {
  .work-label { grid-template-columns: minmax(0, 1fr) minmax(18rem, .8fr); }}


.work-label .h2--name { margin: 0; }
.work-label .said { margin-top: 1.25rem; }
.work-label .spec div:first-child { padding-top: 0; }

/* THE HANG WAS THREE ACROSS ON A PHONE, ON EVERY PAGE THAT USES IT.
   `.wrap--hang .hang` is two classes deep and the responsive rules above are
   one, so from the day the wider hang container was added the 52rem and 34rem
   breakpoints stopped applying: at 390px three paintings shared the screen at
   about 110px each, with four-line captions under them. Nothing reported it
   because the page does not overflow -- it just becomes unreadable. Re-stated
   here at the same depth as the rule that was winning.

   A GROUP OF ONE, AND A GROUP OF TWO. The hang is three columns because a wall
   holds three; a single sculpture in the first of three cells reads as two
   photographs that failed to load. The row narrows to what it actually holds,
   and the work keeps its true width inside it rather than growing to fill the
   page. */
.wrap--hang .hang--single { grid-template-columns: minmax(0, 22rem); justify-content: center; }
.wrap--hang .hang--pair { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 60rem; margin-inline: auto; }

@media (max-width: 52rem) {
  .wrap--hang .hang, .wrap--hang .hang--pair { grid-template-columns: repeat(2, minmax(0, 1fr)); }}


/* TWO ACROSS ON A PHONE (JP, 24/10: one to a row ran for ever). The single and
   pair variants are gone with the per-row lists; only the lone-work page keeps one. */
@media (max-width: 34rem) {
  .wrap--hang .hang,
  .wrap--hang .hang--pair { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2rem 1rem; }
  .wrap--hang .hang--single { grid-template-columns: minmax(0, 1fr); }}



/* The work page's own navigation sits under a hang rather than under a page, so
   it does not need the full step above it as well as the hang's bottom margin. */
.band--ink .hang + .work-nav { margin-top: clamp(2rem, 4vw, 3rem); }

/* THE ADDRESS, SET AS TYPE. Long enough at 29 characters that the display size
   has to come down; the rule under it is the same hairline the .go links carry,
   so it still reads as the thing to click. */
.mail-line {
  display: inline-block;
  font-family: var(--serif);
  font-size: var(--t-h3);
  line-height: 1.15;
  letter-spacing: -.015em;
  text-decoration: none;
  border-bottom: 1px solid currentColor;
  padding-bottom: .15em;
  word-break: break-word;
}
.mail-line:hover { opacity: .55; }


/* ==========================================================================
   INTERACTION — 2026-09-03.

   THE THESIS: the hairline is this site's material. Every rule on the page is
   one pixel of --rule: under a caption, between CV years, down the middle of a
   split section. The page's one authored motion is the uncover -- a clip path
   that draws a painting up from its baseline. So every interactive state is the
   same gesture at small scale: a rule that draws itself in from the left.

   WHY NOT WHAT THE REST OF THE WORLD DOES. A colour hover is unavailable by
   rule: every colour on this site comes from inside a frame, and a link that
   turns blue on hover breaks the one promise the interface makes. An opacity
   fade -- what was here before -- is worse than nothing on paper: the text
   simply loses contrast for as long as you are pointing at it, which reads as
   the site going faint rather than as an answer.

   Two states, not one. HOVER is a pointer; FOCUS-VISIBLE is a keyboard, and
   before this pass the site had no focus styling at all -- tabbing through it
   was invisible, which fails 2.4.7 outright and makes the site unusable
   without a mouse.
   ========================================================================== */

/* The drawn rule. On a pseudo-element so it works on inline links, never moves
   layout, and can sit under text that already carries a border. */
.nav a, .nav-cities > summary, .lang, .wordmark, .foot a, .social a, .cv-note a, .mail-line, .go {
  position: relative;
  transition: color .25s var(--ease);
}
.nav a::after, .lang::after, .wordmark::after, .foot a::after, .social a::after,
.mail-line::after, .go::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -.15em;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .42s var(--ease);
}
.nav a:hover::after, .lang:hover::after, .wordmark:hover::after,
.foot a:hover::after, .social a:hover::after, .mail-line:hover::after,
.go:hover::after,
.nav a:focus-visible::after, .lang:focus-visible::after, .wordmark:focus-visible::after,
.foot a:focus-visible::after, .social a:focus-visible::after,
.mail-line:focus-visible::after, .go:focus-visible::after { transform: scaleX(1); }

/* THE PAGE YOU ARE ON KEEPS ITS RULE DRAWN. The navigation used to mark the
   current page by colour alone -- #5A574F against #0B0B0B, a difference a
   reader has to look for and a colour-blind reader may not get at all. */
.nav a[aria-current]::after { transform: scaleX(1); }
.nav a[aria-current] { color: var(--ink); }

/* `.go` and `.mail-line` already carry a static rule, so the drawn one has to
   land ON it rather than beside it: same offset, full ink, drawn over the
   hairline. The underline moves off the descenders either way. */
.go::after { bottom: -1px; }

/* THE HIT AREA IS BIGGER THAN THE TEXT, AND MOVES NOTHING.
   Measured across all 272 pages at 390px and 360px: 2,170 tap targets under
   the 24px AA floor, from four elements that repeat in the shared chrome --
   every `.go` link at 22px tall, the wordmark at 23, the footer email at 22,
   and the link to X at TEN PIXELS WIDE, because its whole label is one letter.

   On a pseudo-element, not on padding. This site's vertical rhythm is tuned to
   the pixel in several places and padding would move all of it; a transparent
   ::before inside the anchor enlarges what a thumb can hit and changes no
   layout at all. `::after` is taken -- it draws the hover rule.

   PLAIN INSETS, AND NO TRANSFORM. The first version centred a 24px box with
   `top: 50%` and `translateY(-50%)`. It looked identical and it measured wrong:
   mobile-check reads the pseudo-element's own top and bottom and cannot see a
   transform, so a 23px link reported a 35px box, every neighbour then read as
   3px away, and 2,168 size failures became 3,264 spacing ones. Two pixels top
   and bottom needs no transform to be true. */
.nav a::before, .lang::before, .wordmark::before, .foot a::before,
.social a::before, .mail-line::before, .go::before {
  content: "";
  position: absolute;
  /* -4px, not -2px, and the 2px came back from the type pass: at the shared
     13px navigation role the label box is 18px, so the old expander landed at
     22px and fell under the 24px AA floor. -4px puts it at 26px. NOT deeper:
     `.social` is a flex row with a 1rem gap, so ±4px still leaves the 8px
     minimum between two wrapped rows, and widening further would close it. */
  inset-block: -4px;
  inset-inline: 0;
}
/* The X widener that used to live here is gone with the X link itself: Nico's
   own list of accounts is Instagram, TikTok, YouTube and email. It existed
   because a single-letter label made a ten-pixel target -- a problem no
   remaining link has. */
.mail-line::after { bottom: -1px; height: 1px; }
.foot a:hover, .social a:hover { text-decoration: none; }

/* A WORK ANSWERS BY RISING, AND ITS LABEL BY DRAWING ITS RULE. The old hover
   moved the painting 0.4% and scaled it 1.2% -- measured on a 435px plate that
   is under two pixels, which reads as nothing happening. A painting on a wall
   does not scale when you approach it, so the lift is the whole move: 8px, on
   the curve everything else uses, with the caption's rule filling in under it. */
/* ONE HOVER FOR EVERY IMAGE ON THE SITE. The paintings rose 8px and the
   photographs did nothing at all, which is the difference a reader reads as
   "these are the real ones and those are filler". Same distance, same curve,
   same focus behaviour for a keyboard. */
.work a .plate img, .split-plate a .plate img, .aside-work a img,
.shot img {
  transition: transform .6s var(--ease);
}
.work a:hover .plate img, .work a:focus-visible .plate img,
.split-plate a:hover .plate img, .aside-work a:hover img,
.shot:hover img, .shot:focus-visible img {
  transform: translateY(-8px);
}

/* THE LINK ITSELF CARRIES NOTHING. It exists to make the photograph openable
   and to give the rise something to hang off; the site's drawn-rule hover is
   for text links, so it is explicitly not inherited here. */
.shot { display: block; text-decoration: none; color: inherit; }
.shot::after { content: none; }
/* EVERY PICTURE'S CAPTION CARRIES THE SAME RULE (JP, 16/09). This was keyed on
   `.work`, so the paintings got a hairline that drew itself left to right when
   the pointer arrived and the room and studio photographs got nothing -- the
   same "these are the real ones and those are filler" split the 8px rise was
   fixed for on 15/09, one layer down. `.shot .cap` is the photographs' card now
   that the caption lives inside the link. */
.work .cap, .room .cap, .studio-shot .cap { position: relative; }
.work .cap::after, .room .cap::after, .studio-shot .cap::after {
  content: "";
  position: absolute;
  left: 0; right: 0; top: -1px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .5s var(--ease);
}
.work a:hover .cap::after, .work a:focus-visible .cap::after,
/* THE SIBLING COMBINATOR IS THE POINT. The caption is the link's NEXT sibling,
   not its child, so the photograph keeps its own box and its own accessible
   name -- see `_parts.html` for what happened when it was a child. */
.shot:hover + .cap::after, .shot:focus-visible + .cap::after { transform: scaleX(1); }

/* THE WORK NAVIGATION MOVES THE WAY IT IS POINTING. Previous steps left, next
   steps right: the only two links on the site whose direction is their meaning,
   so the acknowledgement carries it. */
/* Display is NOT set here. It was `inline-block`, which sat after the layout
   rule above and quietly cancelled the flex row the thumbnail needs -- the
   later declaration wins, and the thumbnail would have stacked. */
.work-nav-side { transition: transform .35s var(--ease); }
.work-nav-side:hover, .work-nav-side:focus-visible { transform: translateX(-.4rem); }
.work-nav-next:hover, .work-nav-next:focus-visible { transform: translateX(.4rem); }

/* A CV ROW LIGHTS ITS OWN RULE. The record is the one part of this site built
   to be scanned line by line, and forty rows of identical hairline give the eye
   nothing to hold its place with. */
.cv-row { transition: border-color .3s var(--ease); }
.cv-row:hover { border-bottom-color: var(--ink); }

/* KEYBOARD FOCUS, WHICH DID NOT EXIST HERE.
   Drawn in ink on paper and in paper on ink, so it survives the dark bands, and
   offset far enough to clear a painting's own edge rather than sitting on it. */
:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
  border-radius: 1px;
}
.band--ink :focus-visible, .foot :focus-visible { outline-color: var(--paper); }
.work a:focus-visible, .split-plate a:focus-visible, .aside-work a:focus-visible,
.shot:focus-visible {
  outline-offset: 6px;
}

/* The skip link is the first thing a keyboard reader meets. It was a bare box
   at the top-left corner; it now arrives on the page like a control. */
.skip:focus {
  left: 0;
  outline: 2px solid var(--paper);
  outline-offset: -6px;
}

/* TOUCH HAS NO HOVER. Every state above answers to :active as well, so a tap on
   a phone acknowledges itself instead of jumping straight to the next page. */
@media (hover: none) {
  .work a:active .plate img { transform: translateY(-4px); }
  .go:active::after, .mail-line:active::after, .nav a:active::after { transform: scaleX(1); }}



/* ==========================================================================
   PHOTOGRAPHS THAT ARE NOT PAINTINGS — 2026-09-03.

   A room with his work in it, and the painter at work. Both are documents
   rather than works, and the difference has to be visible or the page starts
   offering a photograph of a living room as if it were for sale.

   So they are the one place on this site where an image sits INSIDE a frame
   with a ratio: the hang exists to show a painting at its own shape and true
   size, and a snapshot of a wall borrowing that treatment would read as one
   more piece in the catalogue.
   ========================================================================== */

/* THEY HANG NOW, THEY DO NOT TILE (JP, 16/09). Every photograph used to be
   stretched to the full width of its cell, so a row aligned along its TOP edge
   and ended wherever each aspect ratio happened to leave it -- a portrait shot
   ran half a screen deeper than the landscape beside it, and the eye read that
   as "this one is more important". Nobody could name it; it is simply the
   opposite rule to the one `obra` runs on.

   This is `.hang--even`, the treatment `obra` gives a work whose real size
   nobody has stated: a shared bottom baseline, each image at its own shape and
   never cropped, and a ceiling on the height so no single frame can dominate a
   row. A photograph has no square metreage either, so it is the same problem
   and it takes the same answer. */
.rooms, .studio {
  display: grid;
  align-items: end;
  gap: clamp(1.5rem, 3vw, 2.5rem) clamp(1.25rem, 2vw, 2rem);
  list-style: none;
  margin: 0;
  padding: 0;
  grid-template-columns: minmax(0, 1fr);
}
.room, .studio-shot { display: flex; flex-direction: column; justify-content: flex-end; }
/* TWO ACROSS, NOT THREE (JP, 16/09 -- reverses the three-across of the same
   day). Three columns plus a height ceiling made every photograph land at the
   SAME height, and a row of identical rectangles is what he saw and called
   "extremely squared". The hang on `obra` looks better for one reason: no two
   paintings are the same size, so the row has a shape.

   Two columns is what gives these that back. The picture fills the column, so
   its height is its OWN proportion -- a 16:9 room lands near 315px, a 4:3 near
   420px, a portrait hits the ceiling -- and `align-items: end` still stands
   them all on one line. Bigger, and no longer uniform. */
@media (min-width: 40rem) {
  .rooms, .studio { grid-template-columns: repeat(2, minmax(0, 1fr)); }}



/* NEVER CROPPED. A photograph of a room is a document of what happened in it,
   so it keeps its own proportions -- which is now simply what it does, with no
   cell to fit and no ground to sit on.

   THE CEILING IS THE SAME NUMBER `obra` USES, deliberately: the two pages are
   meant to read at one scale, and two different caps would be the difference
   JP could see and could not name. */
.room .shot, .studio-shot .shot { display: block; }
/* CENTRED, AND THE CAPTION WITH IT (JP, 16/09, asked twice). The first reading
   of "centred with them" was "aligned with them", so these went left like the
   hang on `obra` -- but he means the axis, not the edge. At two columns a
   landscape photograph fills its cell and nothing moves; it is the one tall
   portrait, stopped by the ceiling, that this decides, and it now sits on the
   column's centre with its words under the middle of it. */
.frame--room, .frame--studio { display: flex; align-items: flex-end; justify-content: center; }
/* THE HANG'S OWN CEILING, THE SAME NUMBER (JP, 16/09): "use even the same
   typography and everything. Same alignments, same measurements." So this is
   `min(52vh, 30rem)`, read off `.plate img` on `obra`, not a second number
   invented for photographs.

   IT ONLY BINDS ON A PORTRAIT. `width: auto` with both maxes set is an
   aspect-preserving fit: a landscape photograph is stopped by the column and
   never reaches this, so the ceiling does not flatten the row -- it only stops
   the one tall shot that would otherwise run 840px in a two-column layout. */
.frame--room img, .frame--studio img {
  width: auto;
  max-width: 100%;
  max-height: min(52vh, 30rem);
  height: auto;
  margin-inline: auto;
}
/* A CAPTION IS TWO LINES OF ROOM WHETHER IT USES THEM OR NOT. Every one of
   these photographs carries a caption from 16/09, and at a 252px column some of
   them wrap and some do not -- which would put the row's baseline back exactly
   where `obra`'s was before the held meta line fixed it. Reserving the second
   line costs one blank line under the short ones and keeps every image in a row
   standing on the same edge. `baseline-check.py` is what catches it if this
   number ever stops being enough. */
/* THE SPACE ABOVE IS `.cap`'S NOW -- this margin would come on top of it. The
   two reserved lines stay: at a 252px column some captions wrap and some do
   not, and an uneven caption puts the row's baseline back where `obra`'s was
   before the held meta line fixed it. `baseline-check.py` catches it if two
   lines ever stop being enough. */
.room .cap-meta, .studio-shot .cap-meta { margin-top: 0; min-height: 2lh; text-align: center; }

/* AN EVEN HANG, FOR WORKS WITH NO MEASUREMENTS. The hang's whole argument is
   that a bigger painting is bigger on screen, which needs a number nobody has
   given yet for these. Equal widths and a ceiling on the height is the honest
   placeholder: it says "these are works", not "these are this size". */
.wrap--hang .hang--even .plate { justify-content: center; }
.wrap--hang .hang--even .plate img {
  width: auto;
  max-width: 100%;
  max-height: min(52vh, 30rem);
  margin-inline: auto;
}


/* --- GROUP HEADS AND THE FOLD CONTROL ON THE WORK PAGE -------------------
   A group opens the way every other section on the site opens: heading, then
   one line under it. `.h2` and `.said` are reused rather than re-specified, so
   the scale gains nothing new and the heads stay in step with the rest of the
   page when that scale moves.

   COLOUR IS INHERITED, NOT SET. `.h2` never declares one, and `.said` is
   overridden to currentColor here -- it hardcodes `var(--ink)`, which is not
   redefined on an ink band and would have printed near-black on near-black. */
.group-head {
  text-align: center;
  margin-bottom: clamp(2.5rem, 6vw, 4.5rem);
  /* More air above than below is wrong for a heading INSIDE a band, which
     already carries its own padding: the band gives the space above, the head
     gives the space down to the work it introduces. */
}
.group-head .h2 { margin: 0; text-wrap: balance; }
.group-head .said {
  color: currentColor;
  margin: clamp(.75rem, 2vw, 1.25rem) auto 0;
  max-width: 34ch;          /* a single line of lede, never a paragraph */
  opacity: .78;             /* recedes from the heading without a second colour */
}

/* A GROUP HEAD ALONE IN A BAND CARRIES NEITHER THE RULE NOR THE GAP (17/09).
   Both were correct while the head sat at the top of the hang: the rule cut it
   from the work below, and the bottom margin was the distance down to the first
   plate. `In colour` now takes a statement band of its own, so there is nothing
   under either of them -- the margin became a strip of moving colour with no
   content in it, and the border a hairline across an empty band at 1.89:1.

   The home page's statement band, which this one is built to match, has no rule
   under its heading for the same reason: nothing follows it inside the band. */
.band--statement .group-head,
.band--statement > .wrap > .section-head:last-child {
  margin-bottom: 0;
  padding-bottom: 0;
  border-bottom: 0;
}

/* The fold. Each group shows its first row and holds the rest behind a native
   <details>: no script, every plate still in the DOM, and a page that ran
   42,000px on a phone comes down to a readable length. */
.more-works { margin-top: clamp(2rem, 5vw, 3.5rem); }
.more-works > summary {
  list-style: none;
  cursor: pointer;
  display: block;
  width: max-content;
  max-width: 100%;
  margin-inline: auto;
  padding: clamp(.9rem, 2.2vw, 1.1rem) clamp(1.75rem, 5vw, 2.75rem);
  border: 1px solid currentColor;
  font: 500 var(--t-nav)/1.4 var(--sans);
  letter-spacing: .06em;
  text-transform: uppercase;
  text-align: center;
  transition: background-color .25s var(--ease), color .25s var(--ease);
}
.more-works > summary::-webkit-details-marker { display: none; }
/* THE INVERSION IS THE AFFORDANCE. Ground and figure swap on hover, which is
   the one interaction on this site that has to be unmistakable -- everything
   behind it is unreachable if the reader does not press it. */
.band--paper .more-works > summary:hover,
.band--paper .more-works > summary:focus-visible { background: var(--ink); color: var(--paper); }
.band--ink .more-works > summary:hover,
.band--ink .more-works > summary:focus-visible { background: var(--paper); color: var(--ink); }
.more-works[open] > summary { margin-bottom: clamp(2rem, 5vw, 3.5rem); }
/* THESE THREE MUST SAY `> summary`, NEVER A BARE DESCENDANT. The control is
   RECURSIVE -- every `details` holds the next nine works AND, inside itself, the
   control for the nine after that -- so a descendant rule written on the OPEN
   outer one reaches into the SHUT inner one and relabels it too. Opening the
   first block therefore turned every control below it into "Show less", with
   works still hidden behind them: pressing a button that said show less was the
   only way to see more. Nico reported it; found 22/09. */
.more-works > summary .more-works-shut { display: none; }
.more-works[open] > summary .more-works-open { display: none; }
.more-works[open] > summary .more-works-shut { display: inline; }
.more-works .hang:last-of-type { margin-bottom: 0; }


/* --- STICKY MASTHEAD ------------------------------------------------------
   The bar follows the reader instead of scrolling away with the first work.
   On a 131-piece site the navigation was reachable only from the top of the
   page, which on a long gallery means scrolling back through the whole body
   of work to leave it.

   It starts INVISIBLE and materialises on scroll. At rest the page should read
   as one uninterrupted sheet of paper; a permanent bar puts a lid on it. Past
   the first 24px there is content sliding underneath, and the bar has to hold
   its own ground or the wordmark sits on top of a painting.

   NO JAVASCRIPT REQUIRED. The attribute is absent until the script sets it, and
   `:not([data-scrolled="false"])` treats absent as "show the background" — so
   with the script blocked the bar is simply always solid, which is the safe
   state, never the illegible one. The script only buys the transparent rest
   state, and losing it costs an effect, never a reader. */

.masthead-bar {
  position: sticky;
  top: 0;
  z-index: 100;
  background: transparent;
  transition: background var(--reveal) var(--ease),
              box-shadow var(--reveal) var(--ease);
}
/* NO transition on the height. The bar carries a backdrop-filter, which lives on
   its own GPU layer, and animating the box that layer occupies makes the browser
   rasterise the blur at one size and stretch it to the next — which reads as dirty,
   smeared type for the length of the transition. The background and the shadow
   still fade, and neither of those touches layout. */
.masthead-bar .masthead { transition: none; }

.masthead-bar:not([data-scrolled="false"]) {
  /* --paper at 88%: the works show through as movement, not as detail. */
  background: rgba(244, 241, 234, .88);
  -webkit-backdrop-filter: blur(12px) saturate(120%);
          backdrop-filter: blur(12px) saturate(120%);
  box-shadow: 0 1px 0 var(--rule), 0 10px 24px rgba(11, 11, 11, .06);
}
.masthead-bar:not([data-scrolled="false"]) .masthead {
  padding-block: clamp(.75rem, 2vw, 1.125rem);
}

/* A sticky bar hides whatever an in-page link lands on, so every anchor target
   clears its own height. */
html { scroll-padding-top: 6rem; }

@media (prefers-reduced-motion: reduce) {
  .masthead-bar, .masthead-bar .masthead { transition: none; }}




/* ============================================================
   THE REVEAL
   Sections and works rise as they arrive. app-side, base.html puts
   [data-rise] on the bands and [data-stagger] on the hang, then adds
   .in when each one crosses the line.

   EVERY HIDDEN STATE IS GATED ON `html.js`. With the script off none of
   these rules match, the page renders exactly as it did before, fully
   visible, and a crawler sees the whole thing. A reveal that can leave
   content hidden is not a reveal, it is a blank page.

   28px and 720ms are deliberate. Smaller numbers are not "restrained",
   they are invisible — the reader sees nothing happen and the work was
   spent for nothing. Restraint here is in WHERE the motion goes: whole
   sections and the hang, never individual words, never the navigation,
   and never a painting on its own.
   ============================================================ */
:root {
  --rise-y: 28px;
  --rise-t: 720ms;
  --rise-step: 70ms;
}

.js .band, .js .aside-work, .js .split-plate,
.js [data-rise] {
  opacity: 0;
  transform: translate3d(0, var(--rise-y), 0);
  transition: opacity var(--rise-t) var(--ease), transform var(--rise-t) var(--ease);
}
.js [data-rise].in { opacity: 1; transform: none; }

/* The hang arrives piece by piece rather than as a slab. Eight steps is where it
   stops reading as a sequence and starts reading as a wait, so it repeats after
   that instead of growing. */
.js .hang > *,
.js [data-stagger] > * {
  opacity: 0;
  transform: translate3d(0, var(--rise-y), 0);
  transition: opacity var(--rise-t) var(--ease), transform var(--rise-t) var(--ease);
}
.js [data-stagger].in > * { opacity: 1; transform: none; }
.js [data-stagger].in > *:nth-child(8n+1) { transition-delay: 0ms; }
.js [data-stagger].in > *:nth-child(8n+2) { transition-delay: calc(var(--rise-step) * 1); }
.js [data-stagger].in > *:nth-child(8n+3) { transition-delay: calc(var(--rise-step) * 2); }
.js [data-stagger].in > *:nth-child(8n+4) { transition-delay: calc(var(--rise-step) * 3); }
.js [data-stagger].in > *:nth-child(8n+5) { transition-delay: calc(var(--rise-step) * 4); }
.js [data-stagger].in > *:nth-child(8n+6) { transition-delay: calc(var(--rise-step) * 5); }
.js [data-stagger].in > *:nth-child(8n+7) { transition-delay: calc(var(--rise-step) * 6); }
.js [data-stagger].in > *:nth-child(8n+8) { transition-delay: calc(var(--rise-step) * 7); }

@media (prefers-reduced-motion: reduce) {
  .js .band, .js .aside-work, .js .split-plate, .js .hang > *,
  .js [data-rise], .js [data-stagger] > * {
    opacity: 1 !important; transform: none !important;
    transition: none !important; transition-delay: 0ms !important;
  }}



/* ============================================================================
   THE INTEGRATED HERO (second-pass review, 15/09)

   The opening used to be TWO full-bleed bands: a painting at 62svh, then a
   separate statement band underneath carrying the label, the headline and the
   location line. On a laptop the two halves never appeared together -- the
   reader met a cropped painting with no name on it, scrolled past the fold, and
   met a sentence with no painting. They are one composition now.

   60/40. The art takes the larger share because the art is the argument; the
   panel takes enough to set three lines without the headline wrapping to five.

   MIN-HEIGHT, NEVER HEIGHT. The target is 520-580px, and the text decides where
   inside that it lands. A fixed height would have to be solved twice, because
   the Spanish runs longer than the English on nearly every line of this page,
   and solving it once is how a panel ends up with copy overflowing it.
   ========================================================================= */
/* THE PHOTOGRAPH MUST NOT SET THE HERO'S HEIGHT. With the image in normal flow,
   the grid row grows to the image's natural height at its column width -- so a
   PORTRAIT room shot made the commissions hero 1090px tall against a 580px
   target, while the home page's landscape painting happened to land at 559px
   and looked like the rule working. Taking the image out of flow leaves the row
   measured by the text panel and the min-height, which is what the brief asks
   for: "allowing text to determine the actual height". */
/* STACKED, AND STILL ONE SECTION. The two halves sit inside the same <section>
   on a phone, with no band boundary drawn between them -- the review is
   explicit that the stack must not reintroduce the artificial break the desktop
   layout just removed. */

/* THE SECOND ACTION IN A FOOT. The record link sits beside "About the artist"
   as the smaller, secondary item the review asks for -- same role and size, so
   it is not a sixth text treatment, but the quieter ink and no uppercase, so it
   does not read as an equal choice. */
.section-foot .go + .go--quiet { margin-left: 2rem; }
.go--quiet { color: var(--ink-soft); text-transform: none; letter-spacing: .02em; }

/* THE CITY ROW at the foot of Work. A row of links, not a control strip: the
   five city pages are part of the site from here, and the eye should read them
   as a sentence of place names rather than as filters over an inventory. The
   gap is the same 2rem that already separates two links in a section foot. */
.cities { display: flex; flex-wrap: wrap; gap: 1rem 2rem; margin: 0; }
/* Five cities on a phone wrapped four and one, leaving Panama alone on the
   second row -- the same stray-last-word fault in link form (24/09). Three and
   two instead. */
@media (max-width: 40rem) { .cities { display: grid; grid-template-columns: repeat(3, max-content); } }
/* TALL ENOUGH TO HIT, AND FAR ENOUGH APART. Measured at 390px and 360px: the
   row wraps on a phone, and at the old .35rem padding the links were 35px tall
   with 4px between Barcelona and Panama -- half the 8px WCAG 2.5.5 asks between
   neighbouring targets, on the one row whose whole job is being tapped by a
   buyer looking for their own city. The padding fixes both numbers at once. */
.cities a { padding-block: .6rem; }

/* THE PAGE HEAD. A title, one sentence and the links into the page, on a band
   that does not pretend to be a chapter of its own: the review removed the
   hero crop and the statement band above every one of these, so what is left
   introduces the page once and gets out of the way. Same top padding as a major
   section, less underneath, because the content it introduces begins
   immediately below it rather than after a boundary. */
section.band--head { padding-block: clamp(3rem, 5.3vw, 4.5rem) clamp(2rem, 3.5vw, 3rem); }

/* ============================================================================
   THE ARTIST PAGE'S INTRODUCTION (second-pass review, 15/09)

   A photograph of Nico on one side, his name, identity line and biography on
   the other. It replaces four sections: a bleed crop, a statement band, a
   Practice band on a cycling colour, and a profile that introduced his name for
   the first time after three screens of type about him.

   40/60 -- the reverse of the home page's hero, because here the words are the
   subject and the photograph is the evidence. The columns are `start`-aligned
   rather than centred so the biography can run longer than the portrait without
   dragging the picture down the page with it; the review asks specifically that
   the text not be forced into a fixed height.
   ========================================================================= */
.intro-split {
  display: grid;
  grid-template-columns: 40fr 60fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}
.intro-portrait { margin: 0; }
.intro-portrait img { display: block; width: 100%; height: auto; }
/* The biography's paragraphs are the only thing in this column that is not the
   header group, so the gap above them is the header-to-content gap. */
.intro-text .prose { margin-top: var(--gap-group); }
@media (max-width: 60rem) {
  .intro-split { grid-template-columns: minmax(0, 1fr); gap: 2rem; }
  /* THE WORDS COME FIRST ON A PHONE (JP, 17/09). In two columns the portrait
     sits beside the biography and neither leads. Stacked, the picture was on
     top -- so a reader arriving on the artist page met a photograph of a man in
     a studio and had to scroll past it to find out who he is and what the work
     argues. The thesis is the reason a curator keeps reading, and it is now the
     first thing on the page.
     ORDER, NOT A SECOND MARKUP BLOCK. The figure stays first in the document,
     which is what a screen reader follows and what the two-column layout wants;
     only the painted order changes, and only below 60rem. */
  .intro-text { order: -1; }}


.mail-line { margin-top: var(--gap-group); }

/* ============================================================================
   THE ENQUIRY FORM (15/09)

   Set like the rest of the site and not like a form: no boxes with rounded
   corners, no grey fills, no placeholder text standing in for a label. A field
   is a rule with a label over it, which is the same device the record and the
   specifications already use -- the page gains a form without gaining a second
   design language.

   EVERY CONTROL CLEARS 44px. The review's floor is 24px and that is the legal
   minimum; a form is the one place on a site where a missed target costs the
   owner an enquiry, so the targets here are sized for a thumb rather than for
   the audit.
   ========================================================================= */
/* THE FORM IS CENTRED ON THE PAGE'S AXIS (15/09). At 40rem inside a 78rem
   wrap it sat 498px left of centre under two centred header groups, which
   is what read as the page being out of alignment. The FIELDS inside it
   stay left-aligned: a centred label over a full-width input has no edge
   to follow down the form. */
.enquiry { margin-top: var(--gap-group); max-width: 40rem; margin-inline: auto; text-align: left; }
.field { border: 0; padding: 0; margin: 0 0 2rem; }
.field > label, .field legend {
  display: block;
  font-size: var(--t-label);
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 0 0 var(--gap-label);
  padding: 0;
}
.field-note {
  display: block;
  font-size: var(--t-meta);
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-soft);
  margin: .75rem 0 0;
}
.enquiry input[type="text"],
.enquiry input[type="email"],
.enquiry select,
.enquiry textarea {
  width: 100%;
  font: 400 var(--t-body)/1.6 var(--sans);
  color: var(--ink);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--rule);
  border-radius: 0;
  padding: .75rem 0;
  /* Safari rounds a text input and tints a select on its own; both would be the
     only rounded corners on the site. */
  -webkit-appearance: none;
  appearance: none;
}
.enquiry select {
  /* With the native arrow suppressed the control needs one drawn back, or it
     reads as a text field that will not accept typing. */
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-soft) 50%),
                    linear-gradient(135deg, var(--ink-soft) 50%, transparent 50%);
  background-position: right 4px center, right 0 center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 1.5rem;
}
.enquiry textarea { resize: vertical; }
.enquiry input:focus-visible,
.enquiry select:focus-visible,
.enquiry textarea:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}

/* --- THE FORM ON PAPER (JP, 21/09) ----------------------------------------
   The page went white. The boxes stayed, and that was deliberate: JP's
   instruction on 17/09 was "make sure you can see the boxes", and a field a
   reader cannot find is the same fault on any ground. What changes here is
   only which colours draw them.

   AN UNDERLINE IS NOT AN INVITATION. The base rule sets a field as a label
   over a bottom rule, which is right for the record and the specifications --
   they are things to read. A form is a thing to DO, and a reader has to see
   where the typing goes before reading a single label. Four sides and a ground
   one step off the page say that without an instruction on the screen.

   MEASURED, not estimated, against #F4F1EA:
     field ground  ink at 3%          -> #EDEAE3
     border        #8A8479            -> 3.29:1 on paper, 3.09:1 on the field,
                                        clearing the 3:1 WCAG asks of a
                                        control's boundary on both sides of it
     typed text    --ink   #0B0B0B    -> 16.38:1
     placeholder   --ink-soft #5A574F -> 6.00:1, quiet but never decorative
   #8A8479 is not a new colour: it is the rule the cycle band already carries.

   THE TINT IS ink AT 3%, not a named grey, so the treatment stays correct if
   this band is ever put back on a colour. */
.band--form .enquiry input[type="text"],
.band--form .enquiry input[type="email"],
.band--form .enquiry select,
.band--form .enquiry textarea {
  background: rgba(11, 11, 11, .03);
  border: 1px solid #8A8479;
  color: var(--ink);
  padding: .7rem .85rem;
}
.band--form .enquiry select {
  /* The drawn arrow is built from --ink-soft, so it follows the ground without
     being restated here. */
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-soft) 50%),
                    linear-gradient(135deg, var(--ink-soft) 50%, transparent 50%);
  background-position: right .85rem center, right .55rem center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 2rem;
}
/* A select's own dropdown is drawn by the OS, not by this stylesheet. Stated
   rather than left to inherit: it is one line and it cannot go wrong. */
.band--form .enquiry select option { color: #141414; background: #FFFFFF; }
.band--form .enquiry ::placeholder { color: var(--ink-soft); opacity: 1; }
.band--form .enquiry input:hover,
.band--form .enquiry select:hover,
.band--form .enquiry textarea:hover { border-color: var(--ink-soft); }
.band--form .enquiry input:focus-visible,
.band--form .enquiry select:focus-visible,
.band--form .enquiry textarea:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

/* --- ONE BRANCH AT A TIME (JP, 21/09) -------------------------------------
   The form asked an investment range, a delivery month and a readiness score
   of somebody whose answer was "that painting, the one on the page I came
   from". None of the three has an answer for an existing work, and a question
   with no answer is what makes a form feel like a form.

   PURE CSS, because the page still ships no script of its own and a reveal
   that needs one would leave a reader with scripting off staring at a fork
   that goes nowhere.

   GATED ON @supports, WHICH IS THE WHOLE SAFETY. Without `:has()` these rules
   never apply and BOTH branches stay on screen -- longer than intended, and
   completely usable. Written the other way round, a browser that did not
   understand the selector would hide two thirds of the form and keep it
   hidden, and the enquiry would be lost rather than lengthened. */
@supports selector(:has(*)) {
  .enquiry .branch { display: none; }
  .enquiry:has(#p-existing:checked) .only-existing { display: block; }
  .enquiry:has(#p-custom:checked) .only-commission { display: block; }
}

/* MORE ROOM BEFORE THE FIRST FIELD (JP, 17/09). The form opened one group-gap
   under the head; now that the head is a band of its own, that gap sits on top
   of the band's own padding and the two together were still tight, because the
   colour above draws the eye and the first label has to clear it. */
.band--form .enquiry { margin-top: clamp(1rem, 2.5vw, 2rem); }

/* A CHOICE IS A WHOLE LINE, NOT A 13px DOT. The label wraps the input, so the
   text is part of the target: 44px tall and as wide as the words. */
.choices { display: flex; flex-wrap: wrap; gap: .25rem 2rem; }
.choices--stack { flex-direction: column; gap: .25rem; }
.choice {
  display: flex;
  align-items: center;
  gap: .75rem;
  min-height: 2.75rem;
  font-size: var(--t-body);
  line-height: 1.4;
  cursor: pointer;
}
.choice input { width: 1.125rem; height: 1.125rem; accent-color: var(--ink); margin: 0; flex: none; }

/* THE READINESS SCALE. Five radios rather than a range input: a slider has no
   visible value without JavaScript and this page has none. */
.scale { display: flex; gap: .5rem; }
/* THE FIVE BOXES HAVE TO LOOK LIKE FIVE BUTTONS (JP, 21/09). They were drawn
   in `--rule`, the hairline that separates two paragraphs: #CFC9BC measures
   1.46:1 on paper, so the only thing telling a reader these were pressable was
   the digit inside them. A control's boundary wants 3:1, and #8A8479 -- the
   same border the fields above now carry -- measures 3.29:1. The scale reads as
   part of the form instead of as five numbers in a row. */
.scale-step {
  flex: 1 1 0;
  display: flex; align-items: center; justify-content: center;
  min-height: 2.75rem;
  border: 1px solid #8A8479;
  font-size: var(--t-body);
  cursor: pointer;
}
.scale-step:hover { border-color: var(--ink); }
.scale-step input { position: absolute; opacity: 0; pointer-events: none; }
.scale-step:has(input:checked) { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.scale-step:has(input:focus-visible) { outline: 2px solid var(--ink); outline-offset: 2px; }
.scale-ends {
  display: flex; justify-content: space-between;
  font-size: var(--t-meta); color: var(--ink-soft);
  margin-top: .75rem;
}

.submit {
  font: 500 var(--t-nav)/1.4 var(--sans);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--paper);
  background: var(--ink);
  border: 1px solid var(--ink);
  border-radius: 0;
  padding: 1rem 2rem;
  min-height: 2.75rem;
  cursor: pointer;
}
.submit:hover { background: transparent; color: var(--ink); }
.submit:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

/* THE ADDRESS UNDER THE FORM SITS ON THE PAGE'S AXIS, not against the left
   edge of a 78rem wrap. The declaration belongs HERE and not beside the
   base `.mail-line` rule: this one comes later in the file and re-declares
   `display`, so a centring rule written up there lost the cascade and the
   address stayed exactly where it was. (15/09) */
.mail-line--under { display: block; width: max-content; max-width: 100%;
                    margin: 2rem auto 0; }

/* THE CONFIRMATION, WITHOUT A LINE OF SCRIPT. Web3Forms redirects back to this
   page at `#sent`; `:target` is what makes that visible. It is display:none
   until then, so a reader who has not sent anything never meets a thank-you. */
.sent { display: none; }
/* ONCE SENT, THE THANK-YOU IS THE WHOLE PAGE (JP, 22/09). The page used to
   show the confirmation ABOVE the heading and the full form again, which read
   as "did it go?". Now the heading and the form step aside and the two lines
   stand alone, centred. The form band is reached with `:has()`; a browser
   without it keeps the form under the thank-you, which is where it was. */
.sent:target {
  display: block; text-align: center;
  max-width: 40rem; margin: 0 auto; padding-block: clamp(2rem, 6vw, 5rem);
}
.sent:target .group-sub { margin-inline: auto; }
.sent:target + .section-head { display: none; }
body:has(.sent:target) .band--form { display: none; }

/* ============================================================================
   THE HERO CLIP (15/09)

   The video and the still occupy the same box. Which one the reader sees is a
   stylesheet decision, not a template one, because there is no way to refuse an
   autoplay from CSS -- so under `prefers-reduced-motion` the clip is taken out
   and the painting is put back, rather than a paused frame being left on screen
   pretending to be a design.

   BOTH ARE `object-fit: cover` AND ABSOLUTELY POSITIONED, so neither can set the
   hero's height. That is the same rule the still already follows and the reason
   a portrait photograph made this hero 1090px tall before it did.
   ========================================================================= */
.hero-video {
  position: absolute; inset: 0;
  display: block;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center;
}
/* The still is what sets the hero's height -- `.hero-figure img` gives it
   clamp(340px, 56vh, 620px) -- and the clip is laid over it, so a missing or
   slow video can never collapse the band. */
.hero-figure { position: relative; }
/* The still sits under the clip, so the painting is on screen from the first
   paint rather than after the video's first frame decodes. It is not hidden:
   hiding it would mean an empty box for as long as the network takes. */
.hero-still--under { z-index: 0; }
.hero-video { z-index: 1; }
/* NO PLAY BUTTON, EVER (22/09). When an iPhone refuses an autoplay -- Low Power
   Mode refuses every one -- Safari paints its own play button over the clip, and
   the hero reads as broken until it is tapped. The script in base.html starts
   the clip on the first touch anywhere; until then this keeps the painting on
   screen with nothing drawn over it. */
.hero-video::-webkit-media-controls-start-playback-button { display: none !important; -webkit-appearance: none; }
.hero-video::-webkit-media-controls { display: none !important; }
.hero-video::-webkit-media-controls-overlay-play-button,
.hero-video::-webkit-media-controls-play-button,
.hero-video::-webkit-media-controls-panel,
.hero-video::-webkit-media-controls-enclosure { display: none !important; -webkit-appearance: none; opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  /* THE PAINTING, NOT A FROZEN CLIP. A reader who has asked their system for
     less movement gets the hero the site shipped with for a fortnight, which is
     a finished thing in its own right and not a degraded version of anything. */
  .hero-video { display: none; }}



/* ============================================================================
   THE TWO PRESS ITEMS THAT ARE LINKS (15/09)

   Everything else under "In print" is a screenshot standing in for proof that
   cannot be linked yet. These two can: the El Universal interview and the
   Casapais issue whose cover he painted. So they are bigger, they are
   clickable, and each carries a LINE rather than a URL -- the reason to click,
   not the address. A pasted address on a page whose job is being believed is
   something to squint at.
   ========================================================================= */
/* TWO PRESS ITEMS, AT THUMBNAIL SIZE, UNDER THE RECORD'S PRESS LIST.
   72px is not a new number: it is what `.work-nav-thumb` already uses for the
   previous and next painting, and it is this site's established size for a
   picture that stands in for a page somewhere else. The row reads like one more
   record line with a picture on it, which is what it is. */
.press-thumbs {
  list-style: none; margin: 1.25rem 0 0; padding: 0;
  display: grid; gap: .85rem;
}
.press-thumb {
  display: flex; align-items: center; gap: .9rem;
  text-decoration: none; color: inherit;
  padding-block: .15rem; margin-block: -.15rem;   /* 24px of target, as the film rows get */
}
.press-thumb::after { content: none; }            /* the drawn-rule hover is for text links */
.press-thumb-img { flex: 0 0 72px; width: 72px; height: 54px; display: block; overflow: hidden; }
.press-thumb-img img { width: 100%; height: 100%; object-fit: cover; object-position: top center; }
.press-thumb-line {
  font-size: var(--t-meta); line-height: 1.5; color: var(--ink-soft);
  text-decoration: underline; text-underline-offset: .22em;
  text-decoration-thickness: 1px; text-decoration-color: var(--rule);
}
.press-thumb:hover .press-thumb-line,
.press-thumb:focus-visible .press-thumb-line { text-decoration-color: currentColor; color: var(--ink); }
@media (min-width: 40rem) { .press-thumbs { grid-template-columns: repeat(2, minmax(0, 1fr)); }}



/* The process terms and steps, no longer in the right half of a split rule. */
/* 38rem, NOT 44rem (15/09). The body was 44rem and the paragraph inside it
   took the site's 38rem measure cap, so the terms sentence and the numbered
   steps under it were two different widths on two different axes. Matching
   the body to the measure makes them one column. */
.process-body { max-width: 38rem; margin-inline: auto; }
.process-body .steps { margin-top: var(--gap-group); max-width: none; }
/* THE TERMS PARAGRAPH SHARES THE STEPS' AXIS. It carried `.prose`'s 34rem
   measure inside a 44rem body and sat flush left, so the sentence started
   on the same line as the numbered steps but ended 160px short of them --
   the one thing in the section that lined up with nothing. (15/09) */
.process-body .prose { max-width: none; }
.prose--fit { text-align: center; }
.prose--fit p { margin-inline: auto; text-wrap: balance; }

/* ---------------------------------------------------------------------------
   THE LAST LINE IS NEVER ONE WORD (JP, 24/09). Everything short -- headings,
   descriptions, captions, notes, labels -- balances its lines, so a two-line
   block is two even lines rather than a full one and a stray word. Running
   text uses `pretty`, which keeps paragraphs natural and only pulls words
   down to stop the last line being a single one. The work title used to be
   exempt (`initial`, so the artist's name could break anywhere); it is not
   any more, because "Interpretacion del terremoto en" / "Venezuela" is exactly
   what this forbids. build.py also joins the last two words of every block
   with a no-break space, for the browsers that ignore these properties.
   --------------------------------------------------------------------------- */
h1, h2, h3, .h2, .h2--name, .display, .lede, .group-sub, .said, .cap-title,
.cap-meta, .work-note, .eyebrow, figcaption, dd, dt { text-wrap: balance; }
p, li, blockquote { text-wrap: pretty; }
.lede, .group-sub, .said, .cap-title, .cap-meta, .work-note { text-wrap: balance; }

/* ---------------------------------------------------------------------------
   THE PROCESS DIAGRAM (encargos, JP 24/09). A line of four stations: a serif
   numeral in a ring, the ring threaded on a hairline, the step underneath in
   the site's running text (.prose p: Inter, body size, 1.6). Across on a
   desktop, down on a phone, where the hairline runs vertically behind the
   rings. Achromatic like everything that is not a painting.
   --------------------------------------------------------------------------- */
.process {
  list-style: none; margin: var(--gap-group) auto 0; padding: 0;
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 2rem;
  max-width: 68rem; position: relative;
}
.process::before {
  content: ""; position: absolute; top: 1.5rem; left: 12.5%; right: 12.5%;
  border-top: 1px solid var(--rule);
}
.process-step { position: relative; display: flex; flex-direction: column; align-items: center; text-align: center; gap: 1.25rem; }
.process-n {
  width: 3rem; height: 3rem; border-radius: 50%; display: grid; place-items: center;
  background: var(--paper); border: 1px solid var(--ink); position: relative;
  font: 400 1.5rem/1 var(--serif); color: var(--ink);
}
.process-step p {
  margin: 0; max-width: 16rem;
  font-family: var(--sans); font-size: var(--t-body); line-height: 1.6; letter-spacing: -.005em;
  color: var(--ink); text-wrap: balance;
}
@media (max-width: 48rem) {
  .process { grid-template-columns: 1fr; gap: 1.75rem; max-width: 30rem; }
  .process::before { top: 1.5rem; bottom: 1.5rem; left: 1.5rem; right: auto; border-top: 0; border-left: 1px solid var(--rule); }
  .process-step { flex-direction: row; align-items: flex-start; text-align: left; gap: 1.25rem; }
  .process-n { flex: none; }
  .process-step p { max-width: none; padding-top: .55rem; text-wrap: pretty; }
}

/* PRIVACY AND COOKIES (01/10). The banner sits on paper at the foot of the
   screen, achromatic like everything that is not a painting. Buttons carry the
   #8A8479 border (3.29:1 on paper -- clears the 3:1 a control needs; --rule does
   not) and a 44px minimum height so a thumb can hit them. Hidden by the
   `hidden` attribute until the script decides to ask. */
.consent {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
  background: var(--paper); color: var(--ink);
  border-top: 1px solid #8A8479;
  padding: 16px max(16px, env(safe-area-inset-left)) calc(16px + env(safe-area-inset-bottom));
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 12px 24px;
  font-size: 15px; line-height: 1.45;
}
.consent[hidden] { display: none; }
.consent-text { margin: 0; max-width: 46rem; text-wrap: pretty; }
.consent-text a { color: inherit; text-decoration: underline; text-underline-offset: 3px; }
.consent-actions { display: flex; gap: 12px; }
.consent-btn {
  min-height: 44px; padding: 0 20px; font: inherit; cursor: pointer;
  background: transparent; color: var(--ink); border: 1px solid #8A8479; border-radius: 0;
}
.consent-btn--yes { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.consent-btn:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.foot-legal { display: block; margin-top: 6px; }
.foot-legal a { color: inherit; }
.legal { max-width: 44rem; }
.legal-updated { color: var(--ink-soft); margin-top: 0; }
.legal-title { font-size: 1.15rem; margin: 2rem 0 .5rem; }
.legal p a { color: inherit; }


/* --- THE SLIDER (JP, 02/10) ------------------------------------------------
   Commissions page, rooms and murals. A full-width strip of photographs at one
   height, each at its own shape, snapping one at a time. The strip runs to the
   screen edge on the right so the next photograph is visibly waiting; on the
   left it starts on the page's own margin, so the first photograph lines up
   with the heading above it. Colour comes from the band: on ink everything is
   paper, on paper everything is ink, and nothing here names a colour. */
.band--slider .section-head { margin-bottom: clamp(2rem, 4vw, 3.5rem); }
.slider { --edge: max(var(--gutter), calc((100% - 78rem) / 2 + var(--gutter))); }
.slider-track {
  display: flex;
  align-items: flex-start;
  gap: clamp(1rem, 2.4vw, 2.25rem);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  padding: clamp(1rem, 2vw, 1.75rem) var(--edge);
  scrollbar-width: none;
  cursor: grab;
}
.slider-track::-webkit-scrollbar { display: none; }
.slider-track.is-dragging { cursor: grabbing; scroll-snap-type: none; }
.slider-track.is-dragging .slide img { transition: none; }
.slider-track:focus-visible { outline: 2px solid currentColor; outline-offset: 4px; }
.slide {
  flex: none;
  margin: 0;
  scroll-snap-align: center;
}
.slide .shot { display: block; }
.slide img {
  display: block;
  height: clamp(20rem, 70vh, 50rem);
  width: auto;
  max-width: 80vw;
  object-fit: cover;
  user-select: none;
  -webkit-user-drag: none;
  transform-origin: 50% 50%;
  transition: transform .7s cubic-bezier(.22, .61, .36, 1), opacity .7s ease, filter .7s ease;
}
/* ONE PHOTOGRAPH IN THE LIGHT (JP, 02/10). The centred one sits at full size and
   full strength; the others step back -- smaller, fainter, a shade darker -- so
   the eye has one place to land. Hovering the centred one lifts it a little
   more, which is the cue that a click opens it. */
.js .slide:not(.is-current) img { transform: scale(.9); opacity: .4; filter: brightness(.8) saturate(.7); }
.js .slide.is-current img { transform: scale(1); }
.js .slide.is-current .shot { cursor: zoom-in; }
@media (hover: hover) {
  .js .slide.is-current .shot:hover img { transform: scale(1.03); }
  .js .slide:not(.is-current) .shot:hover img { opacity: .6; }
}
/* THE CAPTION IN THE WORK TITLES' FACE (JP, 02/10): the serif the paintings'
   names are set in, so a room reads like a plate in a catalogue. */
.slide-cap {
  margin-top: 1rem;
  text-align: center;
  font-family: var(--serif);
  font-size: var(--t-title);
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: -.01em;
  opacity: 0;
  transition: opacity .6s ease;
}
.slide.is-current .slide-cap { opacity: 1; }
html:not(.js) .slide-cap { opacity: 1; }
.slider-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: clamp(1.25rem, 2.5vw, 2rem);
}
.slider-count {
  margin: 0;
  font-family: var(--serif);
  font-size: clamp(1.75rem, 1.2rem + 1.4vw, 2.75rem);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.slider-of { opacity: .5; }
.slider-nav { display: flex; gap: .75rem; }
.slider-btn {
  width: 3.25rem;
  height: 3.25rem;
  border-radius: 50%;
  border: 1px solid currentColor;
  background: transparent;
  color: inherit;
  font-size: 1.125rem;
  cursor: pointer;
  transition: background-color .25s ease, color .25s ease, opacity .25s ease;
}
.band--ink .slider-btn:hover:not(:disabled) { background: var(--paper); color: var(--ink); }
.band--paper .slider-btn:hover:not(:disabled) { background: var(--ink); color: var(--paper); }
.slider-btn:disabled { opacity: .3; cursor: default; }
.slider-btn:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }
html:not(.js) .slider-bar { display: none; }
@media (prefers-reduced-motion: reduce) {
  .slide img, .slide-cap { transition: none; }
  .js .slide:not(.is-current) img, .js .slide.is-current .shot:hover img { transform: none; }
}


/* --- THE PROCESS, DRAWN (JP, 02/10) ----------------------------------------
   From clients/nico/process-iconography/integration/process.css, minus the
   preview page's own section, heading and intro rules: the site's section
   head and fit paragraph stay as they are. Four across, two on a tablet, one
   on a phone. */
.nico-process-list{margin-top:clamp(2.5rem,5vw,4rem)!important;text-align:center}
.nico-process-step>p{font-family:var(--sans)}
/* Scoped layout for the supplied fragment. Use the site's existing heading/font tokens. */
.nico-process-list{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:24px;margin:0;padding:0;list-style:none}
.nico-process-step{min-width:0}
.nico-process-icon{display:block;width:100%;height:auto;aspect-ratio:5/7;overflow:visible}
/* ONE AFTER ANOTHER (JP, 02/10). Each drawing plays at 0.4x its supplied
   length (about 1.3s), the next waits for the one before it, and a step's
   number, label and paragraph fade in once its drawing is finished. The
   script sets data-text; without it, or with reduced motion, everything shows. */
.nico-process-icon{--pace:.4}
@media(prefers-reduced-motion:no-preference){
.nico-process-step[data-text]>:not(svg){transition:opacity .35s ease,transform .35s ease}
.nico-process-step[data-text="wait"]>:not(svg){opacity:0;transform:translateY(8px)}
}
.nico-process-number{display:block;font-family:var(--serif,"Instrument Serif",Georgia,serif);font-size:22px;margin:12px 0 8px}
.nico-process-step h3{font-family:var(--serif,"Instrument Serif",Georgia,serif);font-weight:400;font-size:clamp(28px,2.6vw,36px);line-height:1.12;margin:0 0 12px;text-wrap:balance}
.nico-process-step>p{font-size:16px;line-height:1.55;margin:0 auto;max-width:30ch;text-wrap:pretty}
@media(max-width:900px) and (min-width:641px){.nico-process-list{grid-template-columns:repeat(2,minmax(0,1fr));gap:42px}.nico-process-icon{max-width:310px;margin-inline:auto}}
@media(max-width:640px){.nico-process-list{grid-template-columns:1fr;gap:38px}.nico-process-icon{width:min(100%,240px);margin-inline:auto}.nico-process-step h3{font-size:34px}.nico-process-step>p{font-size:17px}}

/* GOOGLE REVIEWS BAND (23/10): the widget is asked for its dark theme (data-theme in index.html)
   and sits straight on the ink band, no white box, so it reads as part of the page rather than a
   pasted panel. Hidden until the visitor accepts cookies (see index.html). */
.reviews-band [data-reviews][hidden] { display: none; }
.reviews-box { margin-top: 1.25rem; }
/* NEWSLETTER SIGN-UP (23/10, _news_form.html). One underlined field and the site's own `go`
   button on one line, the consent in the small type under it. No box, no colour of its own:
   it takes the ink of whatever band it sits in. */
.news-form { max-width: 34rem; margin: 1.5rem auto 0; text-align: left; }
.center .news-form .news-lead { text-align: center; }
.news-lead { font-family: var(--serif); font-size: clamp(1.15rem, 1rem + .6vw, 1.45rem); line-height: 1.35; margin: 0 0 1.25rem; }
.news-row { display: flex; align-items: flex-end; gap: 1.25rem; }
.news-email {
  flex: 1; min-width: 0; font: 400 1rem/1.4 var(--sans); color: inherit; background: transparent;
  border: 0; border-bottom: 1px solid currentColor; border-radius: 0; padding: .6rem 0; outline: none;
}
.news-email::placeholder { color: var(--ink-soft); opacity: 1; }
.news-email:focus-visible { border-bottom-width: 2px; padding-bottom: calc(.6rem - 1px); }
.news-go { background: none; color: inherit; cursor: pointer; padding: .6rem 0 .5rem; border-left: 0; border-right: 0; border-top: 0; border-bottom-color: currentColor; }
.news-consent { display: flex; gap: .6rem; align-items: flex-start; margin-top: 1rem; font-size: var(--t-nav); line-height: 1.5; color: var(--ink-soft); }
.news-consent input { margin-top: .25rem; accent-color: currentColor; flex: none; }
.news-consent a { color: inherit; }
.news-done { font-family: var(--serif); font-size: 1.25rem; margin: 0; }
.center .news-done { text-align: center; }
.news-form--small { margin: 1.75rem 0 0; max-width: 28rem; }
.news-form--small .news-lead { font-family: inherit; font-size: inherit; line-height: 1.5; margin-bottom: .75rem; }


/* =========================================================================
   REDISENO, SLICE 1 -- ONE HANG, A FILTER, A VIEWER (24/10, JP)
   ========================================================================= */

/* A filtered-out or not-yet-shown plate. `.work` sets display:flex, which would
   beat the browser's own [hidden] rule, so it is restated here. */
.work[hidden], .filters[hidden], .filter-none[hidden], .filter-pdf[hidden],
.see-more[hidden], .viewer[hidden], .viewer-ask[hidden] { display: none; }

/* --- THE FILTER BAR -------------------------------------------------------
   Two quiet rows: what kind of work, then the one thing a buyer asks -- is it
   available and where is it. Small capitals like the navigation, no boxes: the
   pressed one is underlined and set in full ink, the rest sit back. */
.band--filters { padding-block: clamp(1.75rem, 4vw, 3rem) 0; }
.filters { display: grid; gap: .5rem 0; margin-bottom: clamp(2rem, 4vw, 3rem); }
.filter-row { display: flex; flex-wrap: wrap; align-items: center; gap: .25rem 1.75rem; }
.filter-cities { display: contents; }
.filter-label {
  font: 400 var(--t-label)/1 var(--sans); letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-soft); padding-right: .25rem;
}
.chip {
  appearance: none; background: none; border: 0; margin: 0; cursor: pointer;
  padding: .7rem 0; color: var(--ink-soft);
  font: 500 var(--t-nav)/1.2 var(--sans); letter-spacing: .06em; text-transform: uppercase;
  border-bottom: 1px solid transparent;
  transition: color .25s var(--ease), border-color .25s var(--ease);
}
.chip:hover, .chip:focus-visible { color: var(--ink); }
.chip[aria-pressed="true"] { color: var(--ink); border-bottom-color: var(--ink); }
/* The availability switch is the one control that is a box: it is the question a
   buyer opens the page to ask, so it is allowed to look pressable. */
.chip--switch {
  padding: .55rem 1.1rem; border: 1px solid var(--ink-soft); border-bottom-color: var(--ink-soft);
  margin-right: .5rem;
}
.chip--switch[aria-pressed="true"] { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.filter-pdf { margin: .25rem 0 0; }
.filter-none { text-align: center; padding-block: clamp(2rem, 6vw, 4rem); color: var(--ink-soft); }
.filter-none button { background: none; border: 0; cursor: pointer; padding: 0; font: inherit; text-decoration: underline; }

/* --- THE FOLD, ONE BUTTON ------------------------------------------------- */
.see-more-wrap { text-align: center; margin: clamp(2.5rem, 6vw, 4rem) 0 0; }
.see-more {
  appearance: none; cursor: pointer; background: none; color: inherit;
  padding: clamp(.9rem, 2.2vw, 1.1rem) clamp(1.75rem, 5vw, 2.75rem);
  border: 1px solid currentColor;
  font: 500 var(--t-nav)/1.4 var(--sans); letter-spacing: .06em; text-transform: uppercase;
  transition: background-color .25s var(--ease), color .25s var(--ease);
}
.see-more:hover, .see-more:focus-visible { background: var(--ink); color: var(--paper); }

/* --- TWO CAPTION LINES, THE SAME HEIGHT ON EVERY PLATE ---------------------
   Title on one line (a long one is cut; the viewer shows it whole), then the
   facts on two reserved lines, so every painting in a row stands on one
   baseline without anyone counting lines. On a phone the technique drops out of
   the grid caption (it is in the viewer) so the size, year and place fit. */
.work .cap-title { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.work .cap-meta {
  min-height: 2lh; margin-top: .35rem;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
  text-wrap: pretty;
}
.work .cap-meta span { white-space: nowrap; }
.work .cap-meta span:not(:last-child)::after { content: "\00a0\00b7"; }
.work .cap-meta span:nth-last-child(2)::after { content: "\00a0\00b7\00a0"; }
.work .cm-place--sold { font-style: italic; }
@media (max-width: 52rem) {
  .work .cm-tech { display: none; }
}
@media (max-width: 34rem) {
  .filter-label { flex-basis: 100%; margin-top: .75rem; }
  .filter-row { gap: .1rem 1.4rem; }
}

/* --- THE VIEWER ------------------------------------------------------------ */
html.viewing { overflow: hidden; }
.viewer {
  position: fixed; inset: 0; z-index: 200;
  background: var(--ink); color: var(--paper);
  display: flex; align-items: center; justify-content: center;
  touch-action: pinch-zoom;
}
.viewer-fig {
  margin: 0; width: 100%; height: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 1.25rem; padding: clamp(3.5rem, 7vh, 4.5rem) clamp(1rem, 9vw, 7rem) clamp(1rem, 3vh, 2rem);
}
.viewer-img {
  display: block; width: auto; height: auto; max-width: 100%;
  max-height: calc(100dvh - 11.5rem); object-fit: contain;
}
.viewer-img.in { animation: viewer-in .45s var(--ease); }
@keyframes viewer-in { from { opacity: 0; transform: scale(.985); } to { opacity: 1; transform: none; } }
.viewer-cap { text-align: center; min-height: 5.5rem; }
.viewer-cap .cap-title { color: var(--paper); font-size: var(--t-h3); line-height: 1.1; }
.viewer-cap .cap-meta { color: rgba(244, 240, 232, .72); margin: .4rem 0 0; font-size: var(--t-meta); }
.viewer-ask { display: inline-block; margin-top: .9rem; color: var(--paper); }

/* The sides of the screen are the arrows. The cursor says so on a desktop; a
   phone swipes. They draw nothing. */
.viewer-edge {
  position: absolute; top: 4rem; bottom: 7rem; width: min(18%, 9rem);
  appearance: none; background: none; border: 0; padding: 0; cursor: pointer;
}
.viewer-edge--prev {
  left: 0;
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='44' height='44' viewBox='0 0 44 44'%3E%3Cpath d='M27 8 13 22l14 14' fill='none' stroke='white' stroke-width='2'/%3E%3C/svg%3E") 22 22, w-resize;
}
.viewer-edge--next {
  right: 0;
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='44' height='44' viewBox='0 0 44 44'%3E%3Cpath d='M17 8l14 14-14 14' fill='none' stroke='white' stroke-width='2'/%3E%3C/svg%3E") 22 22, e-resize;
}
.viewer-edge:focus-visible { outline: 1px solid rgba(244, 240, 232, .6); outline-offset: -4px; }
.viewer-close {
  position: absolute; top: .75rem; right: .75rem; width: 3rem; height: 3rem;
  appearance: none; background: none; border: 0; cursor: pointer; padding: 0;
}
.viewer-close::before, .viewer-close::after {
  content: ""; position: absolute; left: 50%; top: 50%; width: 1.5rem; height: 1px;
  background: var(--paper); transform: translate(-50%, -50%) rotate(45deg);
}
.viewer-close::after { transform: translate(-50%, -50%) rotate(-45deg); }
@media (prefers-reduced-motion: reduce) { .viewer-img.in { animation: none; } }
::view-transition-group(nlv) { animation-duration: .5s; animation-timing-function: var(--ease); }


/* =========================================================================
   REDISENO, SLICE 2 -- THE LOOK (24/10, JP: the Louvre's page)

   ONE TYPE SYSTEM, WRITTEN ONCE, HERE. The stylesheet above answers "what does
   a heading look like" in sixty places and each answer was a little different.
   This block is the answer: capital titles, always left, three sizes (opener
   72/44, section 40/30, sub-heading 24/20), Roboto for everything that is not
   a title, and Light only where the text is 16px or more (below that it goes
   too thin on paper, so captions and labels stay Regular).
   ========================================================================= */
:root {
  --sans: "Roboto", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --t-h1: clamp(2.75rem, .274rem + 6.604vw, 4.5rem);   /* 44 -> 72, a page opener   */
  --t-h2: clamp(1.875rem, 1.35rem + 1.5vw, 2.5rem);    /* 30 -> 40, a section       */
  --t-h3: clamp(1.25rem, 1.1rem + .5vw, 1.5rem);       /* 20 -> 24, a sub-heading   */
  --head-track: .04em;
  --section-pad: clamp(3.5rem, 7vw, 6rem);
}
/* The preview can wear the Louvre's own title face: add ?type=forum to any
   address and it stays for the session. Instrument Serif is the default. */
html[data-type="forum"] { --serif: "Forum", "Instrument Serif", Georgia, serif; }

body { font-weight: 300; }
.cap-meta, .eyebrow, label, .news-consent, dt, dd, small, figcaption, input, select, textarea,
button, .chip, .filter-label, .cv-year, .work-note, .nav a, .lang, .foot { font-weight: 400; }
.lede, .group-sub, .said, .prose p, .opener-line, .news-art-line { font-weight: 300; }

.display, .h2, .group-head, .cv-head {
  text-transform: uppercase;
  letter-spacing: var(--head-track);
  text-align: left;
}
.display, .h2 { line-height: 1.04; }
.display { font-size: var(--t-h1); }
.h2 { font-size: var(--t-h2); }
.group-head, .cv-head { font-size: var(--t-h3); line-height: 1.15; }

/* LEFT, EVERYWHERE (JP: "it looks far more organised"). The old centring is
   undone here rather than in forty places; the sign-up band, the viewer and the
   see-more buttons keep their own centring. */
main .center, main .center .display, main .center .h2,
main .center .group-sub, main .center .lede, main .section-head, .group-head { text-align: left; }
main .center .display, main .center .h2, main .group-sub, main .center .group-sub { margin-inline: 0; }
.band { padding-block: var(--section-pad); }
.section-head { margin-bottom: clamp(2rem, 4vw, 3rem); }

/* --- THE OPENER ------------------------------------------------------------
   See `parts.opener`. The painting takes the right two thirds and fades into the
   ground on the left; on a phone it sits on top and fades down into it. */
.opener {
  --op-1: #0B0B0B;
  position: relative; isolation: isolate; overflow: hidden;
  background-color: var(--op-1); color: #FFFFFF;
  display: flex; align-items: center;
  min-height: clamp(21rem, 50svh, 31rem);
  --ink-soft: #D6D1C8;
}
.opener--tall { min-height: min(46rem, calc(100svh - 4.5rem)); }
.opener-media {
  position: absolute; inset: 0 0 0 auto; width: 66%; z-index: 0;
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 48%);
          mask-image: linear-gradient(to right, transparent 0, #000 48%);
}
.opener .opener-media .hero-figure { position: absolute; inset: 0; margin: 0; height: 100%; overflow: hidden; }
.opener .opener-media .hero-figure img,
.opener .opener-media .hero-figure video {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center;
}
.opener-wrap { position: relative; z-index: 1; width: min(78rem, 100%); }
.opener-text { max-width: min(40rem, 58%); padding-block: clamp(3rem, 8vw, 6rem); }
.opener .display { color: #FFFFFF; font-size: clamp(2.5rem, .8rem + 6.4vw, 5.5rem); text-wrap: balance; margin: 0; }
.opener--long .display { font-size: clamp(1.9rem, 1rem + 3.4vw, 3.6rem); }
.opener-line {
  margin: 1.25rem 0 0; max-width: 30rem; color: rgba(255, 255, 255, .9);
  font-family: var(--sans); font-size: var(--t-lede); line-height: 1.5; letter-spacing: -.005em;
}
.opener-go {
  display: inline-block; margin-top: 2rem; padding: .9rem 1.8rem;
  border: 1px solid rgba(255, 255, 255, .65); color: #FFFFFF; text-decoration: none;
  font: 500 var(--t-nav)/1.4 var(--sans); letter-spacing: .08em; text-transform: uppercase;
  transition: background-color .25s var(--ease), color .25s var(--ease), border-color .25s var(--ease);
}
.opener-go:hover, .opener-go:focus-visible { background: #FFFFFF; color: #0B0B0B; border-color: #FFFFFF; }
.opener :focus-visible { outline-color: #FFFFFF; }

@media (max-width: 52rem) {
  .opener { display: block; min-height: 0; }
  .opener--tall { min-height: 0; }
  .opener-media {
    position: relative; inset: auto; width: 100%; height: min(58svh, 27rem);
    -webkit-mask-image: linear-gradient(to bottom, #000 52%, transparent 100%);
            mask-image: linear-gradient(to bottom, #000 52%, transparent 100%);
  }
  .opener-text { max-width: none; margin-top: -4.5rem; padding-block: 0 clamp(2.5rem, 8vw, 3.5rem); }
}

/* THREE COLOURS PER PAGE, FROM THE PAGE'S OWN PAINTING, TURNING SLOWLY -- the
   way hagodigital.ai turns its heroes, eight seconds, back to the first. Each is
   the painting's hue darkened only as far as white type needs (7:1 and over);
   yellow is left out, because darkened enough for white it is olive. Sampled
   across the transitions, not just the stops, in tools/ui-check. */
.opener--obra     { --op-1: #264DC7; }
.opener--artista  { --op-1: #2954AD; }
.opener--contacto { --op-1: #A72349; }
.opener--encargos { --op-1: #AC1F09; }
@keyframes op-obra     { 0%, 100% { background-color: #264DC7; } 33% { background-color: #A1321D; } 66% { background-color: #1F6451; } }
@keyframes op-artista  { 0%, 100% { background-color: #2954AD; } 33% { background-color: #9A3924; } 66% { background-color: #6E35C4; } }
@keyframes op-contacto { 0%, 100% { background-color: #A72349; } 33% { background-color: #135B94; } 66% { background-color: #673BC2; } }
@keyframes op-encargos { 0%, 100% { background-color: #AC1F09; } 50% { background-color: #285A94; } }
@media (prefers-reduced-motion: no-preference) {
  .opener--obra     { animation: op-obra 8s ease-in-out infinite; }
  .opener--artista  { animation: op-artista 8s ease-in-out infinite; }
  .opener--contacto { animation: op-contacto 8s ease-in-out infinite; }
  .opener--encargos { animation: op-encargos 8s ease-in-out infinite; }
}

/* --- HOME ------------------------------------------------------------------ */
.band--selection { padding-top: clamp(1.5rem, 3vw, 2.5rem); }
.band--selection .wrap { position: relative; }
.masonry {
  list-style: none; margin: 0; padding: 0;
  columns: 3; column-gap: clamp(1.25rem, 2.4vw, 2.25rem);
}
.masonry .work { display: block; break-inside: avoid; margin-bottom: clamp(2rem, 4vw, 3rem); }
.masonry .plate { display: block; }
.masonry .plate img { width: 100%; height: auto; }
.masonry .cap-title { color: var(--paper); }
.masonry-rise .masonry .work { opacity: 0; transform: scale(.95); transition: opacity .5s var(--ease), transform .5s var(--ease); }
.masonry-rise .masonry .work.in { opacity: 1; transform: none; }
/* the foot of the columns dissolves into the ground, and the way on sits in it */
.band--selection .wrap::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 3.75rem; height: 10rem;
  background: linear-gradient(to bottom, rgba(11, 11, 11, 0), var(--ink)); pointer-events: none;
}
.masonry-foot { position: relative; z-index: 1; margin: 0; padding-top: .5rem; }
.band--selection { padding-bottom: clamp(2.5rem, 5vw, 4rem); }

.home-split {
  display: grid; align-items: center; gap: clamp(2rem, 6vw, 6rem);
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
}
.home-split--flip { grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); }
.home-split--flip .home-split-fig { order: 2; }
.home-split-fig { margin: 0; }
.home-split-fig img { display: block; width: 100%; height: auto; max-height: 40rem; object-fit: cover; }
.home-split-text .lede { margin-top: 1.25rem; max-width: 30rem; }
.home-split-text .section-foot { margin-top: 2rem; }
@media (max-width: 52rem) {
  .home-split, .home-split--flip { grid-template-columns: minmax(0, 1fr); }
  .home-split--flip .home-split-fig { order: 0; }
  .masonry { columns: 2; }
}

/* THE SIGN-UP ON A PAINTING (David Zwirner's way). The painting fills the band,
   a dark veil keeps white type readable, and the form is the whole section. */
.news-art {
  position: relative; isolation: isolate; overflow: hidden;
  background: #0B0B0B; color: #FFFFFF; padding-block: clamp(5rem, 12vw, 9rem);
  --ink-soft: #D6D1C8;
}
.news-art-media { position: absolute; inset: 0; z-index: -1; }
.news-art-media img { display: block; width: 100%; height: 100%; object-fit: cover; }
.news-art-media::after { content: ""; position: absolute; inset: 0; background: rgba(0, 0, 0, .62); }
.news-art-inner { text-align: center; max-width: 46rem; }
.news-art .h2 { color: #FFFFFF; text-align: center; }
.news-art-line {
  margin: 1.25rem auto 0; max-width: 34rem; font-family: var(--sans);
  font-size: var(--t-lede); line-height: 1.5; color: rgba(255, 255, 255, .9);
}
.news-art .news-form { margin: 2.25rem auto 0; max-width: 30rem; color: #FFFFFF; }
.news-art .news-email::placeholder { color: rgba(255, 255, 255, .75); }
.news-art .news-consent { color: rgba(255, 255, 255, .85); text-align: left; }
.news-art .news-done { text-align: center; font-family: var(--serif); }
.news-art :focus-visible { outline-color: #FFFFFF; }

/* An empty reviews band is a black stripe: it appears only once a visitor has
   accepted cookies and the widget has been let in. */
.reviews-band:not(:has([data-reviews]:not([hidden]))) { display: none; }
.news-art-media::after { background: rgba(0, 0, 0, .7); }


/* --- THE ARTIST --------------------------------------------------------------
   Statement on the left, his photograph on the right (the Louvre's "picture
   explore"); on a phone the words still come first. */
.intro-split { grid-template-columns: 60fr 40fr; align-items: center; }
.intro-text .prose { margin-top: 0; }
.intro-text .prose p { font-size: var(--t-lede); line-height: 1.6; max-width: 36rem; }
@media (max-width: 60rem) { .intro-split { grid-template-columns: minmax(0, 1fr); } .intro-text { order: 0; } }

/* --- THE REEL: ONE PHOTOGRAPH AT A TIME --------------------------------------
   Each slide is as wide as the frame, so nothing peeks in from the side. The
   photograph is whole (contain), as tall as the screen allows, and a thin line
   under it says how far through the reel you are. */
.reel { position: relative; }
.reel-track {
  display: flex; margin: 0; padding: 0; list-style: none;
  overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; overscroll-behavior-x: contain;
}
.reel-track::-webkit-scrollbar { display: none; }
.reel-track:focus-visible { outline: 1px solid currentColor; outline-offset: -6px; }
.reel-slide { flex: 0 0 100%; scroll-snap-align: center; display: flex; justify-content: center; align-items: center; height: min(74svh, 46rem); }
.reel-open { display: flex; justify-content: center; align-items: center; width: 100%; height: 100%; cursor: zoom-in; }
.reel-open img { display: block; max-width: 92%; max-height: 100%; width: auto; height: auto; object-fit: contain; }
.reel-bar { display: flex; align-items: center; gap: .75rem; margin: 1.25rem var(--gutter) 0; }
.reel-bar .reel-line { flex: 1; margin: 0 .75rem 0 0; }
.reel--one .reel-bar { display: none; }
.reel-btn {
  appearance: none; flex: none; width: 2.75rem; height: 2.75rem; border-radius: 50%; padding: 0;
  display: grid; place-items: center; cursor: pointer;
  background: transparent; color: inherit; border: 1px solid currentColor; opacity: .7;
  transition: opacity .2s var(--ease), background-color .2s var(--ease), color .2s var(--ease), transform .15s var(--ease);
}
.reel-btn svg { width: 1.1rem; height: 1.1rem; fill: none; stroke: currentColor; stroke-width: 1.6; }
.reel-btn:hover, .reel-btn:focus-visible { opacity: 1; }
.reel-btn:active { transform: scale(.94); }
.reel-line { height: 1px; margin: 1.25rem var(--gutter) 0; background: rgba(127, 127, 127, .35); }
.reel-line i { display: block; height: 100%; background: currentColor; transform: scaleX(0); transform-origin: left; transition: transform .45s var(--ease); }
.reel--one .reel-line { display: none; }
.reel-edge {
  position: absolute; top: 0; bottom: 2.5rem; width: min(14%, 7rem);
  appearance: none; background: none; border: 0; padding: 0; cursor: pointer;
}
.reel-edge--prev {
  left: 0;
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='44' height='44' viewBox='0 0 44 44'%3E%3Cpath d='M27 8 13 22l14 14' fill='none' stroke='%23888' stroke-width='2'/%3E%3C/svg%3E") 22 22, w-resize;
}
.reel-edge--next {
  right: 0;
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='44' height='44' viewBox='0 0 44 44'%3E%3Cpath d='M17 8l14 14-14 14' fill='none' stroke='%23888' stroke-width='2'/%3E%3C/svg%3E") 22 22, e-resize;
}
.reel-edge[hidden] { display: none; }
.band--slider { padding-bottom: clamp(2.5rem, 5vw, 4rem); }

/* the viewer, with nothing to say under a photograph */
.viewer-cap[hidden] { display: none; }

/* --- THE RECORD, IN TABS ----------------------------------------------------- */
.cv { max-width: none; }
.tab-list { display: flex; flex-wrap: wrap; gap: .25rem 2rem; margin-bottom: clamp(1.75rem, 3vw, 2.5rem); }
.tab-list[hidden] { display: none; }
[data-tabs-on] .tab-panel { display: none; }
[data-tabs-on] .tab-panel.is-active { display: block; }
[data-tabs-on] .tab-panel .cv-head { display: none; }
.tab-panel + .tab-panel { margin-top: clamp(2rem, 4vw, 3rem); }
[data-tabs-on] .tab-panel + .tab-panel { margin-top: 0; }
.band--ink .chip { color: var(--soft-on-dark, #D6D1C8); }
/* THE RECORD SITS ON INK NOW: its entries were set in --ink and vanished (26/10) */
.band--ink .cv-venue--solo, .band--ink .cv-name { color: #FFFFFF; }
.band--ink .cv-venue { color: #D6D1C8; }
.band--ink .cv-row { border-color: rgba(255, 255, 255, .16); }

/* THE PROCESS DRAWINGS ARE ICONS, NOT PICTURES (JP, 26/10): small, so they
   never compete with his own hand drawing above them. */
.nico-process-step .nico-process-icon { width: 6.5rem !important; max-width: 6.5rem !important; height: auto; margin: 0 auto 1rem; display: block; }
.nico-process-step h3 { font-size: clamp(22px, 1.9vw, 28px) !important; }

/* --- HERO + COLOUR BAND (every page but Home, JP 26/10) --- */
.opener.opener--band { display: block; min-height: 0; padding: 0; }
.opener--band .opener-text { max-width: min(46rem, 100%); padding-block: clamp(2.75rem, 5.5vw, 4.5rem); margin-top: 0; }
@media (max-width: 52rem) { .reel-slide { height: min(60svh, 32rem); } }
.band--ink .chip:hover, .band--ink .chip:focus-visible, .band--ink .chip[aria-pressed="true"],
.band--ink .chip[aria-selected="true"] { color: #FFFFFF; }
.chip[aria-selected="true"] { color: var(--ink); border-bottom-color: currentColor; }

/* --- ON FILM ---------------------------------------------------------------- */
.video { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: clamp(1.5rem, 3vw, 3rem); align-items: start; }
.video-stage { position: relative; aspect-ratio: 16 / 9; background: #0B0B0B; overflow: hidden; }
.video-play { position: absolute; inset: 0; display: block; }
.video-play img { display: block; width: 100%; height: 100%; object-fit: cover; }
.video-glyph {
  position: absolute; left: 50%; top: 50%; width: 4.75rem; height: 4.75rem; transform: translate(-50%, -50%);
  border: 1px solid #FFFFFF; border-radius: 50%; background: rgba(0, 0, 0, .35);
  transition: background-color .25s var(--ease), transform .35s var(--ease);
}
.video-glyph::after {
  content: ""; position: absolute; left: 53%; top: 50%; transform: translate(-50%, -50%);
  border-left: 1.05rem solid #FFFFFF; border-top: .65rem solid transparent; border-bottom: .65rem solid transparent;
}
.video-play:hover .video-glyph, .video-play:focus-visible .video-glyph { background: rgba(0, 0, 0, .6); transform: translate(-50%, -50%) scale(1.06); }
.video-stage iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.video-list { list-style: none; margin: 0; padding: 0; display: grid; gap: .25rem; }
.video-item {
  display: grid; grid-template-columns: 7rem minmax(0, 1fr); gap: 1rem; align-items: center;
  padding: .6rem 0; text-decoration: none; color: inherit; opacity: .62; border-bottom: 1px solid var(--rule);
  transition: opacity .25s var(--ease);
}
.video-item.is-on, .video-item:hover, .video-item:focus-visible { opacity: 1; }
.video-item img { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; }
.video-item-text { display: grid; gap: .2rem; }
.video-item-title { font-size: var(--t-meta); line-height: 1.35; }
.video-item-outlet { font-size: var(--t-label); letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft); }
@media (max-width: 60rem) { .video { grid-template-columns: minmax(0, 1fr); } }

.band--sent:not(:has(.sent:target)) { display: none; }

/* THE FOOTER KEEPS ONE COLOUR PER PAGE (JP, 24/10): the colour that used to turn
   with the page's bands is gone, and the footer was the last thing still doing it.
   Its ground is the page's own --foot-bg, still, and every pair stays 7:1 or more. */
.foot.foot { background-color: var(--foot-bg, var(--ink)); color: #FFFFFF; }

/* type on the part of the opener where the painting is still faintly there */
.opener-text { text-shadow: 0 1px 22px rgba(0, 0, 0, .32); }
.opener-go { text-shadow: none; }

/* A page that is not the front door opens shorter, and on a phone the painting
   above its heading stays a band, not a screen, so the work is one short scroll away. */
@media (max-width: 52rem) {
  .opener:not(.opener--tall) .opener-media { height: min(34svh, 15rem); }
  .opener:not(.opener--tall) .opener-text { margin-top: -3.25rem; }
}


/* --- SLICE 3: MOTION ---------------------------------------------------------
   Nico's own clips. Every one sits over a still that says the same thing (the
   clip's first frame, or the painting), so reduced motion, no scripting and a
   slow connection all get a finished page. Scripts: templates/_motion_js.html. */

/* A FILM IN A BAND: right-hand side, fading into the ground on the left the
   way the openers' paintings do; on a phone it sits on top and fades down. */
.band--film, .film-stage { position: relative; isolation: isolate; overflow: hidden; }
.film {
  position: absolute; inset: 0 0 0 auto; width: min(54%, 48rem); z-index: -1;
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 52%);
          mask-image: linear-gradient(to right, transparent 0, #000 52%);
}
.film-still, .film-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: var(--film-pos, center); }
.film-stage .film::after {
  content: ""; position: absolute; inset: auto 0 0 0; height: 24%;
  background: linear-gradient(to top, var(--ink), transparent);
}
.film-video, .news-art-video { opacity: 0; transition: opacity .8s var(--ease); }
.film-video.is-live, .news-art-video.is-live { opacity: 1; }
.band--film { display: flex; align-items: center; min-height: clamp(26rem, 62svh, 36rem); }
.band--film > .wrap { width: 100%; }
.band--film .wrap.center { text-align: left; }
.band--film .wrap > * { max-width: min(36rem, 52%); margin-inline: 0; }
.film-stage { min-height: clamp(20rem, 52svh, 30rem); display: flex; align-items: center; }
.film-stage .film-head { position: relative; margin-bottom: 0; padding-block: clamp(2rem, 5vw, 3.5rem); }

@media (max-width: 52rem) {
  .band--film { display: block; min-height: 0; padding-top: 0; }
  .film-stage { display: block; min-height: 0; }
  .film {
    position: relative; inset: auto; z-index: 0; width: 100%; height: min(54svh, 26rem);
    -webkit-mask-image: linear-gradient(to bottom, #000 52%, transparent 100%);
            mask-image: linear-gradient(to bottom, #000 52%, transparent 100%);
  }
  .band--film .wrap > * { max-width: none; }
  .band--film .wrap { margin-top: -3.5rem; position: relative; }
  .film-stage .film-head { margin-top: -3.5rem; }
}

/* THE PARALLAX (Home's sign-up band). The clip lives in a fixed layer and the
   band is a window onto it: `clip-path` clips fixed descendants where
   `overflow` does not, and, unlike `background-attachment: fixed`, it works on
   iPhones. One parallax on the site. */
.news-art--motion { overflow: visible; clip-path: inset(0); }
.news-art--motion .news-art-media {
  position: fixed; top: 0; left: 0; right: auto; bottom: auto;
  width: 100%; height: 100vh; height: 100lvh;
}
.news-art-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

/* THE LINE DRAWS ITSELF (Commissions, "The process"). Pinned beside the words
   while the scroll plays his hand drawing; off a desktop it is a still or a loop. */
.draw-pin { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: clamp(2rem, 5vw, 5rem); align-items: center; }
.draw-text .section-head { margin-bottom: 1.5rem; }
.draw-text .h2, .draw-text .prose--fit { text-align: left; }
.draw-text .prose--fit p { margin-inline: 0; }
.draw-fig { position: relative; margin: 0; aspect-ratio: 3 / 4; max-height: 78svh; justify-self: center; width: min(100%, 36rem); background: #FFFFFF; }
.draw-still, .draw-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.draw-video { opacity: 0; transition: opacity .5s var(--ease); }
.draw-video.is-live { opacity: 1; }
.draw-scene.is-scrub { height: 260vh; }
.draw-scene.is-scrub .draw-pin { position: sticky; top: 0; height: 100vh; height: 100svh; }
@media (max-width: 52rem) {
  .draw-pin { grid-template-columns: minmax(0, 1fr); }
  .draw-fig { width: min(100%, 24rem); max-height: 62svh; }
}

@media (prefers-reduced-motion: reduce) {
  .news-art--motion { clip-path: none; overflow: hidden; }
  .news-art--motion .news-art-media { position: absolute; inset: 0; width: auto; height: auto; }
  .news-art-video, .film-video, .draw-video { display: none; }
}

/* =============================================================================
   WORK BY PLACE (JP, 26/10). "In collections" first, then the cities, fullest
   first; each opens on its own colour band (the city palettes of 22/09, every
   frame 7:1 for white type). The bar under the masthead follows the page. */
html:has(.placebar) { scroll-padding-top: 8.25rem; }
.placebar {
  position: sticky; top: var(--placebar-top, 3.9rem); z-index: 90;
  background: rgba(244, 241, 234, .94);
  -webkit-backdrop-filter: blur(12px) saturate(120%); backdrop-filter: blur(12px) saturate(120%);
  border-bottom: 1px solid var(--rule);
}
.placebar-in { position: relative; display: flex; align-items: center; gap: 1.5rem; min-height: 3.5rem; }
.placebar-places {
  display: flex; gap: 1.75rem; margin: 0; padding: 0; list-style: none; flex: 1; min-width: 0;
  overflow-x: auto; scrollbar-width: none; -webkit-mask-image: linear-gradient(to right, #000 90%, transparent);
          mask-image: linear-gradient(to right, #000 90%, transparent);
}
.placebar-places::-webkit-scrollbar { display: none; }
.placebar-places a {
  display: block; padding-block: 1.15rem; white-space: nowrap; text-decoration: none; color: var(--ink-soft);
  font: 400 var(--t-nav)/1 var(--sans); letter-spacing: .08em; text-transform: uppercase;
  transition: color .25s var(--ease);
}
.placebar-places a:hover, .placebar-places a.is-here { color: var(--ink); }
.placebar-mark {
  position: absolute; left: 0; bottom: -1px; height: 2px; width: 0; background: var(--ink);
  opacity: 0; pointer-events: none;
  transition: transform .45s cubic-bezier(.22, 1, .36, 1), width .45s cubic-bezier(.22, 1, .36, 1), opacity .25s;
}
.typemenu { position: relative; display: flex; align-items: center; gap: .5rem; flex: none; }
.typemenu[hidden] { display: none; }
.typemenu-btn {
  appearance: none; display: inline-flex; align-items: center; gap: .55rem; cursor: pointer;
  background: transparent; color: var(--ink); border: 1px solid var(--rule); border-radius: 999px;
  padding: .6rem 1rem .6rem 1.15rem; font: 400 var(--t-nav)/1 var(--sans); letter-spacing: .08em; text-transform: uppercase;
  transition: border-color .2s var(--ease), background-color .2s var(--ease);
}
.typemenu-btn:hover, .typemenu.is-open .typemenu-btn { border-color: var(--ink); }
.typemenu-k { color: var(--ink-soft); }
.typemenu-btn svg { width: 1rem; height: 1rem; fill: none; stroke: currentColor; stroke-width: 1.6; transition: transform .3s cubic-bezier(.22, 1, .36, 1); }
.typemenu.is-open .typemenu-btn svg { transform: rotate(180deg); }
.typemenu-list {
  position: absolute; right: 0; top: calc(100% + .5rem); min-width: 14rem; margin: 0; padding: .4rem; list-style: none;
  background: var(--paper); border: 1px solid var(--rule); border-radius: .75rem;
  box-shadow: 0 18px 40px rgba(11, 11, 11, .14);
  opacity: 0; transform: translateY(-4px) scale(.97); transform-origin: top right; pointer-events: none;
  transition: opacity .18s ease, transform .22s cubic-bezier(.22, 1, .36, 1);
}
.typemenu.is-open .typemenu-list { opacity: 1; transform: none; pointer-events: auto; }
.typemenu-list [role=option] {
  position: relative; padding: .75rem 2.25rem .75rem .9rem; border-radius: .5rem; cursor: pointer;
  font: 400 1rem/1.2 var(--sans); color: var(--ink); outline: none;
  transition: background-color .15s ease;
}
.typemenu-list [role=option]:hover, .typemenu-list [role=option]:focus-visible { background: rgba(11, 11, 11, .06); }
.typemenu-list [aria-selected=true]::after {
  content: ""; position: absolute; right: .9rem; top: 50%; width: .45rem; height: .8rem; margin-top: -.5rem;
  border: solid var(--ink); border-width: 0 1.5px 1.5px 0; transform: rotate(45deg);
}
.typemenu-clear {
  appearance: none; cursor: pointer; border: 0; border-radius: 999px; padding: .55rem .9rem;
  background: var(--ink); color: var(--paper); font: 400 var(--t-nav)/1 var(--sans); letter-spacing: .06em; text-transform: uppercase;
  animation: chip-in .3s cubic-bezier(.22, 1, .36, 1);
}
.typemenu-clear[hidden] { display: none; }
@keyframes chip-in { from { opacity: 0; transform: scale(.85); } }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

.place-band { color: #FFFFFF; background: #0B0B0B; }
.place-band-in { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem 2rem; flex-wrap: wrap;
  padding-block: clamp(2.5rem, 6vw, 4.5rem); }
.place-name { margin: 0; color: #FFFFFF; font-family: var(--display-face, var(--serif)); font-weight: 400;
  font-size: clamp(2.5rem, 1rem + 5vw, 5rem); line-height: 1.05; letter-spacing: .06em; text-transform: uppercase; }
.place-pdf { color: #FFFFFF; font: 400 var(--t-nav)/1.4 var(--sans); letter-spacing: .08em; text-transform: uppercase;
  text-decoration: none; border-bottom: 1px solid rgba(255, 255, 255, .6); }
.place-body.band { padding-top: clamp(2.5rem, 5vw, 4rem); }
.place-none { color: var(--ink-soft); margin: 0; }
.place.is-empty .place-body.band { padding-block: 1.5rem 2.5rem; }
.place.is-empty .place-band-in { padding-block: clamp(1.75rem, 3.5vw, 2.5rem); }
.place.is-empty .place-name { font-size: clamp(1.75rem, 1rem + 2.5vw, 2.75rem); opacity: .75; }
.place-name { transition: font-size .35s cubic-bezier(.22, 1, .36, 1), opacity .35s; }
/* filtering: the works settle in rather than jump */
@media (prefers-reduced-motion: no-preference) {
  .is-turning [data-hang] > .work:not([hidden]) { animation: work-in .4s cubic-bezier(.22, 1, .36, 1) both; }
}
@keyframes work-in { from { opacity: 0; transform: translateY(10px) scale(.985); } }

@media (max-width: 52rem) {
  .placebar { top: var(--placebar-top, 3.6rem); }
  .placebar-in { gap: .75rem; min-height: 3.25rem; }
  .placebar-places { gap: 1.25rem; }
  .typemenu-k { display: none; }
  .typemenu-btn { padding: .5rem .8rem .5rem .9rem; }
  .typemenu-clear { display: none !important; }
  .typemenu.is-set .typemenu-btn { background: var(--ink); color: var(--paper); border-color: var(--ink); }
}
/* the band already names the place, so the caption does not repeat it (the
   viewer still reads it from the markup) */
.place .cm-place { display: none; }
@media (max-width: 52rem) {
  .typemenu-v { max-width: 7.5rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}

/* --- 26/10 ROUND --------------------------------------------------------------
   Work and Artist: the hero alone, taller, as on the live site's best pages. */
.hero-big .hero-figure { margin-bottom: 0; }
.hero-big .hero-figure img { height: min(46rem, calc(100svh - 4.5rem)); }
@media (max-width: 34rem) { .hero-big .hero-figure img { height: min(66svh, 30rem); } }
.intro-title { margin: 0 0 1.5rem; text-wrap: balance; }

/* Commissions: the colour band centred, on its live palette (encargos-cycle,
   worst frame 7.31:1), and the process centred with no clip beside it. */
.opener--center .opener-text { margin-inline: auto; text-align: center; }
.opener--center .opener-line { margin-inline: auto; }
.opener--encargos { --op-1: #724E00; background-color: #724E00; }
@media (prefers-reduced-motion: no-preference) {
  .opener--encargos { animation: encargos-cycle 12s linear infinite; }
}
.process-head { max-width: 44rem; margin: 0 auto; text-align: center; }
.process-head .section-head, .process-head .h2 { text-align: center; }
.process-head .prose { margin-inline: auto; text-align: center; }

/* Work: a city opens on its photograph, fading to black on the left. */
.place-band { position: relative; isolation: isolate; overflow: hidden; }
.place-band--photo { min-height: clamp(16rem, 34vw, 26rem); display: flex; align-items: center; }
.place-band--photo .place-band-in { position: relative; z-index: 1; width: 100%; }
.place-photo {
  position: absolute; inset: 0 0 0 auto; width: 72%; z-index: 0;
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 46%);
          mask-image: linear-gradient(to right, transparent 0, #000 46%);
}
.place-photo img { width: 100%; height: 100%; object-fit: cover; object-position: center; display: block; }
.place-credit { position: absolute; right: var(--gutter); bottom: .6rem; margin: 0; z-index: 1;
  font: 400 .75rem/1.3 var(--sans); color: rgba(255,255,255,.8); text-shadow: 0 1px 2px rgba(0,0,0,.6); }
.place-credit a { color: inherit; }
@media (max-width: 52rem) {
  .place-band--photo { display: block; min-height: 0; }
  .place-photo { position: relative; width: 100%; height: 13rem;
    -webkit-mask-image: linear-gradient(to bottom, #000 45%, transparent);
            mask-image: linear-gradient(to bottom, #000 45%, transparent); }
  .place-band--photo .place-band-in { margin-top: -3.5rem; padding-top: 0; }
  .place-credit { top: 10.5rem; bottom: auto; }
}
.place.is-empty .place-photo { display: none; }
.place.is-empty .place-band--photo { min-height: 0; }
.place.is-empty .place-band--photo .place-band-in { margin-top: 0; padding-top: clamp(1.75rem, 3.5vw, 2.5rem); }

/* Artist: In his hands, four upright clips */
.reveal-strip { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: clamp(.75rem, 1.6vw, 1.5rem); }
.reveal-card { position: relative; aspect-ratio: 9 / 16; overflow: hidden; border-radius: 4px; background: #151515; }
.reveal-card img, .reveal-card video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.reveal-video { opacity: 0; transition: opacity .6s var(--ease); }
.reveal-video.is-live { opacity: 1; }
@media (max-width: 52rem) {
  .reveal-strip { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none;
    margin-inline: calc(-1 * var(--gutter)); padding-inline: var(--gutter); scroll-padding-inline: var(--gutter); }
  .reveal-strip::-webkit-scrollbar { display: none; }
  .reveal-card { flex: 0 0 68%; scroll-snap-align: start; }
}
@media (prefers-reduced-motion: reduce) { .reveal-video { display: none; } }
/* softer, longer fade from the city photograph into the black */
@media (min-width: 52.01rem) {
  .place-photo { width: 86%;
    -webkit-mask-image: linear-gradient(to right, transparent 0, rgba(0,0,0,.35) 30%, #000 62%);
            mask-image: linear-gradient(to right, transparent 0, rgba(0,0,0,.35) 30%, #000 62%); }
}
.opener.opener--center .display, .opener.opener--center .opener-line { text-align: center; margin-inline: auto; }
.opener.opener--center .opener-text { max-width: min(52rem, 100%); }
/* with the place hidden, the span before it ends the line: no trailing dot */
.place .work .cap-meta span:has(+ .cm-place:last-child)::after { content: none; }
/* the catalogue link sits under the city's name */
.place-title { display: flex; flex-direction: column; align-items: flex-start; gap: 1.1rem; }
.place-band-in { flex-direction: column; align-items: flex-start; }

/* =============================================================================
   26/10, HOME: eight works, ONE column and big, on white; then the bands
   alternate again (white, black, white, then reviews and sign-up on black).
   On a phone every block reads title and text FIRST, then its picture. */
.band--selection .wrap::after { content: none; }
.masonry { columns: 1; column-gap: 0; }
.masonry .work { margin-bottom: clamp(3rem, 7vw, 5.5rem); text-align: center; }
.masonry .plate img { width: auto; max-width: 100%; max-height: min(88svh, 62rem); height: auto; margin-inline: auto; display: block; }
.masonry .cap { text-align: center; }
.masonry .cap-title { color: var(--ink); }
.masonry .cap-meta { justify-content: center; }
.masonry-foot { text-align: center; }
@media (max-width: 52rem) {
  .masonry { columns: 1; }
  .home-split-text { order: 1; }
  .home-split-fig { order: 2; }
  .home-split--flip .home-split-fig { order: 2; }
  .intro-text { order: 1; }
  .intro-portrait { order: 2; }
}

/* =============================================================================
   26/10, THE WORK BAR, AGAIN: black, hidden until the reader has passed "In
   collections", then it slides down under the white menu. A white Filter
   button on the right says what it is for. */
html:has(.placebar) { scroll-padding-top: 7.5rem; }
.placebar {
  position: fixed; left: 0; right: 0; top: var(--placebar-top, 4rem); z-index: 90;
  background: rgba(11, 11, 11, .92); color: #FFFFFF; border-bottom: 1px solid rgba(255, 255, 255, .14);
  -webkit-backdrop-filter: blur(12px) saturate(120%); backdrop-filter: blur(12px) saturate(120%);
  transform: translateY(-110%); opacity: 0; pointer-events: none; visibility: hidden;
  transition: transform .45s cubic-bezier(.22, 1, .36, 1), opacity .3s ease, visibility 0s linear .45s;
}
.placebar[hidden] { display: none; }
.placebar.is-on { transform: none; opacity: 1; pointer-events: auto; visibility: visible; transition-delay: 0s; }
.placebar-places a { color: rgba(255, 255, 255, .72); }
.placebar-places a:hover, .placebar-places a.is-here { color: #FFFFFF; }
.placebar-mark { background: #FFFFFF; }
.placebar-places { -webkit-mask-image: none; mask-image: none; overflow: visible; }
.citybtn { display: none; }

.typemenu-btn {
  background: #FFFFFF; color: #0B0B0B; border: 1px solid #FFFFFF; font-weight: 500;
  padding: .65rem 1rem .65rem 1rem; gap: .6rem;
}
.typemenu-btn:hover, .typemenu.is-open .typemenu-btn { background: #F1EEE6; border-color: #F1EEE6; }
.typemenu-ico { width: 1.15rem; height: 1.15rem; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; }
.typemenu-k { color: #0B0B0B; font-weight: 500; }
.typemenu-v { color: #0B0B0B; opacity: .62; font-weight: 400; }
.typemenu-chev { width: 1rem; height: 1rem; fill: none; stroke: currentColor; stroke-width: 1.6; transition: transform .3s cubic-bezier(.22, 1, .36, 1); }
.typemenu.is-open .typemenu-chev { transform: rotate(180deg); }
.typemenu-btn svg:not(.typemenu-ico):not(.typemenu-chev) { display: none; }
.typemenu.is-set .typemenu-v { opacity: 1; }
.typemenu-list { right: 0; left: auto; }
/* one soft pulse the first time the bar arrives, so the eye goes to Filter */
@media (prefers-reduced-motion: no-preference) {
  .placebar.is-first .typemenu-btn { animation: filter-pulse 1.1s ease-out 0.5s 2; }
}
@keyframes filter-pulse { 0% { box-shadow: 0 0 0 0 rgba(255, 255, 255, .65); } 80%, 100% { box-shadow: 0 0 0 .9rem rgba(255, 255, 255, 0); } }

@media (max-width: 52rem) {
  .placebar { top: var(--placebar-top, 3.6rem); }
  .placebar-in { gap: .75rem; justify-content: space-between; min-height: 3.5rem; }
  .citybtn {
    display: inline-flex; align-items: center; gap: .5rem; appearance: none; cursor: pointer;
    background: transparent; color: #FFFFFF; border: 1px solid rgba(255, 255, 255, .4); border-radius: 999px;
    padding: .55rem .85rem .55rem 1rem; font: 400 var(--t-nav)/1 var(--sans); letter-spacing: .08em; text-transform: uppercase;
    max-width: 55%;
  }
  .citybtn-k { color: rgba(255, 255, 255, .6); }
  .citybtn-v { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .citybtn svg { width: 1rem; height: 1rem; fill: none; stroke: currentColor; stroke-width: 1.6; flex: none; transition: transform .3s; }
  .placebar.is-cities .citybtn svg { transform: rotate(180deg); }
  .placebar-mark { display: none; }
  .placebar-places {
    position: absolute; left: var(--gutter, 1rem); top: calc(100% + .4rem); flex-direction: column; gap: 0; min-width: 14rem;
    background: #0B0B0B; border: 1px solid rgba(255, 255, 255, .2); border-radius: .75rem; padding: .4rem;
    box-shadow: 0 18px 40px rgba(0, 0, 0, .45);
    opacity: 0; transform: translateY(-4px) scale(.97); transform-origin: top left; pointer-events: none; visibility: hidden;
    transition: opacity .18s ease, transform .22s cubic-bezier(.22, 1, .36, 1), visibility 0s linear .22s;
  }
  .placebar.is-cities .placebar-places { opacity: 1; transform: none; pointer-events: auto; visibility: visible; transition-delay: 0s; }
  .placebar-places a { padding: .85rem .9rem; border-radius: .5rem; }
  .placebar-places a.is-here { background: rgba(255, 255, 255, .1); }
  .typemenu-btn, .typemenu.is-set .typemenu-btn { background: #FFFFFF; color: #0B0B0B; border-color: #FFFFFF; }
  .typemenu-k { display: inline; }
  .typemenu-v { max-width: 5.5rem; }
  .typemenu-list { background: #FFFFFF; }
}
.typemenu-list { background: #FFFFFF; border-color: #FFFFFF; }
.typemenu-list [role=option] { color: #0B0B0B; }
.typemenu-list [role=option]:hover, .typemenu-list [role=option]:focus-visible { background: rgba(11, 11, 11, .07); }
.typemenu-list [aria-selected=true]::after { border-color: #0B0B0B; }
.typemenu-clear { display: none !important; }

/* the reel's film slides: upright, as tall as a photograph slide */
.reel-slide--clip { justify-content: center; }
.reel-clip { display: block; height: 100%; width: auto; max-width: 92%; aspect-ratio: 9 / 16; object-fit: cover; border-radius: 3px; background: #151515; }

/* =============================================================================
   THE RECORD'S TABS READ AS BUTTONS (JP, 26/10: on a phone they looked like
   the text around them). Rounded, outlined; the chosen one is filled. On a
   phone they sit in one row you swipe, the last one cut by the edge so it is
   plain there is more. */
.tab-list .chip {
  appearance: none; cursor: pointer; border: 1px solid rgba(255, 255, 255, .45); border-bottom-width: 1px;
  border-radius: 999px; padding: .7rem 1.25rem; background: transparent; color: #FFFFFF;
  font: 400 var(--t-nav)/1 var(--sans); letter-spacing: .06em; text-transform: uppercase; white-space: nowrap;
  transition: background-color .2s var(--ease), color .2s var(--ease), border-color .2s var(--ease);
}
.tab-list .chip:hover, .tab-list .chip:focus-visible { border-color: #FFFFFF; }
.tab-list .chip[aria-selected="true"] { background: #FFFFFF; color: #0B0B0B; border-color: #FFFFFF; font-weight: 500; }
.tab-list { gap: .6rem; }
@media (max-width: 52rem) {
  .tab-list { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; scroll-snap-type: x proximity;
    margin-inline: calc(-1 * var(--gutter)); padding-inline: var(--gutter); scroll-padding-inline: var(--gutter);
    -webkit-mask-image: linear-gradient(to right, #000 88%, transparent); mask-image: linear-gradient(to right, #000 88%, transparent); }
  .tab-list::-webkit-scrollbar { display: none; }
  .tab-list .chip { scroll-snap-align: start; flex: none; }
}

/* the colour bands keep air on every side on a phone, and read title, line, link */
@media (max-width: 52rem) {
  .opener.opener--band .opener-text { padding-block: 2.5rem 2.75rem; }
  .opener.opener--band .wrap { padding-inline: var(--gutter, 1.25rem); }
}

/* WHO BUILT IT: the HagoDigital mark itself (SVG, white, vector), a signature on
   the back of the frame -- smaller than Nico's own, last line of the footer. */
.foot-credit { display: inline-flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.foot-credit-logo { display: inline-flex; align-items: center; border: 0; }
.foot-credit-logo img { display: block; height: 1.9rem; width: auto; opacity: .95; }
.foot-credit-logo:hover img, .foot-credit-logo:focus-visible img { opacity: 1; }

/* A card can never be wider than its column (the Panamá canvas overflowed a
   two-across phone, its photograph and title cut off at the left edge). */
.hang > .work, .masonry > .work { min-width: 0; max-width: 100%; }
.work > a { min-width: 0; max-width: 100%; }
.work .plate { max-width: 100%; min-width: 0; }
.work .cap-title { overflow-wrap: anywhere; }
.work .cap-meta { overflow-wrap: anywhere; }
.work .cap-meta span { white-space: normal; }
.work > a { grid-template-columns: minmax(0, 1fr); }

/* Commissions: the band under the hero is a parallax window onto the big canvas */
.opener-par .news-art-inner { text-align: center; }
.opener-par .display { color: #FFFFFF; margin: 0 auto; max-width: 52rem; text-wrap: balance;
  font-size: clamp(1.9rem, 1rem + 3.4vw, 3.6rem); }
.opener-par .news-art-line { margin: 1.25rem auto 0; max-width: 34rem; }
.opener-par .opener-go { margin-top: 2rem; }
@media (max-width: 52rem) { .opener-par { padding-block: 4rem; } }
main .opener-par .display, main .opener-par .news-art-line { text-align: center; }

/* HOME, 26/10 (later): back to THREE ACROSS, six works, as on the live site --
   one work per column, standing on a shared baseline. Two across on a phone. */
.masonry { columns: auto; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: end;
  gap: clamp(2rem, 4vw, 3.5rem) clamp(1.25rem, 2.4vw, 2.25rem); }
.masonry .work { margin-bottom: 0; text-align: center; min-width: 0; }
.masonry .plate img { width: 100%; max-width: 100%; max-height: none; height: auto; }
.masonry-foot { margin-top: clamp(2.5rem, 5vw, 4rem); }
@media (max-width: 52rem) { .masonry { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.reviews-ask { margin: 1.5rem 0 0; }
.reviews-ask[hidden] { display: none; }
.reviews-ask .opener-go { background: transparent; cursor: pointer; font-family: var(--sans); }

/* THE PROCESS ICONS AT HAGODIGITAL.AI'S SIZE (JP, 26/10): its step icons are
   120px squares with air inside them; these drawings fill their own box, so
   they are held to 84px tall to read the same. */
/* between the 84px of 26/10 and the 146px before it (JP, 26/10, later) */
.nico-process-step .nico-process-icon { width: auto !important; max-width: none !important; height: 7.2rem !important; }
@media (max-width: 640px) { .nico-process-step .nico-process-icon { height: 6.25rem !important; } }
/* the Commissions parallax opens the page: hero height */
/* every page's hero the height of Home's (JP, 27/10: "too massive") */
.opener-par--encargos { min-height: min(46rem, calc(100svh - 4.5rem)); display: flex; align-items: center; }
.opener-par--encargos .news-art-inner { width: 100%; }
.band--process + .hero-figure, .band--process + figure.bleed { margin-bottom: 0; }

/* ARTIST, the record over the openings' photographs (JP, 26/10) */
.record-art { position: relative; isolation: isolate; overflow: hidden; }
.record-photos { position: absolute; inset: 0 0 0 auto; width: 58%; z-index: -1;
  -webkit-mask-image: linear-gradient(to right, transparent 0, rgba(0,0,0,.5) 30%, #000 70%);
          mask-image: linear-gradient(to right, transparent 0, rgba(0,0,0,.5) 30%, #000 70%); }
.record-photos::after { content: ""; position: absolute; inset: 0; background: rgba(0,0,0,.35); }
.record-photos img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity 1.6s ease; }
.record-photos img.is-on { opacity: 1; }
.record-wrap { position: relative; }
.record-art .cv { max-width: min(44rem, 56%); }
.record-art .section-head { max-width: 56%; }
@media (max-width: 52rem) {
  .record-photos { position: relative; inset: auto; width: auto; height: 16rem; margin: calc(-1 * var(--section-pad)) 0 0;
    -webkit-mask-image: linear-gradient(to bottom, #000 40%, transparent); mask-image: linear-gradient(to bottom, #000 40%, transparent); }
  .record-art .cv, .record-art .section-head { max-width: none; }
  .record-art .record-wrap { margin-top: -3rem; }
}

.record-photos video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity 1.2s ease; }
.record-photos video.is-on { opacity: 1; }
/* Home's way in to Commissions, same move */
.door-art { min-height: min(72svh, 42rem); display: flex; align-items: center; }
.door-art .record-wrap { width: 100%; }
.door-art .door-head { max-width: min(36rem, 46%); margin-bottom: 0; }
.door-art .record-photos img { transition-duration: 1s; }
@media (max-width: 52rem) {
  .door-art { display: block; min-height: 0; }
  .door-art .record-photos { height: 24rem; }
  .door-art .door-head { max-width: none; }
}

/* Home's rooms: a shorter fade, so a painting near the left edge still reads */
.door-art .record-photos { width: 60%;
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 28%); mask-image: linear-gradient(to right, transparent 0, #000 28%); }
@media (max-width: 52rem) {
  .door-art .record-photos { width: auto;
    -webkit-mask-image: linear-gradient(to bottom, #000 55%, transparent); mask-image: linear-gradient(to bottom, #000 55%, transparent); }
}

/* Home hero: his sentence in quotes and italics, who he is under it (JP, 26/10) */
.opener-line--quote { font-family: var(--serif, inherit); font-style: italic; font-size: clamp(1.25rem, 1.6vw, 1.6rem); line-height: 1.35; }
.opener-sub { margin: .6rem 0 0; max-width: 30rem; color: rgba(255, 255, 255, .78);
  font: 300 var(--t-body, 1rem)/1.5 var(--sans); }
/* Artist: his sentence as a pull quote, not a capitals title; the portrait smaller */
.intro-title--quote { text-transform: none; font-style: italic; letter-spacing: 0;
  font-size: clamp(1.5rem, 2.3vw, 2.2rem); line-height: 1.25; }
.band--statement-text .intro-split { grid-template-columns: 64fr 36fr; }
.band--statement-text .intro-portrait { max-width: 22rem; justify-self: center; }
@media (max-width: 60rem) { .band--statement-text .intro-split { grid-template-columns: minmax(0, 1fr); } .band--statement-text .intro-portrait { max-width: 16rem; } }

/* Home, the Artist section: his sentence in italics under the heading */
.home-quote { margin: 1.25rem 0 0; font-family: var(--serif); font-style: italic; font-size: clamp(1.35rem, 1.9vw, 1.85rem); line-height: 1.3; text-wrap: balance; }
.home-quote + .lede { margin-top: 1.25rem; }

/* WORK PAGE (JP, 26/10): status, then the city on its own line; thin arrows at
   the painting's sides walk its band on a desktop, a swipe does on a phone */
.spec .state + .state-where--line { display: block; margin: .3rem 0 0; }
.work-figure--alone { position: relative; }
.work-step { position: absolute; top: 50%; transform: translateY(-50%); width: 2.75rem; height: 5.5rem;
  display: flex; align-items: center; justify-content: center; color: var(--ink, #111); opacity: .45; transition: opacity .2s ease; }
.work-step:hover, .work-step:focus-visible { opacity: 1; }
.work-step svg { width: 1.1rem; height: 2.2rem; fill: none; stroke: currentColor; stroke-width: 1.25; }
.work-step--prev { left: -3.75rem; }
.work-step--next { right: -3.75rem; }
@media (min-width: 52.01rem) { .work-figure--steps { max-width: min(68rem, calc(100% - 7.5rem)); } }
@media (max-width: 52rem) { .work-step { display: none; } }

/* the HagoDigital mark, quieter: smaller and a touch dimmer (JP, 26/10) */
.foot-credit-logo img { height: 1.3rem; opacity: .8; }
.band--film .split-rule { max-width: min(36rem, 50%); grid-template-columns: minmax(0, 1fr); gap: 1.25rem; }
.band--film .split-rule-body { border-left: 0; padding-left: 0; }
@media (max-width: 52rem) { .band--film .split-rule { max-width: none; } }

/* =============================================================================
   THE FILMSTRIP (JP, 26/10): every carousel is one row of photographs at ONE
   height, each at its own width (nothing cropped), the next one showing at
   the edge, on the paper ground. Swipe, drag, the arrows or the keys move it. */
.reel-track { gap: clamp(.75rem, 1.4vw, 1.25rem); padding-inline: var(--gutter, clamp(1.25rem, 3vw, 3rem)); scroll-padding-inline: var(--gutter, clamp(1.25rem, 3vw, 3rem)); scroll-snap-type: x proximity; }
.reel-slide { flex: 0 0 auto; height: clamp(17rem, 58svh, 34rem); scroll-snap-align: start; }
.reel-open { width: auto; height: 100%; }
.reel-open img { max-width: none; max-height: none; height: 100%; width: auto; }
.reel-slide--clip { width: auto; }
.reel-clip { height: 100%; width: auto; max-width: none; }
.reel-edge { display: none !important; }
@media (max-width: 52rem) { .reel-slide { height: clamp(15rem, 52svh, 26rem); } }
/* carousels sit on white now */
.band--slider { background: var(--paper); color: var(--ink); }
.band--slider .h2 { color: var(--ink); }
.band--slider .reel-btn { color: var(--ink); }
.door-head { max-width: 40rem; margin-bottom: clamp(2rem, 4vw, 3rem); }
.door-head .lede { margin-top: 1.25rem; }
.door-head .section-foot { margin-top: 1.75rem; }
.band--door .reel-btn { color: #FFFFFF; }
.reviews-ask { display: flex; flex-wrap: wrap; align-items: center; gap: 1.25rem 2rem; }

/* THE CAROUSEL (templates/_carousel.html): centred, neighbours stepped back and
   dimmed, the photograph inside each frame on a parallax, a wipe on first view.
   The script writes each slide's scale, its --dim and its image offset from the
   scroll position. */
.band--car .section-head { margin-bottom: clamp(1.5rem, 3vw, 2.5rem); }
.band--car-tight { padding-top: 0; }
.car-track {
  display: flex; align-items: center; gap: clamp(.5rem, 1.4vw, 1.25rem);
  overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x mandatory;
  padding: clamp(1rem, 2vw, 1.75rem) 0; scrollbar-width: none; cursor: grab;
}
.car-track::-webkit-scrollbar { display: none; }
.car-track.is-dragging { cursor: grabbing; scroll-snap-type: none; }
.car-track:focus-visible { outline: 2px solid currentColor; outline-offset: 4px; }
.car-slide { flex: none; margin: 0; scroll-snap-align: center; transform-origin: 50% 50%; will-change: transform; }
.car-open { display: block; }
.car-slide.is-current .car-open { cursor: zoom-in; }
/* each frame keeps its photograph's own shape, as tall as the screen allows and
   never wider than 80% of it, so a wide mural is not cropped to a portrait */
.car-frame { --h: min(clamp(20rem, 70vh, 50rem), calc(80vw / var(--r, 1)));
  position: relative; display: block; overflow: hidden; height: var(--h); width: calc(var(--h) * var(--r, 1)); }
.car-frame img {
  display: block; height: 100%; width: 100%; object-fit: cover;
  user-select: none; -webkit-user-drag: none; transform: scale(1.2); will-change: transform;
}
.car-frame::after { content: ''; position: absolute; inset: 0; background: #050505; opacity: var(--dim, 0); pointer-events: none; }
html:not(.js) .car-frame img { transform: none; }
/* the wipe: each frame opens upwards, the centre first */
.car--wait .car-frame { clip-path: inset(100% 0 0 0); transition: clip-path 1.1s cubic-bezier(.77, 0, .18, 1) var(--wait, 0s); }
.car--wait .car-frame img { transition: scale 1.6s cubic-bezier(.22, .61, .36, 1) var(--wait, 0s); scale: 1.25; }
.car--wait.is-in .car-frame { clip-path: inset(0 0 0 0); }
.car--wait.is-in .car-frame img { scale: 1; }
.car-bar { display: flex; align-items: center; justify-content: space-between; margin-top: clamp(1rem, 2vw, 1.5rem); }
.car-count { margin: 0; font-family: var(--serif); font-size: clamp(1.5rem, 1.1rem + 1.2vw, 2.25rem); line-height: 1; font-variant-numeric: tabular-nums; }
.car-of { opacity: .5; }
.car-nav { display: flex; gap: .75rem; }
.car-btn {
  width: 3rem; height: 3rem; border-radius: 50%; border: 1px solid currentColor; background: transparent; color: inherit;
  display: grid; place-items: center; cursor: pointer; transition: background-color .25s ease, color .25s ease;
}
.car-btn svg { width: 1.1rem; height: 1.1rem; fill: none; stroke: currentColor; stroke-width: 1.5; }
.band--ink .car-btn:hover { background: var(--paper); color: var(--ink); }
.band--paper .car-btn:hover { background: var(--ink); color: var(--paper); }
.car-btn:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }
html:not(.js) .car-bar { display: none; }
@media (max-width: 48rem) {
  .car-frame { --h: min(clamp(16rem, 58svh, 30rem), calc(84vw / var(--r, 1))); }
}
/* the carousel's head, centred (JP, 26/10); specific enough to beat the bands' left-set wraps */
.band .wrap.section-head--centre, .band .wrap.section-head--centre > * { text-align: center; }
.band .wrap.section-head--centre .group-sub { margin-inline: auto; }

/* THE MOSAIC (templates/_mosaic.html): a justified wall, every row one height,
   each photograph its own shape; the open photograph on a dark stage. */
.band--mosaic .section-head { margin-bottom: clamp(1.5rem, 3vw, 2.5rem); }
.mosaic { display: flex; flex-wrap: wrap; gap: clamp(.35rem, .6vw, .6rem); max-width: 82rem; margin: 0 auto; padding: 0 var(--gutter); }
.mosaic::after { content: ''; flex-grow: 999; }
.mosaic-tile { --row: clamp(7rem, 15vw, 12.5rem); flex-grow: calc(var(--r) * 100); width: calc(var(--r) * var(--row)); height: var(--row);
  position: relative; overflow: hidden; background: #e2ddd3; cursor: zoom-in; }
.mosaic-tile img { display: block; width: 100%; height: 100%; object-fit: cover;
  transition: transform .9s cubic-bezier(.22, .61, .36, 1), filter .5s ease, opacity .3s ease; }
@media (hover: hover) {
  .mosaic:hover .mosaic-tile img { filter: brightness(.55) saturate(.75); }
  .mosaic .mosaic-tile:hover img { filter: none; transform: scale(1.05); }
}
.mosaic-tile:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.mosaic-tile.is-out img { opacity: 0; transition: none; }
.mosaic-lb { position: fixed; inset: 0; z-index: 200; }
.mosaic-lb[hidden] { display: none; }
.mosaic-lb-bg { position: absolute; inset: 0; background: rgba(8, 8, 8, .95); opacity: 0; transition: opacity .5s ease; cursor: zoom-out; }
.mosaic-lb.is-open .mosaic-lb-bg { opacity: 1; }
.mosaic-lb-img { position: fixed; display: block; object-fit: cover; transform-origin: 0 0; cursor: zoom-out; will-change: transform; }
.mosaic-lb-btn { position: absolute; top: 50%; translate: 0 -50%; z-index: 2; width: 3rem; height: 3rem; border-radius: 50%;
  border: 1px solid rgba(255,255,255,.7); background: transparent; color: #fff; display: grid; place-items: center; cursor: pointer;
  opacity: 0; transition: opacity .4s ease, background-color .25s ease, color .25s ease; }
.mosaic-lb-btn svg { width: 1.1rem; height: 1.1rem; fill: none; stroke: currentColor; stroke-width: 1.5; }
.mosaic-lb-btn:hover { background: #fff; color: var(--ink); }
.mosaic-lb-prev { left: clamp(.5rem, 2vw, 2rem); }
.mosaic-lb-next { right: clamp(.5rem, 2vw, 2rem); }
.mosaic-lb-close { position: absolute; top: clamp(.75rem, 2vw, 1.5rem); right: clamp(.75rem, 2vw, 1.5rem); z-index: 2; width: 2.75rem; height: 2.75rem;
  border: 0; background: transparent; cursor: pointer; opacity: 0; transition: opacity .4s ease; }
.mosaic-lb-close::before, .mosaic-lb-close::after { content: ''; position: absolute; left: 20%; right: 20%; top: 50%; height: 1px; background: #fff; }
.mosaic-lb-close::before { transform: rotate(45deg); } .mosaic-lb-close::after { transform: rotate(-45deg); }
.mosaic-lb-count { position: absolute; left: 50%; bottom: clamp(.75rem, 2vw, 1.5rem); translate: -50% 0; margin: 0; z-index: 2;
  color: #fff; font-family: var(--serif); font-size: clamp(1.1rem, 1.6vw, 1.5rem); font-variant-numeric: tabular-nums; opacity: 0; transition: opacity .4s ease; }
.mosaic-lb.is-open .mosaic-lb-btn, .mosaic-lb.is-open .mosaic-lb-close, .mosaic-lb.is-open .mosaic-lb-count { opacity: 1; }
html.mosaic-open { overflow: hidden; }
@media (max-width: 40rem) { .mosaic-lb-btn { top: auto; bottom: .5rem; translate: none; } }

/* THE HUNG CAROUSEL (Commissions, JP 27/10: lab options 2 + 1). The carousel in
   templates/_carousel.html, dressed as prints on a wall: warm plaster, every
   photograph the same 4:5 crop, a white mat inside thin black moulding, a
   shadow on the wall; the centred one under a picture light, the neighbours
   darkened by the script's --dim. */
.band--hung { position: relative; isolation: isolate; overflow: hidden; background: #e7e1d6; color: var(--ink); }
.band--hung::before { content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: radial-gradient(ellipse 42% 62% at 50% 58%, rgba(255, 249, 236, .55), rgba(255, 249, 236, 0) 60%),
              radial-gradient(ellipse 90% 90% at 50% 50%, rgba(0, 0, 0, 0) 55%, rgba(40, 30, 20, .22) 100%); }
.band--hung .h2 { color: var(--ink); }
.band--hung .car-track { gap: clamp(1.5rem, 4vw, 4rem); padding-block: clamp(2.5rem, 4vw, 3.5rem) clamp(2rem, 3vw, 3rem); }
.band--hung .car-frame { --h: min(56vh, 32rem); --mat: clamp(.85rem, 1.8vw, 1.5rem);
  box-sizing: content-box; height: var(--h); width: calc(var(--h) * .8); padding: var(--mat);
  background: #fbfaf7; border: clamp(5px, .5vw, 9px) solid #151311;
  box-shadow: inset 0 2px 6px rgba(0, 0, 0, .12), 0 30px 40px -18px rgba(0, 0, 0, .45), 0 8px 14px rgba(0, 0, 0, .16); }
.band--hung .car-frame img { width: 100%; height: 100%; transform: none !important; box-shadow: 0 0 0 1px rgba(0, 0, 0, .1); }
.band--hung .car--wait .car-frame img { scale: 1; }
.band--hung .car-frame::after { background: #1b1712; }
.band--hung .car-slide { position: relative; }
.band--hung .car-slide::before { content: ''; position: absolute; left: 50%; top: -1.6rem; width: 34%; height: .45rem; translate: -50% 0;
  border-radius: .3rem; background: linear-gradient(#2c2925, #0f0e0d); opacity: 0; transition: opacity .6s ease; }
.band--hung .car-slide::after { content: ''; position: absolute; left: -10%; right: -10%; top: -1.2rem; height: 70%; pointer-events: none;
  background: radial-gradient(ellipse 50% 60% at 50% 0, rgba(255, 238, 200, .42), rgba(255, 238, 200, 0) 70%); mix-blend-mode: soft-light;
  opacity: 0; transition: opacity .6s ease; }
.band--hung .car-slide.is-current::before, .band--hung .car-slide.is-current::after { opacity: 1; }
.band--hung .car-btn:hover { background: var(--ink); color: #e7e1d6; }
@media (max-width: 48rem) { .band--hung .car-frame { --h: min(50svh, 24rem); } }

/* THE FOOTER'S TWO SIDES (Nico, 26/10) */
.foot-left, .foot-right { display: flex; flex-direction: column; gap: .25rem; }
.foot-right { align-items: flex-end; text-align: right; }
.foot-by { margin-top: .75rem; white-space: nowrap; }
.foot-rights { margin-top: .5rem; }
.foot-rights .foot-legal { margin-top: 2px; }
@media (max-width: 48rem) { .foot-right { align-items: flex-start; text-align: left; } .foot-by { white-space: normal; } }
/* NO PLAY BUTTON ON ANY CLIP (Nico, 26/10): Safari's own start button never
   draws over a still; templates/_motion_js.html starts the clip instead. */
video::-webkit-media-controls, video::-webkit-media-controls-start-playback-button,
video::-webkit-media-controls-overlay-play-button, video::-webkit-media-controls-panel { display: none !important; -webkit-appearance: none; opacity: 0; }

/* HIS OWN WORDS IN ITALICS (JP, 27/10): the commission lines on Home and Work,
   and the statement on the Artist page */
.own-quote { font-family: var(--serif); font-style: italic; }
.home-split-text .home-expand { margin-top: 1rem; }
.own-statement { margin: 1.25rem 0 0; padding: 0; font-family: var(--serif); font-style: italic; max-width: 36rem; }
.own-statement p { margin: 0 0 .9em; font-size: clamp(1.1rem, 1.35vw, 1.3rem); line-height: 1.5; text-wrap: pretty; }
.own-statement .own-statement-lead { font-size: clamp(1.5rem, 2.3vw, 2.2rem); line-height: 1.25; text-wrap: balance; }
.own-statement p:last-child { margin-bottom: 0; }
.own-statement + .prose { margin-top: var(--gap-group); }

/* =============================================================================
   27/10, THE WORK BAR REBUILT FOR A PHONE (JP: "on mobile it looks horrible, the
   buttons don't fit"). Nothing is hidden behind a menu any more.
   - Row one: the places, as a sideways strip; the one you are in is white and
     underlined, and the strip keeps it in view.
   - Row two: "Filter" and the four types as chips, always visible; the chosen
     one is a white pill. One tap, no menu.
   Desktop keeps one row: places left, the same chips right. */
.citybtn { display: none !important; }
.placebar-places { overflow-x: auto; overflow-y: hidden; scrollbar-width: none; -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity; }
.placebar-places::-webkit-scrollbar { display: none; }
.placebar-places a { scroll-snap-align: start; }
.typemenu { gap: .6rem; }
.typemenu-btn {
  background: transparent !important; border: 0 !important; padding: 0 !important; cursor: default; pointer-events: none;
  color: rgba(255, 255, 255, .6) !important; gap: .45rem;
}
.typemenu-k { color: rgba(255, 255, 255, .6) !important; font-weight: 400; }
.typemenu-ico { width: 1rem; height: 1rem; }
.typemenu-list, .typemenu-list * { box-sizing: border-box; }
.typemenu-list {
  position: static; display: flex; gap: .45rem; min-width: 0; margin: 0; padding: 0; background: transparent !important;
  border: 0 !important; box-shadow: none; border-radius: 0; opacity: 1; transform: none; pointer-events: auto;
  overflow-x: auto; scrollbar-width: none;
}
.typemenu-list::-webkit-scrollbar { display: none; }
.typemenu-list [role=option] {
  flex: none; padding: .5rem 1rem !important; border-radius: 999px; white-space: nowrap;
  color: rgba(255, 255, 255, .86) !important; border: 1px solid rgba(255, 255, 255, .3);
  font: 400 var(--t-nav)/1 var(--sans); letter-spacing: .08em; text-transform: uppercase;
  transition: background-color .2s var(--ease), color .2s var(--ease), border-color .2s var(--ease), transform .2s var(--ease);
}
.typemenu-list [role=option]:hover { border-color: #FFFFFF; background: rgba(255, 255, 255, .1) !important; }
.typemenu-list [role=option]:active { transform: scale(.96); }
.typemenu-list [role=option]:focus-visible { outline: 2px solid #FFFFFF; outline-offset: 2px; background: transparent; }
.typemenu-list [aria-selected=true] { background: #FFFFFF !important; color: #0B0B0B !important; border-color: #FFFFFF; font-weight: 500; }
.typemenu-list [aria-selected=true]::after { display: none; }
@media (min-width: 52.01rem) {
  .placebar-in { gap: 2rem; min-height: 3.75rem; }
  .placebar-places a { padding-block: 1.4rem; }
}
@media (max-width: 52rem) {
  html:has(.placebar) { scroll-padding-top: 9.75rem; }
  .placebar-in { flex-direction: column; align-items: stretch; justify-content: flex-start; gap: 0; min-height: 0; padding-inline: 0; }
  .placebar-places { flex: none; gap: 1.4rem; padding: 0 var(--gutter, 1rem); border-bottom: 1px solid rgba(255, 255, 255, .12);
    -webkit-mask-image: linear-gradient(to right, transparent 0, #000 1rem, #000 calc(100% - 2rem), transparent); mask-image: linear-gradient(to right, transparent 0, #000 1rem, #000 calc(100% - 2rem), transparent); }
  .placebar-places a { padding: .95rem 0 .8rem; border-radius: 0; border-bottom: 2px solid transparent; }
  .placebar-places a.is-here { background: transparent; border-bottom-color: #FFFFFF; }
  .placebar-mark { display: none; }
  .typemenu { padding: .6rem var(--gutter, 1rem) .7rem; overflow: hidden; }
  .typemenu-list { padding-right: 1.5rem; }
  .typemenu-list [role=option] { padding: .55rem .9rem !important; }
}

/* THE HAGODIGITAL MARK IN THE FOOTER (JP, 27/10): it was drawn at 80% opacity, so
   it never matched the white of the words beside it, and on Contact's yellow it
   was white on yellow. Full strength everywhere; on Contact it is the same near-
   black as that footer's text (#141414) -- the file is one-colour white, so the
   filter turns it black and lifts it to that value. */
.foot-credit-logo img { opacity: 1 !important; }
@media (max-width: 52rem) {
  .placebar-places { position: static; flex-direction: row; min-width: 0; background: transparent; border: 0;
    border-bottom: 1px solid rgba(255, 255, 255, .12); border-radius: 0; box-shadow: none; padding: 0 var(--gutter, 1rem);
    opacity: 1; transform: none; pointer-events: auto; visibility: visible; transition: none; }
  .placebar.is-first .typemenu-btn { animation: none; }
}
.typemenu-btn { box-shadow: none !important; animation: none !important; }
@media (max-width: 52rem) {
  .typemenu { gap: .5rem; }
  .typemenu-k { display: none !important; }
  .typemenu-list [role=option] { padding: .55rem .75rem !important; letter-spacing: .05em; font-size: .75rem; }
  .typemenu-list { gap: .35rem; }
}

/* ============================================================================
   27/10, TYPE BACK TO THE SITE'S OWN (JP): Instrument Serif for headings and
   Inter for everything else, as on the live site, and only TWO sizes -- the
   heading and the regular. Colours are untouched. Every tracked or capital label
   is now plain regular text; a quote is regular text in italics with its marks. */
:root {
  --sans: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --serif: "Instrument Serif", ui-serif, Georgia, "Times New Roman", serif;
  --t-head: clamp(2.25rem, 1.1rem + 4.2vw, 4rem);
  --t-reg: clamp(1.0625rem, 1rem + .2vw, 1.125rem);
  --t-h1: var(--t-head); --t-h2: var(--t-head); --t-h3: var(--t-head);
  --t-lede: var(--t-reg); --t-body: var(--t-reg); --t-title: var(--t-reg);
  --t-label: var(--t-reg); --t-meta: var(--t-reg); --t-nav: var(--t-reg); --quote-size: var(--t-reg);
}
body :where(*:not(svg):not(svg *):not(html):not(.masthead-bar):not(.masthead-bar *)) {
  font-family: var(--sans) !important; font-size: var(--t-reg) !important; font-weight: 400 !important;
  text-transform: none !important; letter-spacing: normal !important; }
body h1, body h2, body h3, body .h2, body .display, body .h2--name, body .place-name, body .intro-title,
body .h2 *, body .display *, body h1 *, body h2 * {
  font-family: var(--serif) !important; font-size: var(--t-head) !important; font-weight: 400 !important;
  text-transform: none !important; letter-spacing: -.01em !important; line-height: 1.08 !important; }
body .home-quote, body .own-quote, body .own-statement p, body .own-statement .own-statement-lead {
  font-family: var(--sans) !important; font-style: italic !important; font-size: var(--t-reg) !important;
  line-height: 1.65 !important; letter-spacing: normal !important; }
.own-quote { display: inline; margin: 0; }
.own-statement { max-width: 36rem; }

/* HOME: Selected work on black; the artist on "The wall" */
.band--selection.band--ink .masonry .cap-title { color: var(--paper); }
.home-wall { background: radial-gradient(ellipse 80% 90% at 50% 20%, #ECE6DA, #D9D1C2);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5), inset 0 -40px 60px -50px rgba(0, 0, 0, .25); }
.home-wall .home-split-fig img { box-shadow: 0 2px 3px rgba(0, 0, 0, .2), 0 22px 30px -14px rgba(0, 0, 0, .45); }

/* FOOTERS TURN AGAIN, FAST (JP, 27/10): each page its own three dark colours from
   its own palette, white type throughout (every pair is above 7:1). */
@media (prefers-reduced-motion: no-preference) { .foot.foot { animation-duration: 5s; } }

/* THE GALLERY-WALL CAROUSEL (lab option 1): plaster, framed prints, the middle one lit */
.band--wall { position: relative; overflow: hidden; background: #E2DBCC; padding-bottom: clamp(2rem, 4vw, 3rem); }
.band--wall::before { content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 0;
  background: radial-gradient(ellipse 60% 75% at 50% 45%, rgba(255, 248, 232, .5), rgba(255, 248, 232, 0) 60%), radial-gradient(ellipse 120% 100% at 50% 50%, rgba(0, 0, 0, 0) 55%, rgba(40, 30, 20, .22) 100%); }
.band--wall > * { position: relative; z-index: 1; }
.wallcar { position: relative; z-index: 1; }
.wc-track { display: flex; align-items: center; gap: clamp(2rem, 5vw, 5rem); overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none;
  margin: 0; list-style: none; padding: 2.5rem 0 3rem; cursor: grab; outline-offset: -4px; }
.wc-track::-webkit-scrollbar { display: none; }
.wc-track.is-drag { cursor: grabbing; scroll-snap-type: none; }
.wc-slide { flex: none; scroll-snap-align: center; transform-origin: 50% 50%; will-change: transform, filter; }
.wc-frame { --mat: clamp(.9rem, 2.2vw, 1.9rem); --h: min(54vh, 32rem, calc(66vw / var(--r)));
  height: calc(var(--h) + 2 * var(--mat)); width: calc(var(--h) * var(--r) + 2 * var(--mat)); padding: var(--mat);
  background: #FBFAF7; border: clamp(5px, .55vw, 9px) solid #141210;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .06), inset 0 2px 6px rgba(0, 0, 0, .12), 0 30px 40px -18px rgba(0, 0, 0, .45), 0 8px 14px rgba(0, 0, 0, .18); }
.wc-frame img { display: block; width: 100%; height: 100%; object-fit: cover; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .1); }
.wc-bar { display: flex; align-items: center; justify-content: space-between; max-width: 78rem; margin: 0 auto; padding: 0 var(--gutter, 1rem); }
.wc-count b, .wc-count i { font-style: normal; font-weight: 400; } .wc-count i { opacity: .5; } .wc-count { margin: 0; }
.wc-nav { display: flex; gap: .75rem; }
.wc-btn { width: 2.75rem; height: 2.75rem; border-radius: 50%; border: 1px solid currentColor; background: transparent; color: inherit; cursor: pointer; display: grid; place-items: center; }
.wc-btn svg { width: 1.1rem; height: 1.1rem; fill: none; stroke: currentColor; stroke-width: 1.5; }
.wc-btn:hover { background: #141210; color: #FBFAF7; }

/* CREAM, ONE OF THREE GROUNDS (JP, 27/10): paper (the page), black, and this cream.
   The carousels sit on flat cream with no frames; the lighting does the work. */
:root { --wall: #E2DBCC; }
.band--cream { background: var(--wall); color: var(--ink); border-bottom: 1px solid rgba(11, 11, 11, .14); }
.band--cream .section-head { margin-bottom: 0; }
.selection-head { padding-block: clamp(3rem, 7vw, 5.5rem); }
.selection-head .h2, .selection-head .group-sub { text-align: center; margin-inline: auto; }
.selection-head .group-sub { margin-top: 1rem; color: var(--ink-soft); }
.band--wall::before { content: none; }
.band--wall { background: var(--wall); }
.home-wall { background: var(--wall); box-shadow: none; }
.home-wall .home-split-fig img { box-shadow: none; }
.wc-frame { --mat: 0px; --h: min(68vh, 42rem, calc(78vw / var(--r)));
  padding: 0; border: 0; background: transparent; box-shadow: none; }
.wc-frame img { box-shadow: 0 24px 34px -22px rgba(0, 0, 0, .5); }
.wc-track { padding-block: 2.5rem 3rem; }

/* THE OPENER'S SHADE, ON TWO MORE BANDS (JP, 27/10, to see how it looks): black on
   the left, the opening painting coming through towards the right, as at the top of
   Home. The painting is held back so the works and the reviews stay readable. */
.band--shaded { position: relative; isolation: isolate; }
.band--shaded::before { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background:
    linear-gradient(to right, #0B0B0B 0%, #0B0B0B 22%, rgba(11, 11, 11, .55) 62%, rgba(11, 11, 11, .35) 100%),
    var(--shade-img) 70% center / cover no-repeat, #0B0B0B; }

/* THE WHITE IS THE ORIGINAL PAPER AGAIN (JP, 27/10); --paper is back to #F4F1EA in :root. */
:root { --wall: var(--paper); }
.band--wall, .band--cream, .home-wall { background: var(--paper); }

/* HEROES BACK TO THE LIVE SITE'S SIZE (JP, 27/10): 56vh on a desktop (340 to 620px),
   46vh on a phone (280 to 420px). */
.opener--tall { min-height: clamp(340px, 56vh, 620px); }
.hero-big .hero-figure img { height: clamp(340px, 56vh, 620px); }
@media (max-width: 52rem) {
  .opener-media, .opener:not(.opener--tall) .opener-media { height: clamp(280px, 46vh, 420px); }
}
@media (max-width: 34rem) { .hero-big .hero-figure img { height: clamp(280px, 46vh, 420px); } }

/* EVERY FOOTER BLACK AND STILL (JP, 27/10) */
.foot.foot { animation: none !important; background-color: #0B0B0B !important; color: #FFFFFF; }
.foot--index, .foot--obra, .foot--obras, .foot--artista, .foot--encargos, .foot--contacto, .foot--ciudad { animation: none !important; }

/* THE TOP BAR IS THE LIVE SITE'S AGAIN (JP, 27/10): 12px capitals, 500, tracked. */
.masthead-bar .nav a, .masthead-bar .wordmark { font-family: var(--sans); font-size: var(--t-nav); font-weight: 500; letter-spacing: .065em; text-transform: uppercase; }
.masthead-bar .lang { font-family: var(--sans); font-size: .875rem; font-weight: 400; letter-spacing: .065em; text-transform: uppercase; }

/* HOME 27/10: the Commissions door and the reviews fade from WHITE on the left, lettering black. */
.band--shaded.band--paper::before {
  background: linear-gradient(to right, var(--paper) 0%, var(--paper) 24%, rgba(244, 241, 234, .55) 62%, rgba(244, 241, 234, .15) 100%),
    var(--shade-img) 70% center / cover no-repeat, var(--paper); }
.reviews-band .opener-go { color: var(--ink); border-color: var(--ink); text-shadow: none; }
.reviews-band .opener-go:hover, .reviews-band .opener-go:focus-visible { background: var(--ink); color: var(--paper); }
.reviews-band .reviews-google, .reviews-band .go { color: var(--ink); }

/* WORK 27/10: banners about 30% smaller, the grounds under the paintings all light,
   and In collections' banner turns through three colours of the page's own hero. */
.place-band--photo { min-height: clamp(11rem, 24vw, 18.25rem); }
.place-band-in { padding-block: clamp(1.75rem, 3.6vw, 3rem); }
.place-body.band { background: var(--paper); }
@keyframes coll-cycle { 0%, 100% { background-color: #2E4664; } 33% { background-color: #8A3021; } 66% { background-color: #4A2E2B; } }
@media (prefers-reduced-motion: no-preference) { .place[data-group="colecciones"] .place-band { animation: coll-cycle 6s ease-in-out infinite; } }
@media (max-width: 52rem) {
  .place-photo { height: 9.25rem; }
  .place-band--photo .place-band-in { margin-top: -2.5rem; }
  .place-credit { top: 7.25rem; }
}

/* CONTACT 27/10: the banner's own three colours (crimson, blue, violet), quickly. */
@keyframes op-contacto { 0%, 100% { background-color: #923138; } 33% { background-color: #214D71; } 66% { background-color: #4F4C69; } }
@media (prefers-reduced-motion: no-preference) { .opener--contacto { animation: op-contacto 4s ease-in-out infinite; } }

/* ARTIST 27/10: the title and his sentence sit in the hero on a diffused white, black lettering. */
.hero-over-wrap { position: relative; }
.hero-over { position: absolute; inset: 0; display: flex; align-items: center; pointer-events: none;
  background: linear-gradient(to right, var(--paper) 0%, var(--paper) 26%, rgba(244, 241, 234, .75) 44%, rgba(244, 241, 234, 0) 70%); }
.hero-over .wrap { width: 100%; }
.hero-over .intro-title, .hero-over .hero-over-quote { max-width: min(30rem, 42%); margin: 0; color: var(--ink); pointer-events: auto; }
.hero-over .hero-over-quote { margin-top: 1.25rem; }
@media (max-width: 52rem) {
  .hero-over { position: static; background: var(--paper); padding-block: 1.5rem 0; }
  .hero-over .intro-title, .hero-over .hero-over-quote { max-width: none; }
}

/* NAV AT THE LIVE SIZES (12px nav, 14px language) and every hero one height (JP, 27/10) */
.masthead-bar .nav a { font-size: .75rem; }
.masthead-bar .lang { font-size: .875rem; }
.opener-par, .opener--tall { min-height: clamp(340px, 56vh, 620px); }
.opener-text { padding-block: clamp(2rem, 5vw, 3.5rem); }
.opener-par { display: flex; align-items: center; justify-content: center; }
@media (max-width: 52rem) { .opener-par { min-height: clamp(280px, 46vh, 420px); } }
.hero-over { z-index: 5; }
.hero-over .wrap { margin-inline: auto; padding-inline: var(--gutter, 1.5rem); max-width: 78rem; }
.hero-over .hero-over-quote { display: block; }

/* THE FOOTER, THREE LINES IN TWO SIDES (JP, 27/10): his mark and the icons; the pages
   and the copyright; the credit and privacy. Everything is about the size of the
   icons except his mark and HagoDigital's, which are larger. A little smaller overall. */
.foot { padding-block: clamp(1.75rem, 3vw, 2.5rem); }
.foot .foot-grid { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: .15rem 2rem; margin-top: 0; }
.foot .foot-logo { grid-column: 1; grid-row: 1; margin: 0; }
.foot .foot-reach { grid-column: 2; grid-row: 1; justify-self: end; display: flex; align-items: center; gap: .25rem 1rem; }
.foot .foot-nav { grid-column: 1; grid-row: 2; }
.foot .foot-rights { grid-column: 2; grid-row: 2; justify-self: end; text-align: right; margin: 0; }
.foot .foot-by { grid-column: 1; grid-row: 3; margin: 0; white-space: nowrap; }
.foot .foot-legal { grid-column: 2; grid-row: 3; justify-self: end; text-align: right; margin: 0; }
.foot .logo--foot { height: 3.1rem; }
.foot-credit-logo img { height: 2.1rem !important; }
.foot .foot-nav a, .foot .foot-small, .foot .foot-legal a, .foot .foot-credit { font-size: .875rem; line-height: 1.4; }
.foot .foot-nav { gap: 0 1.25rem; }
.foot .foot-credit { gap: .75rem; }
@media (max-width: 48rem) {
  .foot .foot-grid { grid-template-columns: minmax(0, 1fr); gap: .35rem 0; }
  .foot .foot-logo, .foot .foot-reach, .foot .foot-nav, .foot .foot-rights, .foot .foot-by, .foot .foot-legal { grid-column: 1; grid-row: auto; justify-self: start; text-align: left; }
  .foot .logo--foot { height: 2.3rem; }
}

/* THE ARTIST'S CLIP (JP, 27/10): upright, in place of the photograph */
.intro-portrait--video { max-width: 20rem; justify-self: center; }
.about-video { display: block; width: 100%; height: auto; background: #0B0B0B; }

/* IN COLLECTIONS HAS NO PHOTOGRAPH: just the three colours turning (JP, 27/10) */
.place[data-group="colecciones"] .place-band { min-height: clamp(11rem, 24vw, 18.25rem); display: flex; align-items: center; }
.place[data-group="colecciones"] .place-band-in { width: 100%; }

/* HOME'S COMMISSIONS DOOR: the rooms as they are, no fade and no darkening (JP, 27/10) */
.door-art .record-photos { -webkit-mask-image: none; mask-image: none; width: 56%; }
.door-art .record-photos::after { content: none; }
@media (max-width: 52rem) { .door-art .record-photos { width: auto; height: 20rem; margin: 0 0 1.5rem; } }

/* EVERY HERO ONE HEIGHT, FIXED, so no content can grow it (JP, 27/10) */
.opener--tall, .opener-par { height: clamp(340px, 56vh, 620px); min-height: 0; overflow: hidden; }
@media (max-width: 52rem) { .opener--tall, .opener-par { height: auto; min-height: 0; } .opener-par { height: clamp(280px, 46vh, 420px); } }

/* =============================================================================
   27/10 ROUND 3. Process icons, the Work bar, the Work menu, Nico-style carousel
   controls, the Artist hero words, the bigger footer. */

/* THE PROCESS, FROM THE SUPPLIED PACK */
.nico-process-list { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: clamp(1.25rem, 3vw, 2.5rem); }
.nico-process-img { display: block; width: 100%; max-width: 17rem; height: auto; margin: 0 auto 1.25rem; }
.nico-process-number { display: block; margin: 0 auto .9rem; padding-bottom: .6rem; position: relative; }
.nico-process-number::after { content: ""; position: absolute; left: 50%; bottom: 0; width: 2rem; height: 1px; background: currentColor; opacity: .4; transform: translateX(-50%); }
@media (max-width: 900px) and (min-width: 641px) { .nico-process-list { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .nico-process-list { grid-template-columns: 1fr; } }

/* THE WORK BAR: filters on the left as plain words, the places in one menu on the right */
html body .placebar .placebar-in { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-direction: row; min-height: 3.25rem; }
html body .placebar .typemenu { order: 1; padding: 0; flex: 1 1 auto; min-width: 0; overflow: visible; gap: 1rem; }
html body .placebar .typemenu-list { gap: 1.1rem; padding: 0; overflow-x: auto; }
html body .placebar .typemenu-list [role=option] { padding: .35rem 0 !important; border: 0 !important; border-radius: 0; background: transparent !important;
  color: rgba(255, 255, 255, .62) !important; border-bottom: 2px solid transparent !important; }
html body .placebar .typemenu-list [role=option]:hover { color: #FFFFFF !important; }
html body .placebar .typemenu-list [aria-selected=true] { color: #FFFFFF !important; border-bottom-color: #FFFFFF !important; background: transparent !important; font-weight: 400; }
html body .placebar .placebar-go { order: 2; position: relative; flex: none; }
html body .placebar .citybtn { display: inline-flex !important; align-items: center; gap: .5rem; max-width: none; padding: .35rem 0; border: 0; background: transparent; color: #FFFFFF; cursor: pointer;
  font-family: var(--sans); font-size: .8125rem; letter-spacing: .065em; text-transform: uppercase; }
html body .placebar .citybtn-k { color: rgba(255, 255, 255, .62); }
html body .placebar .citybtn svg { width: 1rem; height: 1rem; fill: none; stroke: currentColor; stroke-width: 1.6; transition: transform .3s; }
html body .placebar.is-cities .citybtn svg { transform: rotate(180deg); }
html body .placebar .placebar-places { position: absolute; right: 0; left: auto; top: calc(100% + .6rem); min-width: 14rem; flex-direction: column; gap: 0; padding: .4rem;
  background: #0B0B0B; border: 1px solid rgba(255, 255, 255, .2); border-radius: .5rem; box-shadow: 0 18px 40px rgba(0, 0, 0, .45);
  opacity: 0; visibility: hidden; pointer-events: none; transform: translateY(-4px); transition: opacity .18s ease, transform .22s ease, visibility 0s linear .22s;
  overflow: visible; -webkit-mask-image: none; mask-image: none; }
html body .placebar.is-cities .placebar-places { opacity: 1; visibility: visible; pointer-events: auto; transform: none; transition-delay: 0s; display: flex; }
html body .placebar .placebar-places a { padding: .65rem .9rem; border-radius: .35rem; border-bottom: 0; white-space: nowrap; }
html body .placebar .placebar-places a.is-here { background: rgba(255, 255, 255, .1); }
html body .placebar .placebar-mark { display: none; }
@media (max-width: 52rem) {
  html body .placebar .typemenu-k, html body .placebar .typemenu-ico { display: none !important; }
  html body .placebar .typemenu-list { gap: .9rem; }
  html body .placebar .citybtn-k { display: none; }
}

/* THE MASTHEAD WORK MENU */
.nav-sub { position: relative; display: inline-block; }
.nav-sub .subnav { position: absolute; left: 0; top: 100%; min-width: 12.5rem; margin: 0; padding: .4rem; list-style: none; background: var(--paper); border: 1px solid var(--rule);
  box-shadow: 0 18px 36px rgba(11, 11, 11, .14); opacity: 0; visibility: hidden; transform: translateY(-4px); transition: opacity .18s ease, transform .2s ease, visibility 0s linear .2s; z-index: 120; }
.nav-sub:hover .subnav, .nav-sub:focus-within .subnav { opacity: 1; visibility: visible; transform: none; transition-delay: 0s; }
.nav-sub .subnav a { display: block; padding: .6rem .8rem; white-space: nowrap; }
.nav-sub .subnav a:hover, .nav-sub .subnav a:focus-visible { background: rgba(11, 11, 11, .06); }
@media (max-width: 48rem) {
  .nav-sub { display: block; }
  .nav-sub .subnav { position: static; opacity: 1; visibility: visible; transform: none; border: 0; box-shadow: none; background: transparent; padding: 0 0 .25rem 1rem; }
}

/* CAROUSEL CONTROLS, NICO HAND: a brush arrow, the count in the middle, a brush arrow, all centred */
.wc-bar { justify-content: center; gap: clamp(1.5rem, 4vw, 3rem); padding-top: .5rem; }
.wc-count, .wc-count b, .wc-count i { margin: 0; font-family: var(--serif) !important; font-size: 2rem !important; line-height: 1; font-variant-numeric: tabular-nums; }
.wc-btn { width: 3.75rem; height: 2.75rem; border: 0; border-radius: 0; background: transparent; padding: 0; color: var(--ink); transition: transform .25s var(--ease); }
.wc-btn svg { width: 100%; height: 100%; fill: none; stroke: currentColor; stroke-width: 3.2; stroke-linecap: round; stroke-linejoin: round; }
.wc-btn:hover { background: transparent; color: var(--ink); }
.wc-btn--prev:hover { transform: translateX(-4px); }
.wc-btn--next:hover { transform: translateX(4px); }
.wc-clip { display: block; width: 100%; height: 100%; object-fit: cover; }

/* THE ARTIST HERO WORDS (JP, 27/10): no wash on the left; black on the blank wall,
   white (with a soft shadow) once the colour has come in */
@media (min-width: 52.01rem) {
  .hero-over { background: none; }
  .hero-over .intro-title, .hero-over .hero-over-quote { color: var(--ink); transition: color .8s ease, text-shadow .8s ease; }
  [data-hero-text].is-colour .intro-title, [data-hero-text].is-colour .hero-over-quote { color: #FFFFFF; text-shadow: 0 0 3px rgba(0, 0, 0, .75), 0 2px 10px rgba(0, 0, 0, .7), 0 4px 28px rgba(0, 0, 0, .65); }
}

/* THE FOOTER, THE BIGGER ONE AGAIN (JP, 27/10) */
.foot { padding-block: clamp(3rem, 6vw, 5rem); }
.foot .foot-grid { gap: .6rem 2rem; }
.foot .logo--foot { height: 3.6rem; }
.foot-credit-logo img { height: 2.4rem !important; }
.foot .foot-nav a, .foot .foot-small, .foot .foot-legal a, .foot .foot-credit { font-size: 1rem; }
@media (max-width: 48rem) { .foot .logo--foot { height: 2.6rem; } }

/* =============================================================================
   27/10 ROUND 4. Heroes at the big size again, small footer type, banners a size
   up, a drifting pattern on In collections, a wider film on Work's Commissions band. */

/* EVERY HERO THE BIG ONE, AS WHEN THE NEW SITE STARTED (JP, 27/10): 46rem tall, or the screen
   less the bar, whichever is smaller; on a phone about two thirds of the screen. */
.opener--tall, .opener-par { height: min(46rem, calc(100svh - 4.5rem)); min-height: 0; overflow: hidden; }
.hero-big .hero-figure img { height: min(46rem, calc(100svh - 4.5rem)); min-height: 0; }
@media (max-width: 52rem) {
  .opener--tall { height: auto; }
  .opener-media, .opener:not(.opener--tall) .opener-media { height: min(62svh, 28rem); }
  .opener-par { height: min(62svh, 28rem); }
  .hero-big .hero-figure img { height: min(62svh, 28rem); }
}

/* THE FOOTER TYPE IS ICON-SIZED (JP, 27/10): the pages, the copyright, privacy and cookies,
   and "Site by" all sit at the size of the icons; only the two marks are large. */
.foot .foot-nav a, .foot .foot-small, .foot .foot-legal a, .foot .foot-credit { font-size: .875rem; }

/* CITY BANNERS: between the small size and the original */
.place-band--photo { min-height: clamp(13.5rem, 29vw, 22rem); }
@media (max-width: 52rem) {
  .place-photo { height: 11rem; }
  .place-credit { top: 9rem; }
  .place-band--photo .place-band-in { margin-top: -3rem; }
}
.place[data-group="colecciones"] .place-band { min-height: clamp(13.5rem, 29vw, 22rem); }

/* IN COLLECTIONS: the colours turn and, over them, a pattern of the marks his paintings are
   made of (dashes, dots, a zigzag) drifts at two speeds. Geometry, not an illustration. */
.place[data-group="colecciones"] .place-band { position: relative; overflow: hidden; }
.place[data-group="colecciones"] .place-band::before,
.place[data-group="colecciones"] .place-band::after { content: ""; position: absolute; inset: -20%; pointer-events: none; z-index: 0; }
.place[data-group="colecciones"] .place-band::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220' fill='none' stroke='%23fff' stroke-width='6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 40l38-14M126 18l30 24M70 112l-6 38M168 120l34 10M24 184l44-8'/%3E%3Cpath d='M92 70l14-16 14 16 14-16 14 16' stroke-width='5'/%3E%3Ccircle cx='170' cy='190' r='5' fill='%23fff' stroke='none'/%3E%3Ccircle cx='108' cy='170' r='4' fill='%23fff' stroke='none'/%3E%3Ccircle cx='38' cy='98' r='4' fill='%23fff' stroke='none'/%3E%3C/svg%3E");
  background-size: 220px 220px; opacity: .22; transform: rotate(-8deg); }
.place[data-group="colecciones"] .place-band::after {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='340' height='340' fill='none' stroke='%23fff' stroke-width='9' stroke-linecap='round'%3E%3Cpath d='M30 60l60 22M210 30l50 40M120 200l-8 60M250 230l56 14M40 290l70-10'/%3E%3Ccircle cx='290' cy='140' r='9' fill='%23fff' stroke='none'/%3E%3Ccircle cx='170' cy='120' r='7' fill='%23fff' stroke='none'/%3E%3C/svg%3E");
  background-size: 340px 340px; opacity: .12; transform: rotate(6deg); }
.place[data-group="colecciones"] .place-band-in { position: relative; z-index: 1; }
@media (prefers-reduced-motion: no-preference) {
  .place[data-group="colecciones"] .place-band::before { animation: pat-drift-a 38s linear infinite; }
  .place[data-group="colecciones"] .place-band::after { animation: pat-drift-b 61s linear infinite reverse; }
}
@keyframes pat-drift-a { from { background-position: 0 0; } to { background-position: 220px 440px; } }
@keyframes pat-drift-b { from { background-position: 0 0; } to { background-position: -340px 340px; } }

/* WORK'S COMMISSIONS BAND: the room film takes more of the right and the fade sits further left */
.band--film-wide .film { width: min(74%, 68rem);
  -webkit-mask-image: linear-gradient(to right, transparent 0, rgba(0, 0, 0, .35) 14%, #000 34%);
          mask-image: linear-gradient(to right, transparent 0, rgba(0, 0, 0, .35) 14%, #000 34%); }
@media (max-width: 52rem) { .band--film-wide .film { width: 100%; } }
.hero-figure--contacto img { height: min(46rem, calc(100svh - 4.5rem)); }
@media (max-width: 52rem) { .hero-figure--contacto img { height: min(62svh, 28rem); } }

/* =============================================================================
   27/10 ROUND 5. The photo credit barely there, In collections drawn in his own
   line-work over red, orange, yellow and blue, one long quote, a really small footer. */

/* THE PHOTO CREDIT: attribution stays, as quiet as it can be, at the foot of the picture */
.place-credit { right: .6rem; bottom: .3rem; font-size: .5625rem !important; line-height: 1.2; opacity: .5; text-shadow: none; letter-spacing: 0; }
.place-credit a { opacity: 1; }
@media (max-width: 52rem) { .place-credit { top: auto; bottom: .3rem; } }

/* IN COLLECTIONS: red, through orange, to yellow and blue, quickly; the lettering turns black on the yellow */
@keyframes coll-cycle {
  0%, 100% { background-color: #8A3021; color: #FFFFFF; }
  24% { background-color: #D4561B; color: #FFFFFF; }
  46%, 54% { background-color: #F0C21A; color: #0B0B0B; }
  76% { background-color: #1F44B0; color: #FFFFFF; }
}
@media (prefers-reduced-motion: no-preference) {
  .place[data-group="colecciones"] .place-band { animation: coll-cycle 8s ease-in-out infinite; }
}
.place[data-group="colecciones"] .place-name { color: inherit; }

/* ...and over the colour his own painting is drawn in line, stroke by stroke, then lifts */
@property --draw { syntax: "<percentage>"; initial-value: 135%; inherits: false; }
.place[data-group="colecciones"] .place-band::after { content: none; }
.place[data-group="colecciones"] .place-band::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: url("assets/motion/lineart-collections.becd8fee.webp") center / cover no-repeat;
  transform: none; opacity: .5; mix-blend-mode: difference;
  --draw: 135%;
  -webkit-mask-image: linear-gradient(100deg, #000 calc(var(--draw) - 22%), transparent var(--draw));
          mask-image: linear-gradient(100deg, #000 calc(var(--draw) - 22%), transparent var(--draw)); }
@media (prefers-reduced-motion: no-preference) {
  .place[data-group="colecciones"] .place-band::before { --draw: 0%; animation: coll-draw 8s ease-in-out infinite; }
}
@keyframes coll-draw {
  0% { --draw: 0%; opacity: 0; }
  6% { opacity: .5; }
  62% { --draw: 135%; opacity: .5; }
  88% { --draw: 135%; opacity: .5; }
  100% { --draw: 135%; opacity: 0; }
}

/* THE FOOTER TYPE, REALLY SMALL (JP, 27/10): the earlier sizes never applied because the two-size
   rule is !important; these are too. Only the two marks are large. */
.foot .foot-nav a, .foot .foot-small, .foot .foot-small a, .foot .foot-legal a, .foot .foot-credit { font-size: .75rem !important; line-height: 1.4; }

/* =============================================================================
   27/10 ROUND 6. In collections: three colours and his line-work written in and
   erased, forever. Process numbers on the title line. Phone footer order. */

/* THE BANNER IS THREE COLOURS, TAKEN FROM HIS PAINTING (yellow, deep blue, red-brown),
   cut by the black outlines the painting has between them. It no longer changes colour. */
.place[data-group="colecciones"] .place-band { animation: none !important; color: #FFFFFF;
  background:
    linear-gradient(to bottom, #F2C316 0 29%, #0B0B0B 29% 31%, #1B3B8C 31% 69%, #0B0B0B 69% 71%, #7F2B17 71% 100%); }

/* his line-work is written in from the left, and as soon as it reaches the end it is deleted
   the same way back, round and round */
.place[data-group="colecciones"] .place-band::before { animation: none; opacity: .85; mix-blend-mode: difference; --draw: 0%; }
@media (prefers-reduced-motion: no-preference) {
  .place[data-group="colecciones"] .place-band::before { animation: coll-write 6s ease-in-out infinite alternate; }
}
@media (prefers-reduced-motion: reduce) { .place[data-group="colecciones"] .place-band::before { --draw: 135%; } }
@keyframes coll-write { from { --draw: 0%; } to { --draw: 135%; } }

/* THE PROCESS: number and title on one line, same hand, no rule */
.nico-process-number { display: inline; margin: 0; padding: 0; font-family: inherit; font-size: inherit; }
.nico-process-number::after { content: none; }
.nico-process-step h3 { font-size: clamp(22px, 1.9vw, 28px) !important; }
@media (max-width: 640px) { .nico-process-step h3 { font-size: 22px !important; } }

/* PHONE FOOTER: copyright, then privacy and cookies right under it, and "Site by" last */
@media (max-width: 48rem) {
  .foot .foot-rights { order: 4; }
  .foot .foot-legal { order: 5; }
  .foot .foot-by { order: 6; margin-top: .5rem; }
}

html body .nico-process-step h3 .nico-process-number { font-family: var(--serif) !important; font-size: inherit !important; letter-spacing: inherit !important; }

/* THE FOOTER MARKS AT THE NAV BAR'S SIZE (JP, 27/10): his mark and HagoDigital's, 36px tall like the masthead mark */
.foot .logo--foot { height: 2.25rem; }
.foot-credit-logo img { height: 2.25rem !important; }
@media (max-width: 48rem) { .foot .logo--foot { height: 2.25rem; } }

/* =============================================================================
   27/10 ROUND 8. In collections: one slow cycle. The band is one colour at a time
   (yellow, deep blue, red-brown), each held about ten seconds and crossfaded into
   the next, and in each colour a different strip of his painting is drawn in as
   gentle line-work, stays, and fades as the colour turns. It starts when the hero
   has finished painting. */

.place[data-group="colecciones"] .place-band { animation: none !important; background: #F2C316; color: #0B0B0B; }
.place[data-group="colecciones"] .place-band::before, .place[data-group="colecciones"] .place-band::after { content: none !important; animation: none !important; }
.place[data-group="colecciones"] .place-name { color: inherit; }
.coll-art { position: absolute; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
.coll-art i { position: absolute; inset: 0; opacity: 0; --draw: 135%;
  -webkit-mask-image: var(--strip), linear-gradient(100deg, #000 calc(var(--draw) - 45%), transparent var(--draw));
          mask-image: var(--strip), linear-gradient(100deg, #000 calc(var(--draw) - 45%), transparent var(--draw));
  -webkit-mask-size: cover, 100% 100%; mask-size: cover, 100% 100%;
  -webkit-mask-position: center, 0 0; mask-position: center, 0 0;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-composite: source-in; mask-composite: intersect; }
.coll-art i:nth-child(1) { --strip: url("assets/motion/coll-a.8ebdab06.webp"); background: #0B0B0B; }
.coll-art i:nth-child(2) { --strip: url("assets/motion/coll-b.5c151c44.webp"); background: #FFFFFF; }
.coll-art i:nth-child(3) { --strip: url("assets/motion/coll-c.6f81c739.webp"); background: #FFFFFF; }
@property --draw { syntax: "<percentage>"; initial-value: 135%; inherits: false; }

/* before the hero finishes (or with reduced motion) the first colour and its drawing simply stand */
.place[data-group="colecciones"] .coll-art i:nth-child(1) { opacity: .26; }
@media (prefers-reduced-motion: no-preference) {
  .place[data-group="colecciones"] .coll-art i:nth-child(1) { opacity: 0; --draw: 0%; }
  .place[data-group="colecciones"].is-run .place-band { animation: coll-colour 30s ease-in-out infinite !important; }
  .place[data-group="colecciones"].is-run .coll-art i { animation: coll-draw-in 30s ease-in-out infinite backwards; }
  .place[data-group="colecciones"].is-run .coll-art i:nth-child(2) { animation-delay: 10s; }
  .place[data-group="colecciones"].is-run .coll-art i:nth-child(3) { animation-delay: 20s; }
}
@keyframes coll-colour {
  0%, 30% { background-color: #F2C316; color: #0B0B0B; }
  37%, 63% { background-color: #1B3B8C; color: #FFFFFF; }
  70%, 96% { background-color: #7F2B17; color: #FFFFFF; }
  100% { background-color: #F2C316; color: #0B0B0B; }
}
/* each strip: drawn in over about 5 s, held, then let go as the colour turns */
@keyframes coll-draw-in {
  0% { --draw: 0%; opacity: 0; }
  2% { opacity: .3; }
  17% { --draw: 135%; opacity: .3; }
  31% { --draw: 135%; opacity: .3; }
  38%, 100% { --draw: 135%; opacity: 0; }
}

/* HAGODIGITAL, SMALLER THAN HIS MARK (JP, 27/10): its bold white weight reads larger at the same height */
.foot-credit-logo img { height: 1.6rem !important; }

/* =============================================================================
   27/10 ROUND 9. In collections, DRAWN (JP: "drawing, very gently... every time it changes the colour
   it draws a new pattern"). The band turns slowly through yellow, deep blue and red-brown; in each
   colour a new passage of his own line-work (traced from his painting, assets/motion/coll-lines.json)
   is drawn in stroke by stroke from inside a figure outward, by templates/_coll_draw.js. The script
   owns the colour now, so the CSS cycles of rounds 6-8 are switched off here. */
.place[data-group="colecciones"].is-run .place-band { animation: none !important; }
.place[data-group="colecciones"] .coll-art i { display: none; }
.coll-art { -webkit-mask-image: none; mask-image: none; }
.coll-art svg { display: block; width: 100%; height: 100%; }

/* HAGODIGITAL BETWEEN THE LAST TWO SIZES (JP, 27/10 night): 22px beside his 36px mark */
.foot-credit-logo img { height: 1.4rem !important; }

/* CONTRAST (audit 27/10): the small photo credit and its licence link read 3.8:1 on black; lighter passes */
.place-credit, .place-credit a { color: #9A9A9A !important; }

/* 27/10 ROUND 10. The drawn bands: In collections mirrors the hero (templates/pages/obra.html), Contact
   blooms from behind its words (contacto.html); both by assets/motion/line-draw.js, which owns the colour. */
.coll-art svg, .line-art svg { position: absolute; left: 0; top: 0; overflow: visible; }
.opener--contacto.is-drawn { position: relative; isolation: isolate; animation: none !important; }
.opener--contacto.is-drawn .line-art { position: absolute; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
.opener--contacto.is-drawn > :not(.line-art) { position: relative; z-index: 1; }
/* PHONE: the Contact band had no padding, so its heading rose 12px into the hero above */
@media (max-width: 48rem) { .opener--contacto { padding-block: 1.75rem 2rem !important; } }

/* 28/10. In collections on black: his shapes are drawn over it in his colours (templates/pages/obra.html). */
.place[data-group="colecciones"] .place-band { background: #0B0B0B !important; color: #F4F1EA !important; transition: none !important; }
/* HAGODIGITAL A LITTLE BIGGER (JP, 28/10): 24px beside his 36px mark */
.foot-credit-logo img { height: 1.5rem !important; }

/* PHONE MENU (JP, 28/10): Work and its places are one group, closed by the same long line as every other item. */
@media (max-width: 48rem) {
  header nav .nav-sub { border-bottom: 1px solid rgb(207, 201, 188); padding-bottom: .6rem; }
  header nav .nav-sub > a { display: inline-block; border-bottom: 0 !important; }
}

/* PHONE FILTERS (JP, 28/10: "always be able to show all the filters"). Two rows on the sticky black bar:
   the four types across the whole width, every one visible, then the place picker on its own line. */
@media (max-width: 48rem) {
  .placebar-in { flex-wrap: wrap !important; row-gap: 0 !important; column-gap: 0 !important; padding: .15rem 1rem .1rem !important; box-sizing: border-box; max-width: 100%; }
  .placebar .typemenu { order: 1; flex: 1 0 100% !important; width: 100%; min-width: 0; }
  .placebar .typemenu-btn { display: none !important; }
  .placebar .typemenu-list { flex: 1; display: flex !important; justify-content: space-between; gap: .25rem; width: 100%; margin: 0; }
  .placebar .typemenu-list [role=option] { font-size: .9rem !important; padding: .6rem 0 .5rem; white-space: nowrap; }
  .placebar .placebar-go { order: 2; flex: 1 0 100% !important; width: 100%; border-top: 1px solid rgba(255, 255, 255, .16); }
  .placebar .citybtn { width: 100%; justify-content: space-between; padding-block: .55rem; font-size: .9rem !important; }
  html:has(.placebar) { scroll-padding-top: 10.5rem; }
}

/* the picture in the middle of a wall carousel opens large on a tap (28/10) */
.wc-slide.is-current:not(.wc-slide--clip) img { cursor: zoom-in; }

/* HIS STATEMENT IN PIECES (Nico, 30/10): a line of it under a section title, in his italics */
body .statement-frag { margin: .75rem 0 0; max-width: 36rem; font-family: var(--sans); font-style: italic;
  font-size: var(--t-reg); line-height: 1.6; opacity: .8; }

/* IN COLLECTIONS, A PLAIN TITLE BAND (Nico, 30/10): no painted faces, no turning colours,
   no drifting marks -- the first hero stays the only one. Black, JP's pick 31/10. */
.place[data-group="colecciones"] .place-band { animation: none !important; background: #0B0B0B !important; color: #FFFFFF !important;
  min-height: 0 !important; display: block !important; }
.place[data-group="colecciones"] .place-band::before,
.place[data-group="colecciones"] .place-band::after { content: none !important; }

/* THE PROCESS IN HIS OWN WORKS (Nico, 30/10; JP 01/11: out of their frames, all four the same size).
   The files are cut to 3:4 at 750x1000, so cover fills the box and nothing is letterboxed. */
.nico-process-img--photo { width: 100%; max-width: 15rem; aspect-ratio: 3 / 4; height: auto; object-fit: cover; }

/* QUIET CAROUSEL CONTROLS (JP, 01/11: the drawn arrows and the big "01 / 27" were "horribles").
   The wall carousel now wears the home reel's controls: two thin round chevrons, nothing else.
   The count stays for screen readers only. */
.wc-bar { gap: .75rem !important; justify-content: center; }
.wc-btn { width: 2.75rem !important; height: 2.75rem !important; border-radius: 50% !important; border: 1px solid currentColor !important;
  background: transparent !important; color: var(--ink) !important; opacity: .7; padding: 0 !important; display: grid; place-items: center;
  transition: opacity .2s var(--ease), background .2s var(--ease), color .2s var(--ease) !important; transform: none !important; }
.wc-btn svg { width: 1.1rem !important; height: 1.1rem !important; stroke-width: 1.6 !important; }
.wc-btn:hover, .wc-btn:focus-visible { opacity: 1; background: var(--ink) !important; color: var(--paper) !important; transform: none !important; }
.wc-count { position: absolute !important; width: 1px !important; height: 1px !important; overflow: hidden !important; clip: rect(0 0 0 0) !important; white-space: nowrap !important; }

/* THE ROOM LIST (JP, 03/11): white air between the hero and the first city photograph.
   !important because the site's late type resets (p, a) otherwise win. */
.placeindex.band { padding-block: clamp(3.5rem, 8vw, 6.5rem); text-align: center; }
.placeindex-in { display: flex; flex-direction: column; align-items: center; gap: 1.25rem; }
.placeindex .placeindex-k { margin: 0 !important; color: var(--ink-soft) !important; font: 400 var(--t-nav)/1.4 var(--sans) !important;
  letter-spacing: .14em !important; text-transform: uppercase !important; }
.placeindex-list { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; justify-content: center; gap: .35rem clamp(1.25rem, 3vw, 2.75rem); }
.placeindex .placeindex-list a, .placeindex .placeindex-sold a { color: var(--ink) !important; text-decoration: none !important;
  font-family: var(--display-face, var(--serif)) !important; font-weight: 400 !important;
  font-size: clamp(1.6rem, 1rem + 2.4vw, 3rem) !important; line-height: 1.1 !important; letter-spacing: .06em !important; text-transform: uppercase !important;
  background: linear-gradient(currentColor, currentColor) 0 100% / 0 1px no-repeat; transition: background-size .35s cubic-bezier(.22, 1, .36, 1); }
.placeindex a:hover, .placeindex a:focus-visible { background-size: 100% 1px; }
.placeindex .placeindex-sold { margin: .5rem 0 0 !important; }
.placeindex .placeindex-sold a { font-size: clamp(1.1rem, .9rem + 1vw, 1.5rem) !important; color: var(--ink-soft) !important; }
/* PROCESS PHOTOS SMALLER (JP, 03/11): about a third down on desktop and on the phone. */
.nico-process-img--photo { max-width: 10.5rem; }
@media (max-width: 640px) { .nico-process-img--photo { max-width: 9rem; } }

/* IN COLLECTIONS SHADED (JP, 03/11): a city band's height, Home's reviews fade, lettering black.
   Replaces the plain black band of 30/10; the selectors match that rule's and add !important to win. */
.place[data-group="colecciones"] .place-band.place-band--coll { background: var(--paper) !important; color: var(--ink) !important;
  min-height: clamp(13.5rem, 29vw, 22rem) !important; display: flex !important; align-items: center; }
.place[data-group="colecciones"] .place-band.place-band--coll::before { content: "" !important; position: absolute; inset: 0 !important; z-index: 0; pointer-events: none;
  opacity: 1 !important; mix-blend-mode: normal !important; transform: none !important; animation: none !important;
  -webkit-mask-image: none !important; mask-image: none !important;
  background: linear-gradient(to right, var(--paper) 0%, var(--paper) 18%, rgba(244, 241, 234, .35) 42%, rgba(244, 241, 234, 0) 66%),
    var(--shade-img) 70% center / cover no-repeat, var(--paper) !important; }
.place[data-group="colecciones"] .place-band--coll .place-band-in { position: relative; z-index: 1; width: 100%; }
.place[data-group="colecciones"] .place-band--coll .place-name { color: var(--ink) !important; }
@media (max-width: 640px) {
  .place[data-group="colecciones"] .place-band.place-band--coll::before {
    background: linear-gradient(to right, var(--paper) 0%, var(--paper) 44%, rgba(244, 241, 234, .55) 58%, rgba(244, 241, 234, 0) 86%),
      var(--shade-img) 65% center / cover no-repeat, var(--paper) !important; }
}

/* THE PDF BUTTON ON A PHONE (JP, 04/11: tapping it opened Creative Commons at Caracas). The photo credit sat
   absolutely over the button's lower half. On a phone it now follows the button, and the button is a full target. */
@media (max-width: 52rem) {
  .place-title { display: flex; flex-direction: column; align-items: flex-start; }
  .place-pdf { order: 2; display: inline-block; padding-block: .7rem; }
  .place-band .place-credit { order: 3; position: static; margin: .35rem 0 0; }
  .place-credit a { font-size: inherit !important; }
}
