/* 1:1 CONCEPTS, the scroll cinematic.
 *
 * Two rules run the whole sheet:
 *   1. every chapter is FULL BLEED. There is no column, no reserved half, no dead margin.
 *   2. one ink on one paper, and the ink is dark. The build this replaced set copy in a pale
 *      grey on cream at a small size, which is why it could not be read.
 *
 * Breakpoints decided before building: desktop >=1024, tablet 760-1023, phone <760.
 */

:root {
  --paper: #faf9f6;
  --ink: #181817;
  --ink-2: rgba(24, 24, 23, 0.72);
  --ink-3: rgba(24, 24, 23, 0.46);
  --hair: rgba(24, 24, 23, 0.16);
  --rail: 2rem;
  --pad: clamp(1.25rem, 4vw, 3.5rem);
  --serif: 'Cormorant Garamond', Georgia, serif;
  --sans: 'Inter', system-ui, -apple-system, sans-serif;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  -webkit-font-smoothing: antialiased;
}

/* nothing scrolls until the loader has handed over */
html.cn-locked, html.cn-locked body { overflow: hidden; height: 100%; }
/* `overflow` is NOT animatable, so trying to release the scroll lock with a keyframe did nothing
   at all. The release is done by the dependency-free script in the page instead. */

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

/* the paper has a tooth, at a weight you feel rather than see */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.5;
  background-image: radial-gradient(rgba(24, 24, 23, 0.055) 0.5px, transparent 0.6px);
  background-size: 3px 3px;
}

/* ------------------------------------------------------------------ header */

.cn-head {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 60;
  height: 5.25rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 var(--pad);
  pointer-events: none;
}
.cn-head > * { pointer-events: auto; }
/* height is what the header actually constrains, so the mark is sized by height and lets its own
   ratio pick the width. Sizing by width let it grow taller than the header and get cropped. */
.cn-head .cn-mark { height: clamp(30px, 3.4vw, 42px); width: auto; opacity: 0.92; }
.cn-cta {
  font: 500 0.72rem/1 var(--sans);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 0.85rem 1.4rem;
  border: 1px solid var(--ink);
  background: var(--paper);
  transition: background 0.3s ease, color 0.3s ease;
}
.cn-cta:hover { background: var(--ink); color: var(--paper); }

/* -------------------------------------------------------------------- rail */

/* A progress indicator, not a menu: the active chapter goes solid, the rest sit back.
   The marks are the client companies, which is what tells you whose space you are in. */
.cn-rail {
  position: fixed;
  left: var(--rail);
  top: 50%;
  transform: translateY(-50%);
  z-index: 55;
  display: flex;
  gap: 0.75rem;
  align-items: stretch;
}
.cn-rail-track {
  position: relative;
  width: 1px;
  background: var(--hair);
  flex: none;
}
.cn-rail-fill {
  position: absolute;
  inset: 0 0 auto 0;
  height: 100%;
  background: var(--ink);
  transform-origin: top;
  transform: scaleY(0);
  transition: transform 0.2s linear;
}
.cn-pills { display: flex; flex-direction: column; gap: 0.3rem; }

.cn-pill {
  appearance: none;
  border: 1px solid transparent;
  background: transparent;
  cursor: pointer;
  padding: 0.42rem 0.7rem;
  min-width: 6.5rem;
  height: 2.5rem;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  opacity: 0.52;
  filter: grayscale(1);
  transition: opacity 0.35s ease, filter 0.35s ease, border-color 0.35s ease, background 0.35s ease;
}
.cn-pill img { width: auto; max-height: 1.55rem; max-width: 5.4rem; }
/* Nivara and Sap Z have no supplied mark, so their name is set as type. Nothing is invented. */
.cn-pill span {
  font: 400 0.78rem/1 var(--serif);
  letter-spacing: 0.05em;
  white-space: nowrap;
}
.cn-pill:hover { opacity: 0.78; }
/* Active is the mark at full strength with a rule beneath it. NEVER a filled panel: a white box
   behind a transparent logo is exactly the boxed-in look the marks were keyed to remove. */
.cn-pill.is-active {
  opacity: 1;
  filter: none;
  border-bottom-color: var(--ink);
}
.cn-pill { border-bottom: 1px solid transparent; }

/* ---------------------------------------------------------------- chapters */

.cn-ch {
  position: relative;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
  z-index: 2;
}

.cn-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

/* the photographs, and the sketch each one resolves out of */
.cn-shot {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  will-change: opacity, transform;
}
.cn-shot img, .cn-shot picture {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* a <picture> is just a wrapper, so the img inside has to fill it too */
.cn-shot picture img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.cn-shot .cn-sketch { opacity: 1; }
.cn-shot .cn-photo { opacity: 0; }

/* Copy over a photograph needs a ground or the ink dies. One paper wash from the bottom, so the
   type colour never changes anywhere on the site.
   ONLY on chapters that have a photograph behind them: `::after` is a positioned child, so it
   paints above ordinary content, and on a flat chapter it washed out the send button and the
   footer. */
.cn-ch.cn-shots::after {
  content: '';
  position: absolute;
  inset: auto 0 0 0;
  height: 46%;
  pointer-events: none;
  background: linear-gradient(to top, var(--paper) 2%, rgba(250, 249, 246, 0.78) 26%, rgba(250, 249, 246, 0) 92%);
}


.cn-shot-open .cn-photo { filter: saturate(0.86) contrast(1.02); }

/* the writing */
.cn-copy {
  position: absolute;
  inset: auto 0 clamp(2.5rem, 7vh, 5rem) 0;
  z-index: 3;
  padding: 0 var(--pad) 0 calc(var(--rail) + 9.5rem);
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  align-items: end;
  gap: clamp(1.5rem, 4vw, 5rem);
  pointer-events: none;
}
.cn-copy > * { pointer-events: auto; }

.cn-eyebrow {
  font: 500 0.68rem/1 var(--sans);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin: 0 0 0.9rem;
}
.cn-title {
  font: 300 clamp(2.6rem, 6.4vw, 5.6rem)/0.98 var(--serif);
  letter-spacing: -0.01em;
  margin: 0;
}
.cn-lede {
  font: 400 clamp(0.95rem, 1.15vw, 1.1rem)/1.62 var(--sans);
  color: var(--ink-2);
  margin: 0;
  max-width: 46ch;
}
.cn-lede + .cn-lede { margin-top: 0.85rem; }

.cn-meta {
  display: flex;
  gap: clamp(1.25rem, 3vw, 2.75rem);
  margin-top: 1.25rem;
  font: 500 0.68rem/1 var(--sans);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.cn-reveal { will-change: filter, transform, opacity; }
.cn-reveal.is-shown { filter: none !important; opacity: 1 !important; transform: none !important; }

/* the scale readout, bottom right, the way a sheet is stamped */
.cn-stamp {
  position: absolute;
  right: var(--pad);
  bottom: clamp(2.5rem, 7vh, 5rem);
  z-index: 4;
  font: 400 clamp(1.6rem, 2.4vw, 2.4rem)/1 var(--serif);
  letter-spacing: 0.1em;
  color: var(--ink-3);
  pointer-events: none;
}

/* Superseded: the opening chapter now carries a photograph of the studio's own door, which fills
   the screen far better than a centred mark did. Kept for any chapter that wants a bare mark. */
.cn-hero {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: grid;
  place-items: center;
  padding: 6rem var(--pad) 34vh;
  pointer-events: none;
}
.cn-hero img { width: min(62vw, 30rem); height: auto; opacity: 0.96; }

/* the scroll hint, only on the first chapter */
.cn-hint {
  position: absolute;
  left: 50%;
  bottom: 1.5rem;
  transform: translateX(-50%);
  z-index: 4;
  font: 500 0.62rem/1 var(--sans);
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--ink-3);
  display: grid;
  justify-items: center;
  gap: 0.5rem;
  pointer-events: none;
}
.cn-hint i { display: block; width: 1px; height: 1.5rem; background: var(--hair); animation: cn-drop 2s ease-in-out infinite; }
@keyframes cn-drop { 0%, 100% { transform: scaleY(0.4); opacity: 0.4; } 50% { transform: scaleY(1); opacity: 1; } }

/* reduced motion: a still backdrop instead of a scrubbed canvas */
.cn-ch.cn-still { background-size: contain; background-position: center; background-repeat: no-repeat; }
.cn-ch.cn-still .cn-canvas { display: none; }

/* the writing always sits above the wash */
.cn-copy, .cn-flat, .cn-stamp, .cn-hint { z-index: 5; }

/* ------------------------------------------------------------ flat chapters */

/* Practice and Enquiry are not cinematic, and the contrast against the scenes is the point.
   They still fill the frame: a grid that uses the whole width, never a half-empty sheet. */
.cn-flat { position: relative; height: 100%; display: grid; align-content: center; gap: clamp(1.5rem, 3.2vh, 2.6rem); padding: 5.5rem var(--pad) 2.5rem calc(var(--rail) + 9.5rem); }
.cn-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1rem, 2.5vw, 2.5rem);
  /* `start`, never the default stretch: a stretched row made each portrait as tall as the whole
     chapter and pushed the names clean out of the frame. */
  align-items: start;
}
.cn-person {
  position: relative;
  /* construction geometry behind each figure: a circle struck from the centre and a baseline,
     the way a draughtsman sets a figure out. Drawn in CSS, so it is crisp at any density and
     costs no asset. */
}
/* Construction geometry behind each portrait: a circle struck from the frame's own centre, wider
   than the frame so it reads past both edges, and the baseline it is struck from. Drawn in CSS, so
   it stays crisp at any density and costs no asset. */
.cn-person { position: relative; }
.cn-person::before {
  content: '';
  position: absolute;
  left: 50%;
  /* Bigger than the frame on every side, because the photograph is opaque: only what reaches past
     the frame can actually be seen. At 128% it was hidden behind the picture. */
  /* Restrained. At 152% the rings were bigger than the frames, overlapped each other across the
     whole section and dominated it. This reads as construction around a picture, not as a diagram. */
  top: -5%;
  width: 110%;
  aspect-ratio: 1;
  transform: translateX(-50%);
  border: 1px solid rgba(24, 24, 23, 0.14);
  border-radius: 50%;
  z-index: 0;
  pointer-events: none;
}
.cn-person::after {
  content: '';
  position: absolute;
  left: -8%; right: -8%;
  top: 46%;
  height: 1px;
  background: rgba(24, 24, 23, 0.12);
  z-index: 0;
  pointer-events: none;
}
/* the photograph sits on top of its own construction */
.cn-person img { position: relative; z-index: 1; }
.cn-person h3, .cn-person p { position: relative; z-index: 1; }
.cn-person img {
  position: relative;
  z-index: 1;
  width: 100%;
  /* the portraits are keyed to transparent PNG, so `contain` on the paper: `cover` would crop a
     cut-out figure and there is no white box left to hide the crop */
  max-height: 34vh;
  aspect-ratio: 1;
  /* `cover` on a square frame: these are photographs presented as photographs, not cut-outs, so a
     defined edge is correct and there is nothing to letterbox. */
  object-fit: cover;
  object-position: top;
  filter: grayscale(1) contrast(1.03);
  /* Two of the three source headshots are framed with the head touching the top edge, so keying
     leaves a hard line across the hair. A gentle fade over the top sliver softens that without
     eating the face. */

}
.cn-person h3 { font: 400 clamp(1rem, 1.5vw, 1.3rem)/1.2 var(--serif); margin: 0.85rem 0 0.2rem; color: var(--ink); }
.cn-person p { font: 400 clamp(0.72rem, 0.9vw, 0.85rem)/1.45 var(--sans); color: var(--ink-2); margin: 0; }

/* A row on ONE baseline. The figures were laid out as free-floating flex items, so a stat whose
   number was empty sat at a different height from the rest and the block read as random. A grid
   with two rows pins every figure to the same line and every caption under it. */
.cn-figs {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, max-content);
  grid-template-rows: auto auto;
  align-items: end;
  justify-content: center;          /* centred, not bunched against the left with dead space right */
  column-gap: clamp(2.5rem, 8vw, 7rem);
  row-gap: 0.5rem;
  text-align: center;
  border-top: 1px solid var(--hair);
  padding-top: clamp(1rem, 2.4vh, 1.6rem);
}
.cn-fig { display: grid; grid-row: 1 / span 2; grid-template-rows: subgrid; align-content: end; justify-items: center; }
@supports not (grid-template-rows: subgrid) {
  /* older engines: still one baseline, just without the shared rows */
  .cn-fig { grid-row: auto; }
}
.cn-fig b {
  display: block;
  font: 300 clamp(2.1rem, 4.2vw, 3.6rem)/0.95 var(--serif);
  letter-spacing: -0.01em;
  align-self: end;
}
.cn-fig.is-long b { font-size: clamp(1.3rem, 2.2vw, 2rem); letter-spacing: 0.02em; }
.cn-fig span {
  font: 500 0.66rem/1.2 var(--sans);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-3);
  align-self: start;
}

@media (max-width: 759px) {
  .cn-figs { grid-auto-flow: row; grid-auto-columns: auto; grid-template-rows: none; column-gap: 0; row-gap: 1rem; }
  .cn-fig { grid-row: auto; grid-template-columns: auto 1fr; align-items: baseline; column-gap: 0.9rem; }
  .cn-fig b { font-size: 1.9rem; }
}

/* wide copy for the framing chapters */
.cn-lede-wide { max-width: 62ch; font-size: clamp(1.05rem, 1.35vw, 1.3rem); }

/* their core: three disciplines, given the room they deserve rather than an eyebrow */
.cn-core { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(1.25rem, 3vw, 3.5rem); }
.cn-core-item { border-top: 1px solid var(--hair); padding-top: 1rem; }
.cn-core-item b { font: 500 0.66rem/1 var(--sans); letter-spacing: 0.2em; color: var(--ink-3); }
.cn-core-item h3 { font: 300 clamp(1.5rem, 2.6vw, 2.3rem)/1.05 var(--serif); margin: 0.6rem 0 0.5rem; }
.cn-core-item p { font: 400 0.9rem/1.55 var(--sans); color: var(--ink-2); margin: 0; max-width: 30ch; }

/* the three scales, so it is obvious what each project chapter is going to do */
.cn-steps { list-style: none; margin: 0; padding: 0; display: flex; gap: clamp(1.5rem, 5vw, 5rem); flex-wrap: wrap; }
.cn-steps li { display: grid; gap: 0.3rem; }
.cn-steps b { font: 400 clamp(1.6rem, 3vw, 2.6rem)/1 var(--serif); letter-spacing: 0.06em; }
.cn-steps span { font: 500 0.66rem/1 var(--sans); letter-spacing: 0.2em; text-transform: uppercase; color: var(--ink-3); }

/* the enquiry: one field at a time, full width, nothing empty beside it */
.cn-form { display: grid; gap: clamp(1.1rem, 2.4vh, 1.9rem); max-width: 62rem; }
.cn-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(1.1rem, 2.4vw, 2.2rem); }
.cn-field { display: grid; gap: 0.5rem; }
.cn-field label { font: 500 0.64rem/1 var(--sans); letter-spacing: 0.2em; text-transform: uppercase; color: var(--ink-3); }
.cn-field input, .cn-field textarea {
  font: 400 1.05rem/1.5 var(--sans);
  color: var(--ink);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--hair);
  padding: 0.55rem 0;
  border-radius: 0;
}
.cn-field input:focus, .cn-field textarea:focus { outline: none; border-bottom-color: var(--ink); }
.cn-field textarea { resize: vertical; min-height: 4.5rem; }
.cn-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.cn-send {
  justify-self: start;
  font: 500 0.72rem/1 var(--sans);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  padding: 1rem 2.2rem;
  border: 1px solid var(--ink);
  background: var(--ink);
  color: var(--paper);
  cursor: pointer;
  transition: opacity 0.3s ease;
}
.cn-send:hover { opacity: 0.82; }
.cn-note { font: 400 0.85rem/1.5 var(--sans); color: var(--ink-3); margin: 0; }
.cn-foot { font: 400 0.78rem/1.7 var(--sans); color: var(--ink-3); display: flex; gap: 2rem; flex-wrap: wrap; }

/* ------------------------------------------------------------------ loader */

.cn-load {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: var(--paper);
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: opacity 0.8s ease;
}
.cn-load.is-gone { opacity: 0; pointer-events: none; }

/* A LAST RESORT WITH NO JAVASCRIPT IN IT. If the script fails to load, is blocked, or throws, this
   animation still retires the loading screen so the site is never a permanently blank sheet.
   `forwards` holds the end state. */
@keyframes cn-bail { 0%, 92% { opacity: 1; visibility: visible; } 100% { opacity: 0; visibility: hidden; } }
.cn-load { animation: cn-bail 16s linear forwards; }
.cn-load canvas { width: min(78vw, 46rem); height: min(52vh, 26rem); }
.cn-load-top {
  position: absolute;
  top: var(--pad);
  left: var(--pad);
  font: 500 0.64rem/1 var(--sans);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.cn-pct-wrap {
  position: absolute;
  right: var(--pad);
  bottom: var(--pad);
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  color: var(--ink);
}
.cn-pct { font: 300 clamp(3.5rem, 9vw, 7.5rem)/0.85 var(--serif); }
.cn-pct-wrap i { font: 500 0.7rem/1 var(--sans); letter-spacing: 0.2em; text-transform: uppercase; color: var(--ink-3); font-style: normal; }
.cn-gate {
  position: absolute;
  left: 50%;
  bottom: 16%;
  transform: translateX(-50%);
  font: 500 0.7rem/1 var(--sans);
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--ink);
  opacity: 0;
  transition: opacity 0.6s ease;
  white-space: nowrap;
}
.cn-gate.is-on { opacity: 1; animation: cn-pulse 2.6s ease-in-out infinite; }
@keyframes cn-pulse { 0%, 100% { opacity: 0.45; } 50% { opacity: 1; } }

/* ------------------------------------------------------------- breakpoints */

@media (max-width: 1023px) {
  :root { --rail: 1rem; }
  .cn-copy {
    grid-template-columns: minmax(0, 1fr);
    padding-left: calc(var(--rail) + 7.5rem);
    gap: 1rem;
  }
  .cn-flat { padding-left: calc(var(--rail) + 7.5rem); }
  .cn-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cn-pill { min-width: 5.6rem; }
  .cn-pill img { max-width: 4.4rem; }
}

@media (max-width: 759px) {
  /* the rail costs too much width on a phone, so it moves to a strip under the header and the
     chapters get the whole screen */
  .cn-rail {
    left: 0; right: 0; top: 5.4rem;
    transform: none;
    padding: 0 var(--pad);
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .cn-rail::-webkit-scrollbar { display: none; }
  .cn-rail-track { display: none; }
  .cn-pills { flex-direction: row; gap: 0.4rem; }
  .cn-pill { height: 2.1rem; min-width: auto; padding: 0.3rem 0.6rem; }
  .cn-pill img { max-height: 1.15rem; max-width: 3.6rem; }

  .cn-copy {
    padding: 0 var(--pad);
    /* A hard ceiling under the header and the rail strip. The copy is bottom-anchored, so if a
       pinned chapter ever measures shorter than the viewport (iOS Safari does this while its
       chrome collapses) the block used to ride up into the logo and the chapter pills. */
    inset: 8.5rem 0 clamp(2rem, 6vh, 3.5rem) 0;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    /* MUST be reset. The desktop rule is a grid with `align-items: end`, which means "bottom" there
       but "right" in a column flex, so every block was shrink-wrapped and pushed to the right edge:
       that was the gap on the left of the heading. */
    align-items: stretch;
    overflow: hidden;
  }
  /* every block flush to the same left edge: the heading was sitting 70px in from the paragraph */
  .cn-copy > * { margin-left: 0; padding-left: 0; width: 100%; }
  .cn-hint { display: none; }          /* it collided with the copy on a phone */
  .cn-hero { padding: 8rem var(--pad) 42vh; }
  .cn-hero img { width: 74vw; }
  .cn-flat { padding: 9rem var(--pad) 3rem; }
  /* three across, not stacked: stacked portraits ran past the bottom of a phone and clipped the
     third architect's name off the screen entirely */
  .cn-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.7rem; }
  .cn-person img { max-height: 16vh; aspect-ratio: 3 / 4; }
  .cn-person h3 { font-size: 0.82rem; margin-top: 0.5rem; }
  .cn-person p { font-size: 0.62rem; line-height: 1.35; }
  .cn-row { grid-template-columns: minmax(0, 1fr); }
  .cn-stamp { font-size: 1.2rem; bottom: auto; top: 8.6rem; right: var(--pad); }
  .cn-ch::after { height: 58%; }
}
