/*
  StudioE, shared stylesheet for every page. Extracted from the approved homepage design
  (option-b2.html, kept in site-work/design-options) and extended for the inner pages.
  Revised after the client's review of November 14, 2026 (v=3, v=4): one-row header from 37.5em,
  three type roles only, compact contact row with an Instagram icon (Contact page only), photo-and-one-line project blocks.
  v=6: the whole layout scales with the window on desktop (see SCALE); three nav items (no Services page).
  v=9: the footer is the colophon alone on every page (contact details live on the Contact page only),
  set a full block space (--space) below the page; the Contact address is in the text role.
  v=7: floor of the scale raised to 68.75%; desktop windows take the 45em tier from 37.5em; Studio is
  stacked at every width; each link's 44px target is a pseudo-element, so the focus ring hugs the text.
  Whole site on ink #1F1A18 with ivory text. One typeface, one weight: Inter Regular (400).

  SCALE (desktop only)
  Every size in this file is in rem, so the root font size is the scale of the whole layout: type, gutters,
  gaps, the page column and the photographs' fold cap all follow it, and the proportion between the type
  and the photograph stays the one approved at a 1440px window.
    @media (min-width: 37.5em) and (hover: hover) and (pointer: fine)
      html { font-size: clamp(68.75%, (100vw + 15px) / 90 + (100% - 16px), 100%) }
  The root is 1/90 of the window width (1.1111vw). From 1440px wide it is 100% (16px: text 14px).
  Narrower, it shrinks in step with the window (13.33px at 1200, 11.38px at 1024) down to a floor of
  68.75% at 990px and below (11px: text 9.625px, labels and fine print 8.25px). Phones (below 37.5em)
  and touch devices keep 100%.
  - DESKTOP TIER: a desktop window is laid out as the 45em tier from 37.5em (600px) up: the same gutters,
    page column, fold cap and three-column gallery as a wider window, only smaller. Touch devices keep
    the 37.5em to 45em tablet rules. The media queries say so with
    "(min-width: 45em), (min-width: 37.5em) and (hover: hover) and (pointer: fine)".
  - The 15px: this page reserves the scrollbar's gutter (scrollbar-gutter: stable), and current Chrome
    and Edge then leave that gutter out of 100vw (15px on Windows). Adding it back makes the root exactly
    window / 90 there. Where the scrollbar takes no room (macOS, or browsers that count it in 100vw) the
    root is 0.17px larger and reaches 100% at 1425px instead of 1440px.
  - The (100% - 16px): nothing at the usual 16px default. A reader who has set a larger default text
    size in the browser gets that difference added, and the two ends are percentages of it, so their
    setting is still honoured (a 32px default gives 28px text at 1440px, as it did before the scaling).
  - Media queries are in em, which is the browser's default size, not the root's: the breakpoints do not move.
  - What must NOT scale is in px: link targets (--tap, 44px), the focus ring (3px), the logo's least
    height (24px), the header's least padding (7px: room for the ring).
  - LINKS. A link's own box is its line of text (the logo: its image), so the 3px focus ring, 3px off the
    box, hugs the text and stays inside the link's row at every scale. The row (--row, 2.75rem) is made
    by the link's block margins. The 44px TARGET is the link's ::after: at least 44px each way, centred
    on the box, reaching past a scaled row by --tap-over into the space around it. Those spaces (header
    paddings, the breadcrumb row, the footer's top padding) are never smaller than the reach, so targets
    never overlap. The project line is different: its link is stretched over its whole block (.card).
  - Browser zoom narrows the window in CSS px, so between a 1440 and a 990 CSS px window zoom does not
    enlarge the text; below 990 it does (the floor), and below 600 the phone layout shows it at 100%.
    At 300% zoom or more, text is at least twice its unzoomed size on any window.
  - The `sizes` attributes in the pages repeat this arithmetic in px and vw for desktop (rem in `sizes`
    is always 16px, and 100vw there is the whole window, scrollbar included), ahead of the rem
    expressions that touch devices use. Change them together.

  CONTRAST (WCAG 2.x; AAA = 7:1)
  ivory #ECE7DD on ink #1F1A18         13.98:1   tagline, page titles, text, current nav item, links, detail values,
                                                 the address on the Contact page,
                                                 Instagram icon, focus ring
  ivory-quiet #B3AEA6 on ink #1F1A18    7.81:1   nav numbers, other nav items on inner pages, project lines,
                                                 breadcrumb, detail labels, captions, E: / T: prefixes, copyright,
                                                 link hover state
  No text sits on a photograph anywhere.

  TYPE (three roles; the same on every page, on desktop and phone; no other size exists)
  label  0.75rem caps, tracking 0.14em     nav, STUDIOE in the colophon
  text   0.875rem / 1.6, ivory             homepage tagline (h1), running text, contact links and address,
                                           "All projects" and other arrow links, the skip link.
                                           Page titles (h1 on inner pages) are the same size in caps, tracking 0.3em.
                                           Running text is at most 31rem wide (80 characters a line at most).
  fine   0.75rem / 1.6, quiet ivory        project lines (address under a photo), project details (values ivory),
                                           captions, breadcrumb, copyright
  Every link's target is at least 44px tall and wide at every root size (see LINKS above).

  HEADER: logo left, numbered nav (01 Projects, 02 Studio, 03 Contact) right, on ONE row from 37.5em (600px).
  Below that (phones): logo, then the nav on its own row without numbers.

  PAGE COLUMN (the 45em tier): max( min(page, 84rem, 1.5 x fold height), min(56rem, page) ), centred.
  Header, photographs, text and footer share its left and right edges on every page, so the header
  does not move between pages. The photograph's HEIGHT is capped to the fold on the first photograph of
  the homepage, of the projects index and of the Studio page (the last two: a lower cap from 64em,
  because a page title sits above the photograph).

  Loading: each page links this file in <head>, directly after the small inline <style>, so it is
  render-blocking in every browser and nothing is painted unstyled.
  Caching: this file is served with a one-year immutable cache. Pages link it as site.css?v=N;
  raise N in every page when this file changes.
*/

/* ---------- Fonts: self-hosted Inter 400, plus a metric-matched fallback so the swap does not shift ---------- */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/inter-400-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/inter-400-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* Fallbacks shown only until Inter arrives (it is preloaded): Arial resized to Inter's measured widths,
   with Inter's ascent and descent, so the swap moves nothing. Inter's lowercase runs about 6.4% wider
   than Arial's, its capitals about 1.5% narrower, hence one face for sentence case and one for caps. */
@font-face {
  font-family: "Inter Fallback";
  font-style: normal;
  font-weight: 400;
  src: local("Arial"), local("ArialMT"), local("Liberation Sans"), local("Arimo");
  size-adjust: 106.4%;
  ascent-override: 91.05%;
  descent-override: 22.7%;
  line-gap-override: 0%;
  /* Only the characters the Inter files cover, so the typed arrow (U+2192) keeps coming from the system font. */
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD, U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Inter Fallback Caps";
  font-style: normal;
  font-weight: 400;
  src: local("Arial"), local("ArialMT"), local("Liberation Sans"), local("Arimo");
  size-adjust: 98.5%;
  ascent-override: 98.35%;
  descent-override: 24.52%;
  line-gap-override: 0%;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD, U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  color-scheme: dark;
  --ink: #1F1A18;
  --ivory: #ECE7DD;
  --ivory-quiet: #B3AEA6;   /* 7.81:1 on ink */
  --font: "Inter", "Inter Fallback", system-ui, Arial, sans-serif;
  --font-caps: "Inter", "Inter Fallback Caps", system-ui, Arial, sans-serif;   /* for uppercase text */
  --gutter: 1rem;
  --space: 3.5rem;          /* between the major blocks of a page */
  --space-s: 2.5rem;        /* between related blocks inside a page */
  --gap: 1rem;              /* between photographs */
  --tap: 44px;              /* the least height and width of a link target: px, so it never shrinks with the root */
  --row: 2.75rem;           /* a row of links at the layout's scale (44px at the 16px root) */
  --tap-over: max(0px, calc((var(--tap) - var(--row)) / 2));   /* how far a target reaches past such a row, each side:
                               0 at the 16px root, 6.875px at the 11px floor */
  --top: max(2.75rem, var(--tap));   /* inner pages: header to h1. Never less than the 44px breadcrumb row of the
                               project page, so the h1 sits at the same height on every inner page */
  --header-top: 0.75rem;    /* the header's top padding: where the logo's row starts */
  --header-bottom: 0.5rem;  /* the header's bottom padding */
  --measure: 31rem;         /* longest line of running text: at most 80 characters at 0.875rem (32rem ran to 81) */
  --vh: 100vh;
  /* Fold budget: what must fit on the first screen besides the photo (header + gap + h1 line + air). */
  --budget: 13rem;
  --floor: 24rem;                                        /* the photo is never asked to be narrower than this */
  --fold-h: calc(var(--vh) - var(--budget));             /* tallest photo that keeps the h1 above the fold */
  --fold-w: max(var(--floor), calc(var(--fold-h) * 1.5)); /* the same limit as a width, for a 3:2 photo */
  --page-w: calc(100vw - 2 * var(--gutter));
  --col-w: var(--page-w);                                /* the page column */
  --logo-x: var(--gutter);                               /* the column's (and the logo's) left edge */
}
@supports (height: 100svh) {
  :root { --vh: 100svh; }
}
/* Short landscape (phones on their side, zoomed laptops): the budget still allows for a two-row header. */
@media (max-height: 30em) and (orientation: landscape) {
  :root { --budget: 10rem; --floor: 16rem; --top: 1rem; }
}
@media (min-width: 37.5em) {
  :root { --header-top: 1rem; --header-bottom: 0.75rem; }
}
/* The 45em tier; a desktop window takes it from 37.5em (see DESKTOP TIER in the header comment). */
@media (min-width: 45em), (min-width: 37.5em) and (hover: hover) and (pointer: fine) {
  :root {
    --gutter: 2rem; --space: 4.5rem; --space-s: 3rem; --top: max(3rem, var(--tap)); --header-top: 1.5rem; --header-bottom: 1.5rem;
    /* Page column shared by header, photos, text and footer. It is as wide as an uncropped
       3:2 photo can be while keeping the homepage h1 above the fold, but never wider than the page
       or 84rem (the 1600px source), and never narrower than 56rem (or the page). */
    --col-w: max(min(var(--page-w), 84rem, var(--fold-w)), min(56rem, var(--page-w)));
    --logo-x: max(var(--gutter), calc((100vw - var(--col-w)) / 2));
  }
}
@media (min-width: 45em) and (max-height: 30em) and (orientation: landscape),
       (min-width: 37.5em) and (hover: hover) and (pointer: fine) and (max-height: 30em) and (orientation: landscape) {
  :root { --budget: 7rem; --top: 1.5rem; }               /* one-row header, tighter paddings */
}
@media (min-width: 64em) {
  /* --top is 4rem: 45.5px at the narrowest desktop root here (11.38px at 64em), so still a 44px row. */
  :root { --gutter: 3rem; --space: 6rem; --space-s: 3.5rem; --gap: 1.5rem; --top: 4rem; --header-top: 2rem; --header-bottom: 1.75rem; }
}
@media (min-width: 64em) and (max-height: 30em) and (orientation: landscape) {
  :root { --top: 1.5rem; }
}
@media (max-height: 30em) and (orientation: landscape) {
  :root { --header-top: 0.5rem; --header-bottom: 0.5rem; }
}

*, *::before, *::after { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  font-synthesis: none;
  background-color: var(--ink);
  scrollbar-gutter: stable;       /* short and long pages share one layout width: the header never shifts */
}
/* SCALE (see the header comment). Desktop only: a window of 600px or more with a mouse or trackpad.
   The root is 1/90 of the window width: 16px (100%) from 1440px up, never less than 11px (68.75%, reached
   at 990px). 100vw leaves out the 15px scrollbar gutter this page reserves, hence the + 15px.
   (100% - 16px) is 0 at the usual default; with the two ends in percent it keeps a reader's own larger
   default text size in force. Print is not scaled (see the print rules at the end). */
@media (min-width: 37.5em) and (hover: hover) and (pointer: fine) {
  html { font-size: clamp(68.75%, (100vw + 15px) / 90 + (100% - 16px), 100%); }
}
/* The footer sits at the bottom of the window on short pages (Contact, Page not found).
   The body carries the TEXT role: every piece of text is 0.875rem unless it is a label or fine print. */
body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100svh;
  margin: 0;
  background-color: var(--ink);
  color: var(--ivory);
  font-family: var(--font);
  font-weight: 400;
  font-size: 0.875rem;
  line-height: 1.6;
  overflow-wrap: break-word;      /* a long word never widens the page at very large text sizes */
  -webkit-font-smoothing: antialiased;
}
h1, h2, p, ul, ol, li, dl, dt, dd, figure, picture { margin: 0; padding: 0; font-size: inherit; font-weight: 400; font-style: normal; }
/* No markers (brand). The empty string, unlike "none", keeps list semantics in Safari / VoiceOver. */
ul, ol { list-style: none; list-style-type: ""; }
img { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }

/* Links: no underline (brand). Identified by place (nav, contact row), wording and a typed arrow.
   Hover: ivory -> quiet ivory, and the arrow steps 2px right. Focus: strong ivory ring (3px, in px).
   The link's box is its one line of text (--line: its line height), so the ring hugs the text; the block
   margins make up the row (--row). The 44px target is the ::after below: positioned, so the part that
   reaches past the row stays on top of what is around it (the footer under an arrow link, the address
   under the contact row) and can be clicked. */
.lnk {
  --line: 1.6em;
  position: relative;
  display: inline-flex;
  align-items: center;
  margin-block: max(0px, calc((var(--row) - var(--line)) / 2));
  transition: color 0.2s ease;
}
/* The target of every link but the project line's: at least 44px each way, centred on the link's box. */
.lnk::after, .logo::after, .contact a::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: max(100%, var(--tap));
  height: max(100%, var(--tap));
  transform: translate(-50%, -50%);
}
.lnk:hover { color: var(--ivory-quiet); }
.arrow {
  display: inline-block;
  padding-left: 0.5em;
  transition: transform 0.2s ease;
}
.lnk:hover .arrow { transform: translateX(2px); }
:focus { outline: none; }
:focus-visible { outline: 3px solid var(--ivory); outline-offset: 3px; }
main:focus { outline: none; }
main { flex: 1 0 auto; }

/* A block that is one link: the block's single link is stretched over it, so the photographs are
   clickable without sitting inside the link (their alt text stays out of the link's name). The focus
   ring is drawn around the visible link text. */
.card { position: relative; }
.card-link::after { content: ""; position: absolute; inset: 0; }

.wrap {
  width: 100%;
  margin-inline: auto;            /* the column is centred; everything inside it aligns left */
  padding-inline: var(--gutter);
}
@media (min-width: 45em), (min-width: 37.5em) and (hover: hover) and (pointer: fine) {
  .wrap { max-width: calc(var(--col-w) + 2 * var(--gutter)); }
}

/* ---------- Type roles (see the header comment). TEXT is the body's own style. ---------- */
/* Page titles: the text size in wide caps, echoing the STUDIOE lettering in the logo. */
.title {
  font-family: var(--font-caps);
  text-transform: uppercase;
  letter-spacing: 0.3em;
  line-height: 1.5;
  text-wrap: balance;
}
/* LABEL: nav, and STUDIOE in the colophon. */
.label {
  font-family: var(--font-caps);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  line-height: 1.5;
}
/* FINE: very small information. */
.fine {
  font-size: 0.75rem;
  line-height: 1.6;
  color: var(--ivory-quiet);
}
.nb { white-space: nowrap; }      /* keeps "design-build" on one line */
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px; margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* Skip link: when focused it sits over the logo's row and covers the logo (ink ground), its text on the
   column's left edge. Its box is the whole row, so its ring starts 6px above the row: inside the window. */
.skip {
  position: absolute;
  left: calc(var(--logo-x) - 0.5rem);
  top: max(var(--header-top), var(--tap-over), 7px);   /* the header's top padding */
  z-index: 10;
  min-width: calc(max(105px, 8.75rem) + 1rem);         /* the logo's width plus 0.5rem each side */
  min-height: var(--row);
  margin-block: 0;
  padding: 0 0.5rem;
  background-color: var(--ink);
  transform: translateY(-300%);
}
.skip:focus, .skip:focus-visible { transform: none; }

/* ---------- Header: an ink row above the page ---------- */
/* From 37.5em: logo left, nav right, one row (the approved homepage). It wraps only when the text is
   enlarged so far that the two no longer fit side by side; it never overflows.
   The row is --row high (2.75rem); the 44px targets of the logo and the nav reach into the paddings,
   which are never smaller than that reach, so the targets stay inside the header, and never smaller
   than 7px, so a focus ring (6px past its box) is never cut by the top of the window nor touches the
   photograph under the header. */
.site-header {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 0 0.75rem;
  padding-block: max(var(--header-top), var(--tap-over), 7px) max(var(--header-bottom), var(--tap-over), 7px);
}
/* Header logo: the ivory file, 2rem high (32px at the 16px root) and never less than 24px (brand
   minimum for the header logo), 140:32 wide; >= half the mark's height of clear space.
   The link's box is the image; its block margins make up the row. */
.logo {
  position: relative;
  display: inline-flex;
  margin-block: max(0px, calc((var(--row) - max(24px, 2rem)) / 2));
}
.logo img { height: max(24px, 2rem); width: auto; }

.site-nav .lnk { --line: 1.5em; }               /* the label's line height */
.site-nav .num { margin-right: 0.75em; color: var(--ivory-quiet); font-family: var(--font); }
.site-nav .lnk:hover .num { color: inherit; }
/* Current section (inner pages): aria-current on its link. That link stays ivory, number included;
   the other two step back to quiet ivory at every width and brighten on hover and focus.
   The page's own h1 repeats the name below. No underline, border, line or icon (brand).
   On the homepage no nav link is current, so all three stay ivory. */
.site-nav [aria-current] .num { color: inherit; }
.site-nav:has([aria-current]) a:not([aria-current]) { color: var(--ivory-quiet); }
.site-nav:has([aria-current]) a:not([aria-current]):hover,
.site-nav:has([aria-current]) a:not([aria-current]):focus-visible { color: var(--ivory); }
.site-nav ol { display: flex; flex-wrap: wrap; row-gap: 0; }

/* Phones (below 37.5em): logo on its own row, then the nav on ONE line at 100% text size from 320px up
   (the three items and their two gaps take about 258px of the 288px there, in the fallback font too).
   At larger text sizes the row wraps; it never overflows. Numbers are hidden visually on phones. */
@media (max-width: 37.49em) {
  .site-nav { flex-basis: 100%; }
  .site-nav ol { justify-content: flex-start; column-gap: 1.25rem; }
  .site-nav .num { display: none; }
}
/* From 37.5em: the nav joins the logo's row, right-aligned, numbers shown; the space between logo and
   nav takes up the rest (at 37.5em and the 16px root there is about 100px of it).
   The list is pulled right by its own tracking, so the last LETTER (not the space after it) sits on
   the column's right edge. */
@media (min-width: 37.5em) {
  .site-nav ol { justify-content: flex-end; column-gap: 1.5rem; margin-right: -0.14em; }
}
@media (min-width: 45em), (min-width: 37.5em) and (hover: hover) and (pointer: fine) {
  .site-header { column-gap: 2rem; }
}
@media (min-width: 64em) {
  .site-nav ol { column-gap: 2rem; }
}
@media (max-height: 30em) and (orientation: landscape) {
  .site-nav { flex-basis: auto; }   /* the nav joins the logo row when it fits */
}

/* ---------- Shared text ---------- */
h1 { text-wrap: balance; }                       /* the homepage tagline: text size, ivory */
.more { margin-top: 0.5rem; }                    /* an arrow link under a block */
/* Running text: never wider than the measure. */
.prose { max-width: var(--measure); }
.prose p + p { margin-top: 2.4em; }              /* 1.5 x the line pitch */
.prose p, p.prose, .details dd { text-wrap: pretty; }   /* no one-word last lines */

/* Photographs fill their box; the box keeps its shape before the file arrives (no layout shift). */
.photo {
  width: 100%;
  height: auto;
  object-fit: cover;
  background-color: var(--ink);
}

/* Project line: the one very small line under a project's photograph(s), on the homepage and the
   projects index. It is the block's heading and holds the block's single link, which is stretched
   over the photographs (see .card), so the target is the whole block. The line box starts 0.75rem
   under the photograph; the link's own box is one row high (--row) and reaches 0.5rem into the gutter
   either side, so its focus ring (drawn just inside the link's box) clears both the text and the
   photograph. Hover and focus: quiet ivory -> ivory. */
.project-line { text-wrap: balance; }
.project-line a {
  display: inline-block;
  min-height: var(--row);
  min-width: var(--tap);
  margin-inline: -0.5rem;
  padding: 0.75rem 0.5rem;
  transition: color 0.2s ease;
}
.project-line a:hover, .project-line a:focus-visible { color: var(--ivory); }
.project-line a:focus-visible { outline-offset: -3px; }

/* ---------- Home: hero ---------- */
.hero, .portrait picture { container-type: inline-size; }
/* Below the 45em tier (short landscape only, in practice): the 3:2 photo narrows to stay above the fold. */
.hero img {
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
  max-width: min(100%, var(--fold-w));
  object-fit: cover;
  object-position: 50% 60%;
  background-color: var(--ink);
}
/* The 45em tier: the photo always fills the column. It is 3:2 where the fold allows; otherwise it is
   trimmed in height (a little ceiling and floor), but never flatter than 2:1. The Studio portrait
   follows the same rule (see Studio). */
@media (min-width: 45em), (min-width: 37.5em) and (hover: hover) and (pointer: fine) {
  .hero img, .portrait .photo {
    max-width: 100%;
    max-height: max(var(--fold-h), calc(var(--col-w) / 2));
    max-height: max(var(--fold-h), 50cqw);
  }
}
/* Upright phones: the 4:5 portrait crop, full width within the gutters. */
@media (max-width: 37.49em) and (orientation: portrait) {
  .hero img { aspect-ratio: 4 / 5; max-width: 100%; }
}

.intro { padding-top: 1.25rem; }
@media (min-width: 64em) {
  .intro { padding-top: 1.5rem; }
}
@media (max-height: 30em) and (orientation: landscape) {
  .intro { padding-top: 1rem; }
}

/* ---------- Home: the one project ---------- */
/* Two photographs one section gap below the tagline, then the project line. Nothing else. */
.feature { padding-top: var(--space); }
.feature .card-link::after { top: var(--space); }   /* the clickable block starts at the photographs, not in the space above them */
/* Two views side by side, equal columns, at every width; outer edges meet the hero's. */
.rooms {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--gap);
}
.rooms img {
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 4;       /* one shared crop, one shared height; each photo's pos-* class places the trim */
  object-fit: cover;
  background-color: var(--ink);
}
/* Desktop: the row never runs past a screen (both boxes shorten together), but never below 32rem. */
@media (min-width: 64em) {
  .rooms img { max-height: max(calc(var(--vh) * 0.85), 32rem); }
}
/* The portrait files are 2:3; a 3:4 box trims about 11% of their height. Where each trim falls
   (used on the homepage, the projects index and the project page): */
.pos-side-table { object-position: 50% 70%; }  /* mostly from the top: keeps the table's feet and the lamp */
.pos-corner     { object-position: 50% 60%; }  /* a little more from the top: keeps the rug and the tiles */
.pos-sun        { object-position: 50% 0%; }   /* all from the bottom: keeps the top lamp shade whole */

/* ---------- Inner pages: text-first top ---------- */
.page { padding-top: var(--top); }
.page > h1 + * { margin-top: 1.5rem; }

/* ---------- Projects: the index ---------- */
/* A list, one <li> per project: photograph, then the project line; the whole <li> is one link (see .card).
   ONE project (now): the homepage hero photograph, in the homepage's own .hero block, so it behaves
   exactly as it does there (3:2 across the column, the 4:5 crop on upright phones). From 64em its height
   is capped a little lower than on the homepage (never flatter than 2:1), because the page title sits
   above it and the project line must stay on the first screen.
   TWO OR MORE projects: from 37.5em a two-column grid of tiles, each its own 3:4 photograph
   (<img class="photo pos-...">) with its line beneath; one column on phones. */
.projects {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--gap);
}
@media (min-width: 64em) {
  /* Header + page top + h1 + gap above the photo + the project line beneath + a little air = 17rem.
     The Studio portrait, under its own page title, takes the same cap. */
  .projects .hero img, .portrait .photo {
    max-height: max(calc(var(--vh) - 17rem), calc(var(--col-w) / 2));
    max-height: max(calc(var(--vh) - 17rem), 50cqw);
  }
}
.projects > li:not(:only-child) .photo { aspect-ratio: 3 / 4; }
@media (min-width: 37.5em) {
  .projects { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .projects > li:only-child { grid-column: 1 / -1; }
}

/* ---------- Project page ---------- */
/* Breadcrumb: sits in the space between header and h1, so the h1 keeps its place. The row is never
   less than 44px, so the link's target fits inside it and touches neither the header's targets nor
   the h1; the focus ring, round the one line of text, stays well inside the row. */
.page--crumbs { padding-top: 0; }
.crumbs {
  display: flex;
  align-items: center;
  min-height: max(var(--tap), var(--top));
}
.crumbs ol { display: flex; flex-wrap: wrap; align-items: center; }
.crumbs li { display: flex; align-items: center; }
.crumbs li + li::before {
  content: "/";
  content: "/" / "";               /* decorative: not read out */
  margin-inline: 0.6em;
}
.crumbs .lnk:hover, .crumbs .lnk:focus-visible { color: var(--ivory); }

/* Details: a compact label / value grid directly under the h1. Labels quiet, values ivory. */
.page > h1 + .details { margin-top: 1rem; }
.details { max-width: var(--measure); }
.details > div {
  display: grid;
  grid-template-columns: 4.5rem minmax(0, 1fr);
  column-gap: 1rem;
}
.details dd { color: var(--ivory); }
.plates { margin-top: var(--space-s); }
.plate .photo { aspect-ratio: 3 / 2; }
/* Three portraits after the landscape photograph. Phones: stacked, each across the column, 3:4.
   Touch devices from 37.5em to 45em: two side by side (3:4), then the third across the column in a
   4:5 box. The 45em tier (desktop from 37.5em): three equal columns, 3:4. Outer edges always meet the
   landscape photograph's. */
.gallery {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--gap);
  margin-top: var(--gap);
}
.gallery .photo { aspect-ratio: 3 / 4; }
@media (min-width: 37.5em) {
  .gallery { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .gallery > li:nth-child(3) { grid-column: 1 / -1; }
  .gallery > li:nth-child(3) .photo { aspect-ratio: 4 / 5; }   /* closes on a portrait shape, unlike the hero */
}
@media (min-width: 45em), (min-width: 37.5em) and (hover: hover) and (pointer: fine) {
  .gallery { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .gallery > li:nth-child(3) { grid-column: auto; }
  .gallery > li:nth-child(3) .photo { aspect-ratio: 3 / 4; }
}
.plates + .more { margin-top: 1rem; }

/* ---------- Studio ---------- */
/* Stacked at every width: portrait across the page column, its two-line caption, then the text in the
   reading measure. In the 45em tier the portrait takes the column and the height cap of the projects
   index's photograph (see .hero and .projects above), so type and photograph keep the proportion they
   have there; where it is trimmed, the trim comes mostly from the bottom, so the head keeps its air.
   Touch devices from 37.5em to 45em show it whole (3:2); on phones it fills a 4:5 box (its own crop),
   placed so the figure, who stands just right of centre, is centred and whole. */
.studio {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  row-gap: 2rem;
}
.portrait picture { display: block; }
.portrait .photo { object-position: 50% 15%; }
@media (max-width: 37.49em) {
  .portrait .photo { aspect-ratio: 4 / 5; }   /* the phone source is already a 4:5 crop */
}
.portrait figcaption { margin-top: 0.75rem; }  /* two very small lines: name and role, then where the portrait was taken */

/* ---------- Contact row: on the Contact page only ---------- */
/* One compact row, left-aligned: E: email, T: telephone, Instagram icon. Phones: 1rem between the
   items, which keeps all three on one row from 22em (352px). Narrower than that the email takes
   the first row and the telephone and the icon share the second, so the icon is not left alone.
   A desktop window (a zoomed one, in practice) loses 15px to its scrollbar, so there the email takes
   the first row up to 23.5em (376px). */
.contact {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 1rem;
}
@media (max-width: 21.99em), (max-width: 23.49em) and (hover: hover) and (pointer: fine) {
  .contact > li:first-child { flex-basis: 100%; }
}
@media (min-width: 37.5em) {
  .contact { column-gap: 2rem; }
}
/* Normal inline flow (not flex) so the spaces in the accessible names survive. The link's box is its
   line of text, so the focus ring hugs it; the block margins make up the row (--row). The 44px target
   is its ::after (see .lnk), which reaches past a scaled row by --tap-over, above and below. */
.contact a {
  position: relative;
  display: inline-block;
  margin-block: max(0px, calc((var(--row) - 1.6em) / 2));
  overflow-wrap: anywhere;
  transition: color 0.2s ease;
}
.contact a:hover { color: var(--ivory-quiet); }   /* the whole link turns quiet; the prefix already is */
/* Brand-book prefixes, visible and part of the link name; abbr expands them. No dotted underline (brand). */
.contact abbr {
  color: var(--ivory-quiet);
  text-decoration: none;
  border: 0;
  cursor: inherit;
}
/* Instagram: the icon alone (its name is visually hidden text). The link's box is the 1.25rem glyph,
   so the visible spacing of the row stays even and the glyph sits on the column's edge when it wraps;
   its 44px target, centred on the glyph, reaches into the gaps either side. */
.contact .icon-link {
  display: inline-flex;
  margin-block: max(0px, calc((var(--row) - 1.25rem) / 2));
}
.icon { display: block; flex: none; width: 1.25rem; height: 1.25rem; }

/* ---------- Contact page ---------- */
.page > .contact { margin-top: 0.5rem; }
.place { margin-top: 0.5rem; }                 /* the company address, in the text role, on its own line: not a fourth contact item */

/* ---------- Footer: the colophon alone, on every page ---------- */
/* Top padding: a full block space (--space), so the colophon never reads as one more line of the page's
   text (the Studio paragraphs, a project line) and stays clear of an arrow link's target above it.
   Bottom padding: the header's top spacing (1.5rem in the 45em tier, 2rem from 64em), never less than 1rem. */
.site-footer {
  padding-top: var(--space);
  padding-bottom: max(1rem, var(--header-top));
}
.colophon {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.25rem 2rem;
}
.colophon .label { letter-spacing: 0.2em; line-height: 1.6; }

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

/* ---------- Print: black on white, nothing hidden, not scaled with the window ---------- */
@media print {
  :root { color-scheme: light; --ink: #fff; --ivory: #000; --ivory-quiet: #444; }   /* #444 on white: 9.7:1 */
  html { font-size: 100%; }
  html, body { background: #fff; color: #000; }
  body { min-height: 0; }
  .logo img { filter: brightness(0); }   /* the ivory logo file prints black */
}
