/* Eddie Fitzgerald: the design layer (2026-10-21; polish pass 2026-10-23).
   A quiet gallery wall: a warm off-white by default, the art carries the colour. Two faces (review 2026-10-22): a
   display face (--f-display, server.js DISPLAY_FACES) for his name, the page headings, the hero line, the pop-up title
   and the footer name; Schibsted Grotesk for everything else. The display face is Gloock (T, 2026-10-22), his name too
   unless Rest of Site → The look says otherwise. Sharp corners throughout.
   Colours come from Rest of Site → Colours (--c-*, written in partials/head.ejs); every other tone is mixed from
   them, so a chosen background or ink carries through the whole page.
   Polish pass (2026-10-23, T's brief): the hero as a split (the piece beside his line and a button), the nav with a
   stronger current page and Contact as a button, one accent colour for links, buttons and hover, a wider Contact form.
   Each change is marked "POLISH" below.
   Mosaic pass (2026-10-26, T's brief, ../_intake/brief-2026-10-26-mosaic.md): every piece under the hero in a mosaic
   with 12px between them and nacharlet's hover (the picture grows, a caption rises); a frame with depth on every piece;
   the pop-up as a large picture with its words under it; the top and bottom bars with a colour and a veil of their
   own; the box behind words over a background photograph on a slider. Marked "MOSAIC" below. */

:root {
  /* POLISH: the page is a warm off-white (#f8f7f5) rather than pure white, so the white-backed photographs and the
     off-white panels sit on a wall, not in a void. Rest of Site → Colours still overrides it. */
  --bg: var(--c-bg, #f8f7f5);
  --ink: var(--c-ink, #1b1d1f);
  --muted: color-mix(in srgb, var(--ink) 66%, var(--bg));   /* 5.3:1 on the off-white */
  --line: color-mix(in srgb, var(--ink) 14%, var(--bg));
  --field: color-mix(in srgb, var(--ink) 58%, var(--bg)); /* field edges at 3:1 or more (WCAG 1.4.11) */
  /* POLISH: one accent, a deep sea green drawn from the resin (pieces #2 and #6): links, buttons, the current page,
     hover and focus. 6.9:1 on the off-white, and the off-white reads on it at the same ratio. Rest of Site → Colours
     overrides it; the hover shade is mixed from it so a chosen accent darkens the same way. */
  --accent: var(--c-accent, #1f5f58);
  --accent-ink: var(--c-accent-ink, var(--bg));
  --accent-hover: color-mix(in srgb, var(--ink) 18%, var(--accent));
  --font: 'Schibsted Grotesk', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --display: var(--f-display, var(--font));

  /* The type ladder (review 2026-10-22; hero step added 2026-10-23): each step at least 3px from the next at every width.
     1440: heading 1 60, hero line 40, name 36, heading 2 32, lead 24, body 18, menu 16, caption 15.
      390: heading 1 38, name 31, heading 2 and hero line 26, lead 22, body 18, menu 16, caption 15. Nothing under 15px. */
  /* The page heading's size is set in Rest of Site → The look (--head-size, 60px at 1440 unless changed; T, 2026-10-27):
     at a computer that size, growing from 63% of it at 390. */
  --t-h1: clamp(max(2rem, var(--head-size, 60px) * .633), calc(var(--head-size, 60px) * .633 + (100vw - 390px) * var(--head-n, 60) * .367 / 1050), var(--head-size, 60px));
  --t-hero: clamp(1.625rem, 1.1rem + 2vw, 2.5rem);
  --t-h2: min(clamp(1.625rem, 1.5rem + .6vw, 2rem), calc(var(--t-h1) * .8)); /* always a step below the page heading */
  --t-lead: clamp(1.375rem, 1.3rem + .25vw, 1.5rem);
  --t-h3: var(--t-lead);
  --t-body: 1.125rem;
  --t-menu: 1rem;
  --t-small: 0.9375rem;

  --max: 1360px;
  --gutter: clamp(20px, 4.4vw, 64px);
  --head-h: 98px; /* the bar at the top: 84px until T, 2026-10-26 ("about 15 to 20% wider"); 78px on a phone */
  --gap: clamp(20px, 2.8vw, 44px);
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  /* MOSAIC: 12px between the pieces of a mosaic at every width (the bands in server.js assume the same). */
  --gap-mosaic: 12px;
  /* MOSAIC: the frame on every piece (brief item 8): a thin mat in the page's ground inside a hairline of the ink at
     low strength, and a shadow tinted from the ink, stronger at the bottom edge. Quiet on purpose: resin has its own
     edge, and a frame that fights it is worse than none. --mat is the mat's width; tiles 6px, the hero and pop-up 12px. */
  --mat: 6px;
  --frame-edge: color-mix(in srgb, var(--ink) 16%, transparent);
  --frame-shadow: 0 1px 2px color-mix(in srgb, var(--ink) 14%, transparent), 0 12px 28px -12px color-mix(in srgb, var(--ink) 40%, transparent);
  /* MOSAIC: the top and bottom bars (brief item 1): a colour each from Rest of Site (--c-bar, --c-foot, else the
     background) under a veil 0 to 100 (--c-bar-veil, --c-foot-veil) saying how much of it lies over what is behind. */
  --bar: var(--c-bar, var(--bg));
  --bar-veil: var(--c-bar-veil, 100);
  --foot: var(--c-foot, var(--bg));
  --foot-veil: var(--c-foot-veil, 100);
}

/* ─── Base ─────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html { background: var(--bg); -webkit-text-size-adjust: 100%; }
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font-family: var(--font); font-size: var(--t-body); line-height: 1.6; font-weight: 400;
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
}
img { display: block; max-width: 100%; }
a { color: inherit; }
h1, h2, h3 { margin: 0; line-height: 1.15; text-wrap: balance; }
/* The headings (page headings, the smaller ones inside pages, the pop-up's title) take the face set in Rest of Site →
   The look, Page headings (--f-head*; T, 2026-10-27). His name in the footer keeps the headings' original face. */
h1, h2, .pb-title, .foot-wm, .hero-line {
  font-family: var(--display); font-weight: var(--f-display-weight, 600); letter-spacing: var(--f-display-track, -0.02em);
  font-synthesis: none; /* a one-weight face is never thickened by the browser */
}
h1, h2, .pb-title {
  font-family: var(--f-head, var(--display)); font-weight: var(--f-head-weight, var(--f-display-weight, 600));
  letter-spacing: var(--f-head-track, var(--f-display-track, -0.02em)); font-style: var(--f-head-style, normal);
}
h1 { font-size: var(--t-h1); line-height: 1.08; }
h2 { font-size: var(--t-h2); }
h3 { font-size: var(--t-h3); font-weight: 600; letter-spacing: -0.01em; }
p { margin: 0; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.sr { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.skip { position: absolute; left: var(--gutter); top: -60px; z-index: 900; padding: .6rem 1rem; background: var(--ink); color: var(--bg); text-decoration: none; }
.skip:focus { top: 12px; }
.wrap { width: 100%; max-width: var(--max); margin-inline: auto; padding-inline: var(--gutter); }
main { display: block; min-height: 50vh; }

.text-link { display: inline-flex; align-items: center; min-height: 44px; color: var(--accent); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 5px; font-weight: 500; transition: color .15s; }
.text-link:hover { color: var(--accent-hover); text-decoration-thickness: 2px; }
.small { font-size: var(--t-small); color: var(--muted); }

/* ─── The photograph behind the pages (optional) ───────────────── */
/* A fixed layer under everything, under a veil of the background colour: lighter on the pages of art, heavier
   on the pages of words (Beara's lesson: running text never reads over a texture). */
body.has-bg, html:has(body.has-bg) { background: var(--bg); }
.bg-layer { position: fixed; inset: 0; z-index: -1; overflow: hidden; pointer-events: none; }
.bg-layer img { width: 100%; height: 100%; object-fit: cover; }
.bg-layer::after { content: ""; position: absolute; inset: 0; background: color-mix(in srgb, var(--bg) var(--veil), transparent); }
body.has-bg { background: transparent; }
/* MOSAIC: the box behind the words beside the piece at the top and beside a collection, over the photograph: its
   strength is --cap-veil (Rest of Site, 0 to 100, 86 by default); at 0 there is no box and no padding. The mosaic's
   own captions are the dark panel on hover, so they need none. */
body.has-bg .hero-label {
  background: color-mix(in srgb, var(--bg) calc(var(--cap-veil, 86) * 1%), transparent);
  padding: calc(min(var(--cap-veil, 86), 1) * .6rem) calc(min(var(--cap-veil, 86), 1) * .75rem);
}
/* The box fitted to the words, like a gallery wall label (T, 2026-10-31; Rest of Site → Home page, "The box behind the
   line", the default): the column itself goes clear and the line carries the box, held to 30rem so a long line breaks
   into a few short ones rather than a thin strip. The arrow has a small box of its own, or it is lost on the
   photograph. The caption veil still sets how see-through both are; at 0 there is no box. "Fills the column" is the
   rule above, as before. */
body.has-bg .hero-label.box-fit { background: none; padding: 0; }
body.has-bg .hero-label.box-fit h1 {
  justify-self: start; width: fit-content; max-width: min(100%, 30rem);
  background: color-mix(in srgb, var(--bg) calc(var(--cap-veil, 86) * 1%), transparent);
  padding: calc(min(var(--cap-veil, 86), 1) * 1.4rem) calc(min(var(--cap-veil, 86), 1) * 1.6rem);
  box-shadow: 0 1px 2px color-mix(in srgb, var(--ink) 8%, transparent);
}
/* Beside the piece the label takes three quarters of the space beside it (T, 2026-11-03: beside a tall, skinny piece
   the 30rem label wrapped his line into five short lines in a wide empty space), never narrower than 30rem and never
   wider than 44rem, about three lines of his line, so it never becomes a thin strip. Beside a wide piece the space is
   narrow and the label simply fills it, as before; under the piece (a phone) it stays at 30rem. */
body.has-bg .hero-label.box-fit.is-beside h1 { max-width: min(100%, clamp(30rem, 75%, 44rem)); }
body.has-bg .hero-label.box-fit .hero-down {
  justify-self: start; margin-top: .75rem; margin-left: 0;
  background: color-mix(in srgb, var(--bg) calc(var(--cap-veil, 86) * 1%), transparent);
}

/* ─── Header ───────────────────────────────────────────────────── */
.site-head {
  position: sticky; top: 0; z-index: 400;
  /* MOSAIC: the bar's own colour under its veil; at a low veil the art scrolls under the menu. */
  background: color-mix(in srgb, var(--bar) calc(var(--bar-veil) * 1%), transparent);
  transition: transform .35s var(--ease), box-shadow .2s, background-color .2s;
}
/* The words on the bar (T, 2026-10-31): a colour of their own from Rest of Site (--c-bar-ink), else the Words colour;
   the hairline under the raised bar is mixed from them. */
.site-head { --ink: var(--c-bar-ink, var(--c-ink, #1b1d1f)); --line: color-mix(in srgb, var(--ink) 14%, var(--bar)); color: var(--ink); }
.site-head.is-away { transform: translateY(-100%); }
.site-head:focus-within { transform: none; } /* a keyboard visitor tabbing into a hidden header brings it back */
.site-head.is-raised { box-shadow: 0 1px 0 var(--line); }
/* Below the top of the page the bar is solid: its own colour at its veil laid on the background colour, so the page
   goes behind it and nothing shows through (T, 2026-11-03: the heading showed through the see-through bar, and a
   frosted bar made it a grey smudge). At the very top it is as set in Rest of Site. */
.site-head.is-raised:not(.has-img) { background: color-mix(in srgb, var(--bar) calc(var(--bar-veil) * 1%), var(--bg)); }
.head-row { height: var(--head-h); display: flex; align-items: center; justify-content: space-between; gap: 2rem; }
.wm-link { text-decoration: none; color: var(--ink); display: inline-flex; align-items: center; min-height: 44px; }
.wm {
  font-synthesis: none;
  font-family: var(--wm-font, var(--display)); font-weight: var(--wm-weight, 500); font-size: var(--wm-size, 30px);
  letter-spacing: var(--wm-track, -0.01em); font-style: var(--wm-style, normal); text-transform: var(--wm-transform, none);
  font-variant-caps: var(--wm-caps, normal); line-height: 1.1; white-space: nowrap;
}
.wm-crop { display: inline-block; overflow: hidden; line-height: 0; max-width: 60vw; }
.wm-logo { height: var(--logo-h, 44px); width: auto; max-width: 60vw; }
/* POLISH: the menu. Wider spacing, the links a touch heavier, the current page marked by a 2px rule in the accent
   (a 1px hairline on hover). Contact is a link like the others, with no box (T, 2026-10-26).
   The menu stays at 16px: the ladder keeps it a step below the body. */
.menu ul { list-style: none; margin: 0; padding: 0; display: flex; align-items: center; gap: clamp(1.5rem, 3vw, 2.75rem); }
.menu a { position: relative; display: inline-flex; align-items: center; min-height: 44px; min-width: 44px; font-size: var(--t-menu); font-weight: 500; color: var(--ink); text-decoration: none; }
.menu a::after { content: ""; position: absolute; left: 0; right: 0; bottom: 8px; height: 1px; background: currentColor; opacity: 0; transition: opacity .15s; }
.menu a:hover::after { opacity: 1; }
.menu a[aria-current="page"]::after { height: 2px; background: var(--accent); opacity: 1; }
.burger { display: none; }
/* The other language (2026-10-22): after the menu on a computer, set apart by a hairline; two letters beside the three
   lines on a phone. No flags: a language is not a country. */
.menu { margin-left: auto; }
.lang-switch { position: relative; display: inline-flex; align-items: center; min-height: 44px; min-width: 44px; padding-left: clamp(1.5rem, 3vw, 2.75rem); font-size: var(--t-menu); font-weight: 500; color: var(--ink); text-decoration: none; white-space: nowrap; }
.lang-switch::before { content: ""; position: absolute; left: 0; top: 50%; width: 1px; height: 1.1em; transform: translateY(-50%); background: var(--line); }
.lang-switch:hover { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 7px; }
.ls-short { display: none; }

/* ─── Home: the piece at the top ───────────────────────────────── */
/* POLISH (was prompt 4, review 2026-10-22): the piece first and big, whole at its own shape, about three quarters of
   the first screen tall. Beside it, on the piece's floor, his line in the display face, the piece's label and one
   button (the "see all the work" words). The row wraps by itself: a square or upright piece leaves room for the
   words beside it; a wide piece (over about 1.35 to 1 at 1440) takes the page's width and its words go underneath,
   as they do on a phone. --hero-h is the piece's height when the width allows it. */
/* MOSAIC (brief item 3): the piece a little larger, 5rem under it instead of 9 (736px tall at 1440 x 900, 82%); a wide
   piece still fits the first screen because its width is capped by the measure. In its frame (item 8), a 12px mat. */
/* 2026-10-26 (T, item 3): no caption and no button; the piece larger again (3rem under it), less room above it, and the
   mosaic closer under it. An arrow at the piece's floor, under his line, says there is more below. */
.hero { --hero-under: 3rem; --hero-h: calc(100svh - var(--head-h) - var(--hero-under)); padding-top: clamp(12px, 1.6vw, 24px); padding-bottom: clamp(40px, 5vw, 64px); }
.hero-frame { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 2rem clamp(32px, 5vw, 72px); }
/* The picture's shape is on the box inside the mat (.hero-img), not on the frame: on the frame it took the mat into the
   shape, and a tall narrow piece (Piece #6, 1 to 3) had 24px of extra white above and below it (T, 2026-10-31). The
   frame is the picture plus the mat; its width makes the whole frame --hero-h tall. */
.hero-piece { --mat: 12px; display: block; flex: 0 1 calc((var(--hero-h) - 2 * var(--mat)) * var(--ar, 1) + 2 * var(--mat)); max-width: 100%; min-width: min(100%, 18rem); padding: var(--mat); background: var(--bg); box-shadow: inset 0 0 0 1px var(--frame-edge), var(--frame-shadow); }
.hero-img { display: block; width: 100%; aspect-ratio: var(--ar, 1); }
.hero-piece img { width: 100%; height: 100%; object-fit: contain; }
/* His line (2026-10-26, T): it takes the whole column beside the piece (no 22ch cap, which wrapped it early) and sits
   at the piece's top, middle or foot as Rest of Site says (at-top, at-middle, at-bottom); the arrow stays at the
   piece's foot. The column stretches to the piece's height so the line can be placed in it. Its typeface, size
   (at a computer; 65% of it on a phone, growing with the width), weight and italic come from Rest of Site → Home page
   (--hero-*, partials/head.ejs). Under a wide piece, or on a phone, the column has no spare height and the line
   simply follows the piece. */
.hero-label { flex: 1 1 18rem; min-width: 0; align-self: stretch; display: grid; grid-template-rows: auto auto; justify-items: start; }
.hero-label h1 {
  font-family: var(--hero-font, var(--display)); font-weight: var(--hero-weight, 400); font-style: var(--hero-style, normal);
  letter-spacing: var(--hero-track, 0em);
  font-size: clamp(calc(var(--hero-size, 40px) * .65), calc(var(--hero-size, 40px) * .65 + (100vw - 390px) * var(--hero-n, 40) * .35 / 1050), var(--hero-size, 40px));
  line-height: 1.18; text-wrap: pretty;
}
.hero-down { align-self: end; margin-top: 1rem; }
/* Beside the piece (main.js marks it is-beside), a grid of three rows: the line in the middle row between two equal
   ones, so it is centred on the piece itself, and the arrow at the foot of the last; at the top, the line takes the
   first row; at the foot, the line sits on the arrow. Under the piece (a wide piece, a phone) it is the line, then the
   arrow. */
.hero-label.is-beside { grid-template-rows: 1fr auto 1fr; }
.hero-label.is-beside h1 { grid-row: 2; }
.hero-label.is-beside .hero-down { grid-row: 3; }
.hero-label.is-beside.at-top { grid-template-rows: auto 1fr; }
.hero-label.is-beside.at-top h1 { grid-row: 1; }
.hero-label.is-beside.at-top .hero-down { grid-row: 2; }
.hero-label.is-beside.at-bottom { grid-template-rows: 1fr auto auto; }
.hero-label.is-beside.at-bottom .hero-down { margin-top: .5rem; }
.hero-down { display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 56px; margin-left: -10px; color: var(--ink); opacity: .7; transition: opacity .2s, color .2s; }
.hero-down:hover { opacity: 1; color: var(--accent); }
.hero-down svg { width: 18px; height: 30px; fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; }

/* ─── Home: the news (T, 2026-10-31) ─────────────────────────────── */
/* Between the piece at the top and the mosaic, a band a shade off the ground with a hairline above and below (the
   collection band's treatment), so it reads as a notice and not as one of the pieces. Each item on the About page's
   split, 5 to 7: the heading with when and where under it, then its words and link. Two or more are parted by a
   hairline. Over a photograph behind the pages the band takes the background colour at the caption veil. */
.news-band { background: color-mix(in srgb, var(--ink) 4%, var(--bg)); border-block: 1px solid var(--line); padding-block: clamp(32px, 4vw, 56px); margin-bottom: clamp(28px, 3.5vw, 44px); }
body.has-bg .news-band { background: color-mix(in srgb, var(--bg) calc(var(--cap-veil, 86) * 1%), transparent); }
/* The words sit on the heading's first line (T, 2026-10-31): first-baseline alignment, still top-aligned, so the 18px
   words no longer float above a 32px heading. */
.news-item { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 1rem clamp(32px, 5vw, 88px); align-items: first baseline; }
.news-item + .news-item { margin-top: clamp(28px, 3.5vw, 44px); padding-top: clamp(28px, 3.5vw, 44px); border-top: 1px solid var(--line); }
.news-head h2 { font-size: var(--t-h2); }
.news-when { margin-top: .6rem; color: var(--muted); }
.news-words .prose > :last-child { margin-bottom: 0; }
.news-words .rich-text > div:has(> br:only-child) { display: none; }
.news-link { margin-top: .5rem; }
.news-link .text-link { margin-left: 0; }
/* The mosaic's own hairline would double the band's lower edge. */
.news-band + .sample::before { border-top: 0; padding-bottom: 0; }

/* ─── Grids of pieces ──────────────────────────────────────────── */
/* POLISH: the mosaic opens on a hairline, so the hero and the mosaic read as two rooms, not one long drop. */
.sample { padding-bottom: clamp(72px, 9vw, 120px); }
.sample::before { content: ""; display: block; border-top: 1px solid var(--line); padding-bottom: clamp(28px, 3.5vw, 44px); }
.sample-more { margin-top: clamp(20px, 2.5vw, 32px); } /* a chosen few on the home page: the link on to All work */ /* on the content's edges, like the Get in touch rule */
.grid { list-style: none; margin-block: 0; padding-block: 0; display: grid; gap: clamp(28px, 3.2vw, 44px) var(--gap); }
.sample .grid { padding-inline: 0; }
.grid li { min-width: 0; }
.gm-item.is-hidden { display: none; }
/* The Work page: justified rows (review 2026-10-22). Each piece whole at its own shape; every row one height and the
   measure's width; the last row at the usual height, from the left. The server works out each piece's share of its
   row (--f) and the gaps in that row (--n) for three bands; --ar is its shape.
   POLISH: the row gap comes down (52 to 44 at 1440): the captions already hold the rows apart. */
.grid-justified { list-style: none; margin-block: 0; padding-block: 0; display: flex; flex-wrap: wrap; align-items: flex-start; gap: clamp(28px, 3.2vw, 44px) var(--gap); }
.grid-justified > li { flex: 0 0 auto; min-width: 0; width: calc((100% - var(--nl, 0) * var(--gap)) * var(--fl, .25)); }
.grid-justified .tile-frame { aspect-ratio: var(--ar, 1); }
/* MOSAIC (brief item 4): the rows sit 12px apart in both directions, a wall of pieces. */
.mosaic { --gap: var(--gap-mosaic); gap: var(--gap-mosaic); }
.sample .grid-justified { padding-inline: 0; }
/* MOSAIC: a tile is the piece in its frame (the link that opens the pop-up) with the caption laid over it, outside the
   link so Enquire is a link of its own. The frame keeps its exact shape, so contain and cover are the same thing
   here; a cropped shape is the piece's own choice in the site manager (is-cropped). The picture sits in a clipped box
   inside the mat and grows to 1.05 over .65s on hover (nacharlet's curve); the framing from the site manager is a
   transform on the img itself, so the growing is done by the box around it (tile-pic). */
.tile { position: relative; display: block; container-type: inline-size; }
.tile-frame { display: block; aspect-ratio: 1; padding: var(--mat); background: var(--bg); box-shadow: inset 0 0 0 1px var(--frame-edge), var(--frame-shadow); text-decoration: none; color: inherit; }
.tile-img { display: block; position: relative; width: 100%; height: 100%; overflow: hidden; }
.tile-pic { display: block; width: 100%; height: 100%; transition: transform .65s cubic-bezier(.25, 0, .25, 1); }
.tile-pic img { width: 100%; height: 100%; object-position: center bottom; }
.tile-frame.is-cropped img { object-position: center; }
/* Keyboard focus shows the caption too, but not focus a mouse click left behind (2026-10-26, item 10): :focus-visible. */
.tile:hover .tile-pic, .tile:has(:focus-visible) .tile-pic { transform: scale(1.05); }
/* MOSAIC: the caption rises from the bottom edge of the picture on a dark gradient (nacharlet's), white words in the
   site's own type and sentence case: the title, the medium and year, then Sold or an outlined Enquire link. It is a
   layer over the picture that lets clicks through to the link beneath, except on Enquire. On a touch screen it shows
   all the time. */
.tile-cap { position: absolute; inset: var(--mat); overflow: hidden; pointer-events: none; overflow-wrap: anywhere; }
.tile-cap-in {
  position: absolute; left: 0; right: 0; bottom: 0; display: flex; flex-direction: column; align-items: flex-start; gap: .1rem;
  padding: 2.4rem 1rem .9rem; color: #fff; text-shadow: 0 1px 4px rgba(0, 0, 0, .5);
  background: linear-gradient(0deg, rgba(20, 18, 16, .92), rgba(20, 18, 16, .72) 40%, transparent);
  transform: translateY(100%); transition: transform .4s cubic-bezier(.25, 0, .25, 1);
}
.tile:hover .tile-cap-in, .tile:has(:focus-visible) .tile-cap-in { transform: translateY(0); }
.tile-title { font-weight: 500; font-size: var(--t-menu); line-height: 1.35; }
.tile-meta { font-size: var(--t-small); color: var(--muted); }
.tile-meta:empty { display: none; }
.tile-cap .tile-meta { color: rgba(255, 255, 255, .88); }
.tile-sold { margin-top: .35rem; font-size: var(--t-small); font-weight: 500; color: rgba(255, 255, 255, .88); }
.tile-ask {
  pointer-events: auto; display: inline-flex; align-items: center; min-height: 44px; margin-top: .25rem; padding: 0 1rem;
  border: 1px solid rgba(255, 255, 255, .6); color: #fff; text-decoration: none; font-size: var(--t-small); font-weight: 500;
  transition: background-color .25s, border-color .25s;
}
.tile-ask:hover { background: rgba(255, 255, 255, .18); border-color: #fff; }
@media (hover: none) { .tile-cap-in { transform: none; } }
/* A small tile (a phone's two across, a narrow upright piece) has no room for the Enquire link: the title alone, and
   the pop-up carries the Ask button. Under 200px the link loses its padding; under 150px it goes. */
.tile-ask { white-space: nowrap; }
@container (max-width: 200px) { .tile-cap-in { padding: 1.4rem .6rem .5rem; } .tile-ask { padding: 0 .6rem; } }
@container (max-width: 150px) { .tile-ask, .tile-cap .tile-meta { display: none; } }
.more { margin-top: clamp(32px, 4vw, 48px); }

/* ─── Page openings ────────────────────────────────────────────── */
/* POLISH: the opening sits a little closer to what follows it (88 to 72 at the top, 56 to 40 under it). */
.page-top { padding-top: clamp(36px, 5vw, 72px); padding-bottom: clamp(28px, 3.5vw, 40px); }
/* A page heading eases down to fit a phone's width (9vw: 35px at 390) so "Terms and conditions" and "Conditions
   générales" stay on one line rather than leaving a word alone (2026-10-26). From about 670px wide it is the ladder's. */
.page-top h1 { font-size: min(var(--t-h1), 9vw); }
.page-top .lead { margin-top: 1rem; }
.page-top p + p { margin-top: 1.5rem; }
.lead { font-size: var(--t-lead); line-height: 1.5; max-width: 52ch; }
/* No back and next links at the foot of a page (T, 2026-10-26, item 4): the last block keeps the room under it. */
.page-end { padding-bottom: clamp(72px, 9vw, 120px); }
.empty-note { padding-bottom: 80px; color: var(--muted); }

/* Gallery groups (Rest of Site → Gallery).
   POLISH: a row of tabs on a hairline: every name in the ink, the chosen one carrying a 2px accent rule that sits on
   the hairline, the label small and muted at the left, "All work" at the far right (T, 2026-10-21). */
.series-tabs { display: flex; flex-wrap: wrap; align-items: stretch; gap: 0 clamp(1.25rem, 2.4vw, 2rem); border-bottom: 1px solid var(--line); }
.work-grid { margin-top: clamp(32px, 4vw, 48px) !important; }
.tabs-label { display: inline-flex; align-items: center; font-size: var(--t-small); color: var(--muted); margin-right: .25rem; }
.series-tabs .tab-all { margin-left: auto; }
@media (max-width: 720px) { .tabs-label { flex: 1 1 100%; padding-top: .25rem; } .series-tabs .tab-all { margin-left: 0; } }
/* "All work" is a link to the home page's mosaic while the home page shows every piece (2026-10-26): it looks the same. */
.series-tabs button, .series-tabs a.tab-all {
  position: relative; display: inline-flex; align-items: center; min-height: 48px; padding: 0 .1rem; border: 0; background: none; cursor: pointer; text-decoration: none;
  font: inherit; font-size: var(--t-menu); font-weight: 500; color: var(--muted); transition: color .15s;
}
.series-tabs button::after, .series-tabs a.tab-all::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; background: var(--accent); opacity: 0; transition: opacity .15s; }
.series-tabs button:hover, .series-tabs a.tab-all:hover { color: var(--ink); }
.series-tabs button.active { color: var(--ink); }
.series-tabs button.active::after { opacity: 1; }
/* 2026-10-26 (T, item 7, after nacharlet's): under the row, the chosen collection's picture and words in a band of
   their own across the page, a shade off the ground with a hairline under it, so the picture never reads as one of
   the pieces below. The picture (4 by 3, framed as on the collection's own screen, no mat and no shadow) floats at the
   left and the words run beside it, then on under it when they are long; a short text sits at the picture's top. The
   band's measure is about 1000px so a line under the picture stays readable. With a photograph behind the pages the
   band takes the background colour at the caption veil's strength. */
.series-desc { background: color-mix(in srgb, var(--ink) 4%, var(--bg)); border-bottom: 1px solid var(--line); padding-block: clamp(28px, 3.5vw, 48px); }
body.has-bg .series-desc { background: color-mix(in srgb, var(--bg) calc(var(--cap-veil, 86) * 1%), transparent); }
.series-desc-inner { display: flow-root; max-width: 62rem; }
/* The picture at its own shape and the width chosen for it (T, 2026-10-26; --sd-w, 320px unless set), never more than
   half the band, cropped as framed: its box is its own shape, so the framing's zoom inside the clipped box shows what the
   frame in the site manager showed. */
.series-desc-pic { float: left; width: min(var(--sd-w, 320px), 50%); margin: .3rem clamp(1.5rem, 3vw, 2.75rem) .75rem 0; }
.sd-crop { display: block; overflow: hidden; line-height: 0; }
.sd-crop img { display: block; width: 100%; height: auto; }
.series-desc-text > div, .series-desc-text > p { margin: 0 0 1em; }
.series-desc-text > :last-child { margin-bottom: 0; }
.series-desc-text > div:has(> br:only-child) { display: none; } /* a blank line typed in the editor: the gap is already there */
.series-desc-text a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 4px; }

/* ─── Words ────────────────────────────────────────────────────── */
/* POLISH: running text at 62 characters a line (was 66) and a steady gap under every heading. */
.prose { max-width: 62ch; }
/* A word or web address longer than the line breaks onto the next line instead of running off the page (T, 2026-11-03). */
.prose, .rich-text, .lead, h1, h2, h3 { overflow-wrap: break-word; }
.prose p, .rich-text > div { margin: 0 0 1.1em; }
.prose h2 { margin: 2.25rem 0 .9rem; }
.prose h2:first-child { margin-top: 0; }
.prose ul, .prose ol { padding-left: 1.2em; margin: 0 0 1.1em; }
.prose a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 4px; }
.prose a:hover { color: var(--accent-hover); }
.rich-text h1 { font-size: var(--t-h2); margin: 2.25rem 0 .9rem; }

/* POLISH: the About photo on 5 of 12 columns, upright (4 : 5), and the words beside it start on the same line as its
   top edge; the Exhibitions heading keeps one steady gap above it. */
.about-grid { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: clamp(32px, 5vw, 88px); align-items: start; }
.about-grid.no-photo { grid-template-columns: minmax(0, 1fr); }
.about-photo { margin: 0; aspect-ratio: 4 / 5; overflow: hidden; }
.about-photo img { width: 100%; height: 100%; object-fit: cover; }
/* His words stay put while his photograph scrolls past them, as the words do beside How I work (T, 2026-10-31: "match
   the functions of How I work, even if it's not visible"). Only the shorter side of a pair can hold still, so this shows
   only while his words are shorter than his photograph. On a computer only; stacked on a tablet and a phone. */
@media (min-width: 901px) { .about-grid > .about-words { position: sticky; top: calc(var(--head-h) + 24px); } }
.about-words > h2 { margin: clamp(36px, 4.5vw, 56px) 0 .9rem; }
/* His words end on their last line, as beside How I work: no space after the last paragraph, no blank line typed in the editor. */
.about-words > :last-child, .about-words .prose > :last-child { margin-bottom: 0; }
.about-words .rich-text > div:has(> br:only-child) { display: none; }
.exh > div { margin-bottom: .35em; }
/* How I work (T, 2026-10-31, second version): under About, opening on a hairline like the mosaic. The photographs on
   7 of 12 and his words on 5 (the About block's split mirrored, so a photograph is never thumbnail small: about 324px
   each two to a row at 1440). Each row is a flex row whose items grow by their shape (--ar) from nothing, so every
   photograph in a row comes out the same height and the row fills the column; one alone in a row is held to 34rem
   tall. The words stay in view beside the photographs while they pass (sticky under the bar). */
.how { padding-top: clamp(8px, 1vw, 16px); }
.how::before { content: ""; display: block; border-top: 1px solid var(--line); padding-bottom: clamp(48px, 6vw, 80px); }
.how > h2 { margin-bottom: clamp(28px, 3.5vw, 44px); }
.how-grid { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: clamp(32px, 5vw, 88px); align-items: start; }
.how-grid.no-photos, .how-grid.no-words { grid-template-columns: minmax(0, 1fr); }
.how-grid.no-words .how-mosaic { max-width: calc((100% - clamp(32px, 5vw, 88px)) * 7 / 12); }
.how-mosaic { display: grid; gap: var(--gap-mosaic); }
.how-mrow { display: flex; gap: var(--gap-mosaic); }
.how-ph { flex: var(--ar) 1 0%; min-width: 0; aspect-ratio: var(--ar); display: block; padding: 0; border: 0; background: color-mix(in srgb, var(--ink) 6%, var(--bg)); overflow: hidden; cursor: zoom-in; }
.how-mrow.solo .how-ph { flex: 0 1 auto; width: 100%; max-width: calc(34rem * var(--ar)); }
.how-ph img { display: block; width: 100%; height: 100%; object-fit: cover; transition: filter .25s; }
.how-ph:hover img { filter: brightness(1.06); }
.how-ph:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.how-words { position: sticky; top: calc(var(--head-h) + 24px); }
.how-words .prose > :last-child { margin-bottom: 0; }
.how-words .rich-text > div:has(> br:only-child) { display: none; } /* a blank line typed in the editor: the gap is already there */

/* In situ (T, 2026-11-03): one photograph to a row, whole at its own shape on 7 of 12 (How I work's split), its words on
   the other 5, the sides changing every row. Tops aligned. No frame: these are rooms, not the pieces. As on About (T,
   2026-11-03: "sticky like the about page"), the shorter side holds still while the longer one scrolls past: a tall
   photograph runs past the screen beside his words. */
.situ-list { --situ-gap: clamp(32px, 5vw, 88px); display: grid; gap: clamp(64px, 8vw, 128px); }
.situ-row { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: var(--situ-gap); align-items: start; }
.situ-row.flip { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
.situ-row.flip .situ-ph { order: 2; }
.situ-ph { display: block; width: 100%; aspect-ratio: var(--ar); padding: 0; border: 0; background: color-mix(in srgb, var(--ink) 6%, var(--bg)); overflow: hidden; cursor: zoom-in; }
.situ-ph img { display: block; width: 100%; height: 100%; object-fit: cover; transition: filter .25s; }
.situ-ph:hover img { filter: brightness(1.06); }
.situ-ph:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.situ-words { max-width: 36rem; }
.situ-row.flip .situ-words { justify-self: start; }
.situ-words > h2 { font-size: var(--t-h3); line-height: 1.3; margin: 0 0 .9rem; text-wrap: balance; }
.situ-words .prose > :last-child { margin-bottom: 0; }
.situ-words .rich-text > div:has(> br:only-child) { display: none; }
.situ-piece { margin: .6rem 0 0; }
/* Both sides are sticky; only the shorter one can hold still. On a computer only. */
@media (min-width: 901px) { .situ-ph, .situ-words { position: sticky; top: calc(var(--head-h) + 24px); } }
/* In the pop-up a photograph of the making has no frame, no mat and no Enquire: it is not a piece for sale. */
.piece-box.is-plain { --pb-mat: 0px; }
.piece-box.is-plain .pb-mat { background: none; box-shadow: none; }

/* ─── Contact ──────────────────────────────────────────────────── */
/* 2026-10-26 (T): his words beside the form always, 5 to 6 as before, and the form tightened (48px boxes, a message box
   of five lines, closer rows) so the whole form, Send included, is on the first screen of a laptop. The words start
   level with the form's first label. Stacked under 900px, with a hairline between the words and the form. */
.contact-grid { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); gap: clamp(32px, 6vw, 112px); align-items: start; padding-bottom: clamp(56px, 7vw, 88px); }
.contact-info .prose > :first-child { margin-top: 0; }
.facts { margin: 2rem 0 1.5rem; display: grid; gap: 1rem; }
.facts div { display: grid; gap: .1rem; }
.facts dt { font-size: var(--t-small); color: var(--muted); }
.facts dd { margin: 0; }
.facts a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 4px; overflow-wrap: anywhere; }
.contact-form { display: grid; grid-template-columns: 1fr 1fr; gap: 1.1rem 1.25rem; }
.contact-form > * { grid-column: 1 / -1; }
.contact-form .field:has(> input) { grid-column: auto; }
@media (max-width: 560px) { .contact-form .field:has(> input) { grid-column: 1 / -1; } }
.field { display: grid; gap: .5rem; }
.field label { font-weight: 500; font-size: var(--t-small); }
.field input, .field textarea {
  width: 100%; font: inherit; font-size: var(--t-body); color: var(--ink); background: var(--bg);
  border: 1px solid var(--field); border-radius: 0; padding: .55rem .8rem; min-height: 48px; line-height: 1.5;
}
.field textarea { resize: vertical; min-height: 8.5rem; line-height: 1.55; }
.field { gap: .4rem; }
.field input:focus, .field textarea:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }
/* POLISH: the button. A touch more room inside, the words a weight heavier, a darker shade of the accent on hover
   (not a fade), and the same press as before. Links that act as buttons get it too (the hero, the pop-up's Ask). */
.btn {
  display: inline-flex; align-items: center; justify-content: center; justify-self: start;
  min-height: 50px; padding: .8rem 2.2rem; border: 0; border-radius: 0; cursor: pointer;
  font: inherit; font-weight: 600; line-height: 1.2; background: var(--accent); color: var(--accent-ink); text-decoration: none;
  transition: background-color .15s, transform .15s var(--ease);
}
.btn:hover { background: var(--accent-hover); }
.btn:active { transform: translateY(1px); }
.sent h2 { margin-bottom: .75rem; }
.sent p + p { margin-top: 1.5rem; }

/* ─── Footer ───────────────────────────────────────────────────── */
.site-foot { border-top: 1px solid var(--line); padding: clamp(40px, 5vw, 64px) 0 clamp(24px, 3vw, 32px); background: color-mix(in srgb, var(--foot) calc(var(--foot-veil) * 1%), transparent); }
.foot-row { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 4fr) auto; gap: 2rem var(--gap); align-items: start; }
.foot-wm { display: inline-flex; align-items: center; min-height: 44px; font-size: var(--t-lead); text-decoration: none; }
.foot-name p { margin-top: .35rem; color: var(--muted); }
.foot-reach { display: grid; gap: .35rem; justify-items: start; }
.foot-reach > a { text-decoration-thickness: 1px; text-underline-offset: 4px; overflow-wrap: anywhere; }
.foot-reach > a:hover { color: var(--accent); }
.foot-nav { display: flex; flex-wrap: wrap; gap: .25rem 1.5rem; }
.foot-nav a { min-height: 44px; min-width: 44px; display: inline-flex; align-items: center; text-decoration: none; font-weight: 500; font-size: var(--t-menu); }
.foot-nav a:hover { text-decoration: underline; text-underline-offset: 6px; }
.foot-small { margin-top: clamp(32px, 4vw, 48px); font-size: var(--t-small); color: var(--muted); }

/* The words on the bar at the foot (T, 2026-10-31): their own colour (--c-foot-ink), else the Words colour; the softer
   lines and the hairline are mixed from them, as on the page. */
.site-foot { --ink: var(--c-foot-ink, var(--c-ink, #1b1d1f)); --muted: color-mix(in srgb, var(--ink) 66%, var(--foot)); --line: color-mix(in srgb, var(--ink) 14%, var(--foot)); color: var(--ink); }
/* A photograph behind a bar (T, 2026-10-31, after Beara Joinery's): it fills the bar, cropped as framed in Rest of Site,
   and the bar's colour lies over it at the bar's veil (0 shows the photograph as it is, 100 hides it). The bar's words
   sit above it. */
.site-head.has-img, .site-foot.has-img { background: none; }
.site-foot.has-img { position: relative; }
.bar-img { position: absolute; inset: 0; z-index: 0; overflow: hidden; pointer-events: none; }
.bar-img img { display: block; width: 100%; height: 100%; object-fit: cover; }
.bar-img::after { content: ""; position: absolute; inset: 0; }
.site-head .bar-img::after { background: color-mix(in srgb, var(--bar) calc(var(--bar-veil) * 1%), transparent); }
.site-foot .bar-img::after { background: color-mix(in srgb, var(--foot) calc(var(--foot-veil) * 1%), transparent); }
.has-img > .wrap { position: relative; z-index: 1; }

/* Social links are icons (playbook): 44px targets, the ink colour on any ground. */
.soc-icons { display: flex; gap: .25rem; margin-left: -10px; }
.soc-icons a { width: 44px; height: 44px; display: inline-flex; align-items: center; justify-content: center; color: var(--ink); transition: color .15s; }
.soc-icons svg { width: 26px; height: 26px; fill: currentColor; } /* POLISH: the glyphs sit small inside their box; 26px reads at the caption size */
.soc-icons a:hover { color: var(--accent); }

.to-top {
  position: fixed; right: var(--gutter); bottom: 20px; z-index: 300; width: 48px; height: 48px;
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
  background: var(--bg); color: var(--ink); border: 1px solid var(--line); border-radius: 0;
}
.to-top[hidden] { display: none; }
.to-top:hover { border-color: var(--ink); }
.to-top svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }

/* ─── Artwork pop-up (public/js/main.js) ───────────────────────── */
/* MOSAIC (brief item 5, after nacharlet's lightbox): the whole piece as large as the screen allows, in its frame, and
   its words under it like a caption on the picture's left edge; on the page's own ground so it reads as the same wall
   (T: the page's ground, not a dark one). A click anywhere that is not a link or a button leaves (zoom-out cursor);
   the small arrows sit at the picture's sides, the close button in the corner, all 44px. When the words run past the
   bottom the pop-up scrolls; the page behind stays still. */
html.pb-open, html.pb-open body { overflow: hidden; }
.opens-piece { cursor: zoom-in; }
.piece-box { display: none; position: fixed; inset: 0; z-index: 600; background: var(--bg); color: var(--ink); cursor: zoom-out; }
.piece-box.open { display: block; }
.piece-box { --pb-side: 72px; --pb-mat: 12px; }
.pb-panel { position: absolute; inset: 0; overflow-y: auto; overscroll-behavior: contain; display: flex; flex-direction: column; align-items: center; padding: 1.5rem var(--pb-side); }
.pb-stack { display: flex; flex-direction: column; align-items: flex-start; max-width: 100%; margin: auto 0; transition: opacity .17s ease; } /* centred while it is short */
.pb-stack.is-leaving { opacity: 0; } /* next or previous: out, the new piece in whole, back (main.js, item 9) */
.pb-figure { margin: 0; position: relative; max-width: 100%; }
.pb-mat { display: block; padding: var(--pb-mat); background: var(--bg); box-shadow: inset 0 0 0 1px var(--frame-edge), 0 2px 4px color-mix(in srgb, var(--ink) 14%, transparent), 0 28px 64px -24px color-mix(in srgb, var(--ink) 48%, transparent); }
/* As tall as leaves room for a short caption under it (the title, the state and the button) on a 900px screen; a
   description makes the pop-up scroll, the title showing as the cue. */
.pb-figure img { display: block; width: auto; height: auto; max-width: calc(100vw - 2 * var(--pb-side) - 2 * var(--pb-mat)); max-height: min(84vh, 100vh - 15rem); max-height: min(84dvh, 100dvh - 15rem); object-fit: contain; aspect-ratio: var(--pb-ar, auto); }
/* The caption takes the picture's width and no more (width 0 with min-width 100%: the words never widen the stack). */
.pb-words { width: 0; min-width: 100%; padding-top: 1rem; cursor: default; }
/* In order of weight: the title in the display face at the lead step; medium, year and size as one muted line; where
   it was made; the collection as a link; the description; the state (Available with the price, or Sold) and Ask
   about this piece as a button. Everything empty is hidden by main.js. */
.pb-title { font-size: var(--t-lead); margin: 0 0 .25rem; }
.pb-meta, .pb-place { color: var(--muted); line-height: 1.5; }
.pb-col { margin-top: .35rem; }
.pb-col .text-link { min-height: 32px; }
.pb-col[hidden] { display: none; }
.pb-desc { margin-top: 1rem; max-width: 60ch; }
.pb-desc p { margin: 0 0 1em; }
.pb-sale { margin-top: .6rem; font-weight: 500; }
.pb-ask-row { margin-top: .6rem; }
/* Enquire (T, 2026-10-26, item 6): a small outlined link in the ink, not a coloured block; the accent only on hover. */
.pb-ask.text-link { min-height: 44px; padding: 0 1.1rem; border: 1px solid color-mix(in srgb, var(--ink) 45%, transparent); color: var(--ink); text-decoration: none; font-size: var(--t-small); font-weight: 500; line-height: 1.2; transition: border-color .15s, color .15s; }
.pb-ask.text-link:hover { border-color: var(--accent); color: var(--accent); text-decoration: none; }
.pb-btn { position: absolute; width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; border: 0; border-radius: 0; background: transparent; color: var(--ink); cursor: pointer; transition: background-color .15s; }
.pb-btn:hover { background: var(--line); }
.pb-btn svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.pb-btn[hidden], .pb-sale[hidden], .pb-ask-row[hidden], .pb-meta[hidden], .pb-place[hidden], .pb-desc[hidden] { display: none; }
.pb-close { position: fixed; top: 1rem; right: 1rem; }
.pb-prev, .pb-next { top: 50%; transform: translateY(-50%); }
.pb-prev { right: calc(100% + 10px); }  /* in the margin left of the picture */
.pb-next { left: calc(100% + 10px); }   /* in the margin right of it */
@keyframes pb-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes hero-drift { 0%, 100% { transform: translateY(-3px); } 50% { transform: translateY(4px); } }

/* ─── Motion: only with the visitor's leave ────────────────────── */
@media (prefers-reduced-motion: no-preference) {
  .piece-box.open { animation: pb-in .2s ease; }
  html { scroll-behavior: smooth; }
  .hero-down svg { animation: hero-drift 2.4s ease-in-out infinite; }
}
@media (prefers-reduced-motion: reduce) {
  .site-head, .tile-pic, .tile-cap-in, .btn, .menu a::after, .series-tabs button::after, .pb-btn, .text-link, .tile-ask { transition: none; }
  .tile:hover .tile-pic, .tile:has(:focus-visible) .tile-pic { transform: none; }
}

/* A smaller computer (1024 x 768): at 5rem under it a square piece pushes his line under the piece and off the first
   screen, so the piece keeps the polish's height there and the words stay beside it. */
@media (max-width: 1100px) { .hero { --hero-under: 9rem; } }
/* On a computer the line stays beside the piece whatever its shape (T, 2026-10-26: under a wide piece it "just moves
   to the bottom of the image"): the row never wraps, the line keeps a column of about a quarter of the page (18 to 26rem)
   and a wide piece gives up width to make room, keeping its shape. The phone and tablet layout below stacks them. */
@media (min-width: 901px) {
  .hero-frame { flex-wrap: nowrap; }
  .hero-piece { min-width: 0; }
  .hero-label { flex: 1 0 clamp(18rem, 28vw, 26rem); }
}

/* ─── Between a computer and a phone ───────────────────────────── */
@media (max-width: 900px) {
  /* In situ: the photograph first, its words under it; a tall one held to the screen's height. */
  .situ-row, .situ-row.flip, .situ-row.no-words { grid-template-columns: minmax(0, 1fr); gap: 20px; }
  .situ-row.flip .situ-ph { order: 0; }
  .situ-ph { max-width: calc((100svh - var(--head-h, 64px) - 64px) * var(--ar)); }
  .grid-justified > li { width: calc((100% - var(--nm, 0) * var(--gap)) * var(--fm, .5)); }
  /* The hero stacks: the piece first, at the page's width, then its words (--hero-under leaves them room). */
  .hero { --hero-under: 15rem; }
  .hero-piece { flex-basis: 100%; }
  .hero-label { flex-basis: 100%; }
  .about-grid, .contact-grid { grid-template-columns: minmax(0, 1fr); }
  .contact-grid { gap: clamp(24px, 3vw, 40px); }
  .contact-form { border-top: 1px solid var(--line); padding-top: clamp(24px, 3.5vw, 36px); }
  .about-photo { max-width: 480px; }
  .how-grid { grid-template-columns: minmax(0, 1fr); }
  .how-grid.no-words .how-mosaic { max-width: none; }
  .how-words { position: static; }
  .news-item { grid-template-columns: minmax(0, 1fr); }
  .foot-row { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .foot-nav { grid-column: 1 / -1; }
  .piece-box { --pb-side: var(--gutter); }
  .pb-panel { padding: 4.5rem var(--pb-side) 6rem; }
  .pb-figure { position: static; }
  .pb-figure img { max-height: calc(70vh - 2 * var(--pb-mat)); max-height: calc(70dvh - 2 * var(--pb-mat)); }
  .pb-prev, .pb-next { position: fixed; top: auto; bottom: 1rem; transform: none; background: var(--bg); border: 1px solid var(--line); }
  .pb-prev { right: auto; left: 1rem; }
  .pb-next { left: auto; right: 1rem; }
}

/* ─── Phone ────────────────────────────────────────────────────── */
@media (max-width: 720px) {
  :root { --head-h: 78px; }
  .grid-justified > li { width: calc((100% - var(--ns, 0) * var(--gap)) * var(--fs, .5)); }
  .hero { --hero-under: 16rem; }
  .hero-piece { --mat: 8px; }
  .hero-frame { gap: 1.5rem; }
  .tile-cap-in { padding: 1.5rem .7rem .6rem; }
  .series-desc-pic { float: none; width: min(100%, var(--sd-w, 320px) * 1.25); margin: 0 0 1.25rem; }
  .hero-label h1 { text-wrap: balance; } /* no word left alone on the last line of his line */
  .wm { font-size: min(calc(var(--wm-size, 30px) * .86), 8vw); } /* a large name still fits beside the menu lines */
  .wm-logo { height: calc(var(--logo-h, 44px) * .8); }
  .head-row { gap: .25rem; }
  .wm-link { margin-right: auto; min-width: 0; }
  .lang-switch { padding: 0 .25rem; justify-content: center; }
  .lang-switch::before { display: none; }
  .ls-long { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .ls-short { display: inline; }
  /* The menu is the three lines alone; their right end sits on the page's right edge. */
  .how-mrow.stack-phone { flex-direction: column; }
  .how-mrow.stack-phone .how-ph { flex: none; width: 100%; max-width: calc(34rem * var(--ar)); }
  .burger {
    display: inline-flex; flex-direction: column; justify-content: center; gap: 6px;
    width: 44px; height: 44px; margin-right: -10px; padding: 10px; border: 0; background: none; cursor: pointer; color: var(--ink);
  }
  .burger span { display: block; width: 24px; height: 1.5px; background: currentColor; transition: transform .25s var(--ease), opacity .2s; }
  html.menu-open .burger span:nth-child(1) { transform: translateY(7.5px) rotate(45deg); }
  html.menu-open .burger span:nth-child(2) { opacity: 0; }
  html.menu-open .burger span:nth-child(3) { transform: translateY(-7.5px) rotate(-45deg); }
  /* The open panel is on the page's own ground, so it keeps the Words colour whatever the bar's words are. */
  .menu { --ink: var(--c-ink, #1b1d1f); --line: color-mix(in srgb, var(--ink) 14%, var(--bg)); }
  .menu { display: none; position: fixed; left: 0; right: 0; top: var(--head-h); bottom: 0; background: var(--bg); padding: 1.5rem var(--gutter); border-top: 1px solid var(--line); overflow-y: auto; }
  html.menu-open .menu { display: block; }
  html.menu-open { overflow: hidden; }
  .menu ul { flex-direction: column; align-items: stretch; gap: .5rem; }
  /* The phone panel: every link in the display face at heading size, Contact among them (no box here), the current
     page marked by the same accent rule. */
  .menu a { font-family: var(--f-head, var(--display)); font-weight: var(--f-head-weight, 600); letter-spacing: var(--f-head-track, -0.02em); font-style: var(--f-head-style, normal); font-synthesis: none; font-size: var(--t-h2); min-height: 52px; padding: 0; border: 0; background: none; color: var(--ink); justify-content: flex-start; }
  .menu a::after { bottom: 6px; }
  .foot-row { grid-template-columns: minmax(0, 1fr); }
  .foot-reach:empty { display: none; }
  .to-top { bottom: 16px; }
}
@media (prefers-reduced-motion: reduce) { .burger span { transition: none; } }
