/* ============================================================
   THE CLOSE — one ending for every page
   ------------------------------------------------------------
   The site used to stop four different ways: index had a contact
   section stacked on a thin footer bar (two endings, one after the
   other), about had its own unified sheet written in about.css and
   reachable from nowhere else, project.html dead-ended on a three-item
   strip with no way to reach the studio at all, and projects.html
   simply stopped. This file is the single ending all four now share.

   ------------------------------------------------------------
   THE ARGUMENT: THE APERTURE

   The first version of this footer was a title block — the ruled
   panel a drawing carries in its corner — with the invitation and a
   ledger of facts side by side. It was correct and it was inert: two
   columns of small type, the one thing you can actually DO buried
   inside the left one at the same scale as everything around it.

   This version inverts that. The address is the largest thing on the
   sheet, because it is the only thing here anybody came for; the
   invitation shrinks to the label above it. And the address does not
   fade in — it OPENS, from the centre outward, the way a door does.
   That is the site's own vocabulary returning at the scale of a
   doorway: the hero already reads its keywords through apertures, so
   the page ends on the same gesture it began with.

   Three rows, in the order you would read a drawing:
     1. the invitation — label, live clock, one line, the address
     2. the dimensions — four labelled cells, ruled as they arrive
     3. the base + fine — the mark, the sitemap, the way back, rights

   Every hairline in here DRAWS rather than appears. A rule that fades
   up is a rule someone typed; a rule that runs out from its origin is
   a rule someone struck. It costs one scale transform each and it is
   the difference between a footer and a drawing.

   Ground is deliberately transparent: index and projects end on white,
   about ends on paper, project ends under a full-bleed dark plate. A
   band of its own colour would fight one of them whatever colour it
   was, so the close takes the ground it lands on and draws in ink.
   ============================================================ */

footer.close {
  --cl-ink: #0a0a0a;
  --cl-dim: #6f6a63;
  --cl-line: rgba(10, 10, 10, .14);
  --cl-e: cubic-bezier(.22, 1, .36, 1);

  position: relative;
  display: block;
  width: 100%;
  max-width: none;
  margin: 0;
  padding: 0;
  /* Every row starts 14px below its resting place and every rule starts
     scaled to nothing. This is the last element on the page, so without
     a crop those offsets are a sliver of scrollable space under the
     footer for as long as the arrival takes. */
  overflow: hidden;
  color: var(--cl-ink);
  background: transparent;
  font-family: var(--sans, 'Poppins', sans-serif);
  text-align: left;
}

/* The datum the whole sheet hangs from. An element rather than
   border-top because it has to be able to run out from the left edge
   instead of switching on. */
footer.close::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--cl-line);
  transform-origin: left;
}

.cl-shell {
  width: 100%;
  max-width: 1320px;
  margin: 0 auto;
  padding: 0 clamp(20px, 5vw, 64px);
}

/* -- shared cell lettering ---------------------------------------
   Every label in the sheet is the same object: small, tracked, quiet.
   Defining it once is what makes the cells read as one system rather
   than four separately-styled corners. */
.cl-lbl {
  display: block;
  margin: 0 0 7px;
  font-size: .6rem;
  font-weight: 500;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--cl-dim);
}

/* ============================================================
   1. THE INVITATION
   ============================================================ */
.cl-invite {
  padding: clamp(52px, 8.5svh, 112px) 0 clamp(34px, 5svh, 62px);
}

/* Label and clock share one baseline: what this block is, and the fact
   that there is somebody at the other end of it right now. */
.cl-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  margin: 0 0 clamp(16px, 2.6svh, 30px);
}
.cl-head .cl-lbl { margin: 0; }

/* The one live thing in the sheet: the studio's own clock, computed
   from the timezone of the address two rows down. Tabular figures so
   the minute changing does not shift the line it sits on. */
.cl-clock {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  flex: 0 0 auto;
  font-size: .6rem;
  font-weight: 400;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--cl-dim);
  white-space: nowrap;
}
.cl-clock::before {
  content: '';
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--cl-ink);
  animation: clPulse 2.6s var(--cl-e) infinite;
}
@keyframes clPulse {
  0%, 62%, 100% { opacity: .28; transform: scale(1); }
  16%           { opacity: 1;   transform: scale(1.35); }
}
.cl-clock b {
  font-weight: 400;
  font-variant-numeric: tabular-nums;
  letter-spacing: .06em;
  color: var(--cl-ink);
}

/* Demoted on purpose. It used to be the headline; the address is the
   headline now, and this is the sentence that introduces it. */
.cl-line {
  margin: 0 0 clamp(22px, 3.6svh, 44px);
  max-width: 22ch;
  font-family: var(--serif, 'Instrument Serif', serif);
  font-weight: 400;
  font-size: clamp(1.5rem, 3.1vw, 2.5rem);
  line-height: 1.08;
  letter-spacing: -.005em;
}

/* -- the address --------------------------------------------------
   Set at display scale, because it is the whole point of the page's
   last screen. Sixteen characters of this face run about 5.7× the font
   size, so 11.5vw puts the address at roughly two thirds of the window
   at every width — always the largest thing on the sheet, never close
   to the shell's edge. Below ~975px the vw term governs; above it the
   7rem cap takes over and the white space to the right of the address
   opens up instead. It never needs to wrap and is never allowed to. */
.cl-mail {
  position: relative;
  display: inline-block;
  max-width: 100%;
  padding-bottom: clamp(10px, 1.4svh, 16px);
  font-family: var(--serif, 'Instrument Serif', serif);
  font-size: clamp(2rem, 11.5vw, 7rem);
  line-height: 1.12;
  letter-spacing: -.02em;
  color: var(--cl-ink);
  text-decoration: none;
  white-space: nowrap;
}

/* The door. Its width is the address's width, so the opening is
   exactly as wide as what it reveals. */
.cl-mail-aperture {
  position: relative;
  display: block;
  overflow: hidden;
}
/* Two copies of the address in one opening: the first is in flow and
   therefore sets the aperture's height exactly, the second is pinned
   over it one line below. Hovering rolls both up by exactly their own
   height — no measured offsets, nothing to round wrong. */
.cl-mail-text {
  display: block;
  transition: transform .62s var(--cl-e);
}
.cl-mail-text + .cl-mail-text {
  position: absolute;
  inset: 0;
  transform: translateY(100%);
}
.cl-mail:hover .cl-mail-text,
.cl-mail:focus-visible .cl-mail-text { transform: translateY(-100%); }
.cl-mail:hover .cl-mail-text + .cl-mail-text,
.cl-mail:focus-visible .cl-mail-text + .cl-mail-text { transform: translateY(0); }

/* Separate element rather than a border so it can wipe from one side
   without the address moving. */
.cl-mail-rule {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--cl-ink);
  transform-origin: left;
  transition: transform .55s var(--cl-e);
}
.cl-mail:hover .cl-mail-rule,
.cl-mail:focus-visible .cl-mail-rule { animation: clWipe .72s var(--cl-e); }
@keyframes clWipe {
  0%   { transform: scaleX(1); transform-origin: right; }
  49%  { transform: scaleX(0); transform-origin: right; }
  51%  { transform: scaleX(0); transform-origin: left; }
  100% { transform: scaleX(1); transform-origin: left; }
}

/* ============================================================
   2. THE DIMENSIONS — four labelled cells
   A <dl>, because that is what it is: four terms and their values.
   The rules are drawn, not bordered: the top rule of each cell runs
   out from the left, the divider between cells runs down from the
   top, and both are staggered so the strip is ruled left to right
   like a hand moving across a sheet.
   ============================================================ */
.cl-dims {
  --gap: clamp(20px, 3vw, 46px);
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  column-gap: var(--gap);
  row-gap: clamp(18px, 3svh, 32px);
  margin: 0;
  padding-bottom: clamp(30px, 4.5svh, 54px);
}
.cl-cell {
  position: relative;
  min-width: 0;
  padding-top: clamp(13px, 1.9svh, 19px);
}
/* the rule above the cell */
.cl-cell::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--cl-line);
  transform-origin: left;
}
/* the divider before it — sits in the middle of the column gap so the
   first cell in a row still lines up flush with the address above */
.cl-cell::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 6px;
  left: calc(var(--gap) / -2);
  width: 1px;
  background: var(--cl-line);
  transform-origin: top;
}
.cl-cell:first-child::after { display: none; }

.cl-cell dd {
  margin: 0;
  font-size: clamp(.78rem, .95vw, .87rem);
  font-weight: 300;
  line-height: 1.62;
  font-style: normal;
}
.cl-cell dd a {
  color: var(--cl-ink);
  text-decoration: none;
  border-bottom: 1px solid var(--cl-line);
  transition: border-color .4s var(--cl-e);
}
.cl-cell dd a:hover,
.cl-cell dd a:focus-visible { border-bottom-color: var(--cl-ink); }
/* Two links on one line need a separator that is not a character in
   either of them. */
.cl-cell dd a + a { margin-left: 14px; }

/* ============================================================
   3. THE BASE — mark | sitemap | way back
   ============================================================ */
.cl-base {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(16px, 3vw, 44px);
  padding: clamp(18px, 2.8svh, 30px) 0;
}
.cl-base::before,
.cl-fine::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--cl-line);
  transform-origin: left;
}
.cl-home {
  display: block;
  flex: 0 0 auto;
  line-height: 0;
}
.cl-home img {
  height: clamp(30px, 3.4vw, 40px);
  width: auto;
  /* The mark ships light. Every ground the close lands on is light. */
  filter: invert(1);
  opacity: .88;
  transition: transform .5s var(--cl-e), opacity .4s var(--cl-e);
}
.cl-home:hover img { transform: translateY(-3px); opacity: 1; }

.cl-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: clamp(14px, 2.4vw, 34px);
  min-width: 0;
}
.cl-nav a {
  position: relative;
  display: inline-block;
  padding-bottom: 3px;
  font-size: .64rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--cl-dim);
  text-decoration: none;
  transition: color .45s var(--cl-e);
}
.cl-nav a::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform .5s var(--cl-e);
}
.cl-nav a:hover,
.cl-nav a:focus-visible,
.cl-nav a[aria-current="page"] { color: var(--cl-ink); }
.cl-nav a:hover::after,
.cl-nav a:focus-visible::after,
.cl-nav a[aria-current="page"]::after {
  transform: scaleX(1);
  transform-origin: left;
}

.cl-up {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: .62rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--cl-dim);
  text-decoration: none;
  white-space: nowrap;
  transition: color .45s var(--cl-e);
}
.cl-up:hover, .cl-up:focus-visible { color: var(--cl-ink); }
/* Drawn rather than typed: an arrow glyph inherits the font's own
   idea of weight and sits off the text's optical centre. */
.cl-up-arrow {
  position: relative;
  width: 1px;
  height: 22px;
  background: currentColor;
  transition: transform .5s var(--cl-e);
}
.cl-up-arrow::before,
.cl-up-arrow::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 7px;
  height: 1px;
  background: currentColor;
  transform-origin: left center;
}
.cl-up-arrow::before { transform: rotate(-45deg); }
.cl-up-arrow::after  { transform: rotate(-135deg); }
.cl-up:hover .cl-up-arrow { transform: translateY(-4px); }

/* -- the fine print ----------------------------------------------
   Deliberately the thinnest row on the sheet. It is the last thing and
   it should read like the last thing. */
.cl-fine {
  position: relative;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: clamp(12px, 3vw, 32px);
  padding: clamp(13px, 2svh, 20px) 0 clamp(30px, 5svh, 60px);
  font-size: .62rem;
  font-weight: 300;
  letter-spacing: .1em;
  color: var(--cl-dim);
}

/* ============================================================
   EVERY SCREEN
   The dimension strip folds in two stages, and each stage is a
   decision about what stops fitting first — not a width picked
   because it is round.
   ============================================================ */

/* Four values stop having room to sit beside each other once a column
   is narrower than the studio's two-line address. */
@media (max-width: 1100px) {
  .cl-dims { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* Every odd cell is now first in its row, so it loses the divider. */
  .cl-cell:nth-child(odd)::after { display: none; }
}

/* One line of a phone number is the narrowest a cell gets to be. */
@media (max-width: 620px) {
  .cl-dims { grid-template-columns: minmax(0, 1fr); row-gap: 0; }
  .cl-cell::after { display: none; }
  .cl-line { max-width: none; }
}

/* The sitemap stops fitting between the mark and the way back before
   any of it stops fitting on the page. */
@media (max-width: 760px) {
  .cl-base {
    grid-template-columns: auto auto;
    justify-content: space-between;
    row-gap: clamp(16px, 2.6svh, 24px);
  }
  .cl-nav {
    order: 3;
    grid-column: 1 / -1;
    justify-content: flex-start;
    gap: clamp(14px, 4.5vw, 28px);
  }
}

/* Copyright and rights reserved on one line stop fitting well before
   either of them stops fitting alone. */
@media (max-width: 520px) {
  .cl-fine {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }
  .cl-head {
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
  }
}

/* A short window in landscape has no vertical budget to spend on the
   opening gap. */
@media (max-height: 640px) and (min-width: 721px) {
  .cl-invite { padding-top: clamp(34px, 6svh, 60px); }
}

/* ============================================================
   ARRIVAL
   Gated on html.has-close, which close.js adds. A blocked script
   therefore leaves the whole sheet drawn and readable rather than a
   footer that never fades in.

   Two mechanisms, both keyed off --i (set per element by close.js) so
   the whole sheet resolves in one continuous sweep rather than in
   separately-tuned groups:
     · type rises and fades
     · rules scale out from their origin
   ============================================================ */

/* -- type -- */
html.has-close .close .cl-eyebrow,
html.has-close .close .cl-clock,
html.has-close .close .cl-line,
html.has-close .close .cl-cell > *,
html.has-close .close .cl-base > *,
html.has-close .close .cl-fine > * {
  opacity: 0;
  translate: 0 14px;
  transition: opacity .7s var(--cl-e), translate .9s var(--cl-e);
  transition-delay: calc(var(--i, 0) * 60ms);
}
html.has-close .close.is-in .cl-eyebrow,
html.has-close .close.is-in .cl-clock,
html.has-close .close.is-in .cl-line,
html.has-close .close.is-in .cl-cell > *,
html.has-close .close.is-in .cl-base > *,
html.has-close .close.is-in .cl-fine > * {
  opacity: 1;
  translate: 0 0;
}

/* -- the aperture --
   The address does not rise with the rest of the type. It opens from
   the centre outward, which is the one gesture in this footer that is
   worth spending a full second on. */
html.has-close .close .cl-mail-aperture {
  clip-path: inset(0 50% 0 50%);
  transition: clip-path 1.05s var(--cl-e);
  transition-delay: calc(var(--i, 0) * 60ms);
}
html.has-close .close.is-in .cl-mail-aperture { clip-path: inset(0 0 0 0); }
/* The rule under it strikes left to right once the door is open. */
html.has-close .close .cl-mail-rule {
  transform: scaleX(0);
  transition: transform .8s var(--cl-e);
  transition-delay: calc(var(--i, 0) * 60ms + 260ms);
}
html.has-close .close.is-in .cl-mail-rule { transform: scaleX(1); }

/* -- rules --
   Each is struck from its own origin: the horizontals run out from the
   left, the cell dividers run down from the top. */
html.has-close .close::before,
html.has-close .close .cl-cell::before,
html.has-close .close .cl-base::before,
html.has-close .close .cl-fine::before {
  transform: scaleX(0);
  transition: transform .85s var(--cl-e);
  transition-delay: calc(var(--i, 0) * 60ms);
}
html.has-close .close .cl-cell::after {
  transform: scaleY(0);
  transition: transform .6s var(--cl-e);
  transition-delay: calc(var(--i, 0) * 60ms + 140ms);
}
html.has-close .close.is-in::before,
html.has-close .close.is-in .cl-cell::before,
html.has-close .close.is-in .cl-base::before,
html.has-close .close.is-in .cl-fine::before { transform: scaleX(1); }
html.has-close .close.is-in .cl-cell::after { transform: scaleY(1); }

@media (prefers-reduced-motion: reduce) {
  html.has-close .close .cl-eyebrow,
  html.has-close .close .cl-clock,
  html.has-close .close .cl-line,
  html.has-close .close .cl-cell > *,
  html.has-close .close .cl-base > *,
  html.has-close .close .cl-fine > * {
    opacity: 1;
    translate: none;
    transition: none;
  }
  html.has-close .close .cl-mail-aperture {
    clip-path: none;
    transition: none;
  }
  html.has-close .close .cl-mail-rule,
  html.has-close .close::before,
  html.has-close .close .cl-cell::before,
  html.has-close .close .cl-base::before,
  html.has-close .close .cl-fine::before { transform: scaleX(1); transition: none; }
  html.has-close .close .cl-cell::after { transform: scaleY(1); transition: none; }
  .cl-clock::before { animation: none; opacity: .55; }
  .cl-mail-text { transition: none; }
  .cl-mail:hover .cl-mail-rule,
  .cl-mail:focus-visible .cl-mail-rule { animation: none; }
  .cl-home img,
  .cl-up-arrow,
  .cl-nav a::after { transition: none; }
}
