/* ═══════════════════════════════════════════════════════════════════
   Alderton Rowe — concept site for TKO Solutions.

   A fictional London interior architecture practice, built so the film
   is the site and the interface stays out of its way.

   The rules this was drawn to:
     · one display face, one sans, and no third
     · nothing has a corner radius, a shadow or a border box
     · rules are hairlines, and there are few of them
     · sections do not share a rhythm — the page is set, not assembled
     · capitals are for metadata only, never for headings or prose
     · motion is opacity and about 14px of travel, nothing else

   The palette is taken off the film — limestone, walnut, a warm black —
   but deliberately quieter than it. The apartment supplies the gold; the
   page does not compete with it.
   ═══════════════════════════════════════════════════════════════════ */

:root {
  --stone:    #EFECE6;   /* the ground */
  --paper:    #F6F4EF;   /* insets, forms */
  --ink:      #1C1917;   /* warm black, never #000 */
  --ink-2:    #5C5349;   /* metadata, captions — 6.4:1 on the stone */
  --ink-3:    #6E665C;   /* 4.8:1 */
  --rule:     #D9D2C7;
  --walnut:   #7A5B3E;   /* used about four times in the whole site */
  --dark:     #191614;

  --display: "Newsreader", "Times New Roman", Georgia, serif;
  --sans: "Inter", -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;

  /* One measure for the page and one for text, so nothing is arbitrary. */
  --strip: 34px;   /* the concept bar, fixed so the pin can size against it */
  --shell: 1560px;
  --gut: clamp(22px, 5vw, 90px);
  --measure: 62ch;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0; padding-top: var(--strip); background: var(--stone); color: var(--ink);
  font-family: var(--sans); font-size: 16px; line-height: 1.6;
  font-feature-settings: "kern" 1;
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}
/* height: auto is not optional. Without it an HTML height attribute becomes
   the CSS height as soon as width is 100%, object-fit computes to fill, and
   every picture is stretched to whatever number is in the markup. */
img, video { display: block; max-width: 100%; height: auto; }
p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; }
:focus-visible { outline: 1.5px solid var(--walnut); outline-offset: 3px; }

/* Display type sits light and large. Newsreader's optical sizing does the
   work that a heavier weight would otherwise have to. */
h1, h2, h3, h4 {
  margin: 0; font-family: var(--display); font-weight: 300;
  line-height: 1.08; letter-spacing: -0.015em; font-optical-sizing: auto;
}
.d-xl { font-size: clamp(2.6rem, 6.2vw, 5.1rem); line-height: 1.02; letter-spacing: -0.022em; }
.d-lg { font-size: clamp(2.1rem, 4.4vw, 3.5rem); }
.d-md { font-size: clamp(1.5rem, 2.6vw, 2.15rem); line-height: 1.16; }
.d-sm { font-size: clamp(1.2rem, 1.7vw, 1.45rem); line-height: 1.25; }
em, .it { font-style: italic; }

/* The only place capitals appear. */
.meta {
  font-family: var(--sans); font-size: 11px; font-weight: 500;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-2);
}
.lede { font-size: clamp(1.0625rem, 1.35vw, 1.1875rem); line-height: 1.65; color: var(--ink); max-width: var(--measure); }
.body { color: var(--ink-2); max-width: var(--measure); }
.body p + p { margin-top: 1.1em; }
.small { font-size: 14px; }
.muted { color: var(--ink-2); }

.shell { width: 100%; max-width: var(--shell); margin-inline: auto; padding-inline: var(--gut); }
.rule { height: 1px; background: var(--rule); border: 0; margin: 0; }

/* ── the film ─────────────────────────────────────────────────────── */
/* svh, not vh: on iOS the address bar makes vh taller than the screen and
   the scroll cue lands under the chrome. */
/* The film is scrubbed by scroll, so the section is a tall block with a sticky
   child. Nothing is hijacked: the scrollbar, the keyboard and find-in-page all
   behave normally, and the reader can leave at any point by carrying on.

   The sticky child is sized against the fixed strip rather than 100svh, which
   is what keeps the project identifier and the scroll cue on screen. */
/* How tall this is decides how fast the film runs. Over 300svh a trackpad
   notch advanced four frames at once and the motion stepped; at 450 it is
   closer to two, which the eye reads as movement rather than as a flick book.
   A phone scrolls continuously and finely, so it needs less. */
/* How much scroll the film costs, which is what sets its speed. The measure
   that matters is pixels of scroll per second of footage: it was 209, which
   read as a rush. At 800svh it is about 420 — half the pace for the same
   fifteen seconds. A phone covers distance far faster under a thumb, so it
   gets less. */
.filmpin { position: relative; height: 800vh; height: 800svh; }
@media (max-width: 820px) { .filmpin { height: 600vh; height: 600svh; } }
.filmsticky {
  position: sticky; top: var(--strip);
  height: calc(100vh - var(--strip)); height: calc(100svh - var(--strip));
  min-height: 480px; overflow: hidden; background: var(--dark);
}
.hero { position: relative; height: 100%; overflow: hidden; background: var(--dark); }
/* The poster is a fallback, not a layer: it stands in until the first frame
   is on the canvas and is then taken out of the way. Without this it simply
   paints over the canvas — both are absolute, neither had a z-index, and the
   image is later in the DOM, so it won. The scrub ran perfectly underneath it
   the whole time. */
.hero canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; z-index: 1; }
.hero .poster { z-index: 0; }
.hero[data-painted="true"] .poster { opacity: 0; }
/* The scroll cue has done its job once the scrub has started. */
.filmpin .scroll { transition: opacity 500ms ease; opacity: calc(1 - (var(--p, 0) * 6)); }
.hero video, .hero canvas, .hero .poster {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center;
}
/* Only as much shading as the type needs, top and bottom, and nothing
   across the middle where the room is. */
.hero::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 2;
  background:
    linear-gradient(to bottom, rgba(14,11,9,.72) 0%, rgba(14,11,9,.32) 15%, rgba(14,11,9,0) 34%),
    linear-gradient(to top, rgba(14,11,9,.66) 0%, rgba(14,11,9,.28) 20%, rgba(14,11,9,0) 50%),
    linear-gradient(to right, rgba(14,11,9,.30) 0%, rgba(14,11,9,0) 46%);
}
.hero-in {
  position: relative; z-index: 3; height: 100%;
  display: grid; grid-template-rows: auto 1fr auto;
  padding-block: clamp(22px, 3.4vw, 40px) clamp(24px, 3.4vw, 44px);
  color: #F3EFE8;
}

/* ── masthead ─────────────────────────────────────────────────────── */
.top { display: flex; align-items: baseline; justify-content: space-between; gap: 24px; }
.wordmark {
  font-family: var(--display); font-weight: 300; font-size: clamp(1.05rem, 1.5vw, 1.3rem);
  letter-spacing: 0.02em; line-height: 1; white-space: nowrap;
}
/* The one piece of hero type that sits high enough to catch the bright ceiling
   in the last seconds of the clip; measured at 4.44:1 against #F3EFE8. */
.hero .wordmark { color: #FFFDF9; }
.wordmark .r { font-style: italic; }
.nav { display: flex; gap: clamp(18px, 2.4vw, 34px); }
.nav a { font-size: 13px; letter-spacing: 0.01em; padding-block: 4px; position: relative; color: inherit; }
/* A hairline that grows from the left rather than a colour change. */
.nav a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: currentColor; transform: scaleX(0); transform-origin: left;
  transition: transform 420ms cubic-bezier(.22,.61,.36,1);
}
.nav a:hover::after, .nav a[aria-current="page"]::after { transform: scaleX(1); }
.nav a[aria-current="page"] { opacity: .72; }
.navclose { display: none; }
.navtoggle { display: none; background: none; border: 0; padding: 6px 0; cursor: pointer; font-size: 13px; }

/* ── hero copy ────────────────────────────────────────────────────── */
.hero-say { align-self: end; max-width: 21ch; margin-bottom: clamp(22px, 3vw, 44px); }
.hero-say h1 { font-size: clamp(1.9rem, 3.5vw, 3.1rem); font-weight: 200; line-height: 1.06; letter-spacing: -0.02em; }
.hero-foot { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; }
.ident { display: grid; gap: 2px; }
.ident .meta { color: rgba(243,239,232,.94); }
.ident .place { font-family: var(--display); font-size: 1.0625rem; }
.scroll { display: inline-flex; align-items: center; gap: 10px; font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: rgba(243,239,232,.92); background: none; border: 0; cursor: pointer; padding: 0; }
.scroll i { display: block; width: 46px; height: 1px; background: currentColor; transform-origin: left; animation: draw 3.4s cubic-bezier(.4,0,.2,1) infinite; }
@keyframes draw { 0%, 100% { transform: scaleX(.3); opacity: .5 } 50% { transform: scaleX(1); opacity: 1 } }

.filmctl {
  position: absolute; right: var(--gut); bottom: calc(clamp(24px, 3.4vw, 44px) + 62px); z-index: 3;
  background: none; border: 0; cursor: pointer; padding: 6px;
  font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: rgba(243,239,232,.96);
}
.filmctl:hover { color: #fff; }

/* ── page header, for the inner pages ─────────────────────────────── */
.pagetop { background: var(--stone); padding-block: clamp(26px, 3vw, 38px) 0; }
.pagetop .top { color: var(--ink); }
.pagetop .nav a { color: var(--ink); }

/* ── sections: each with its own rhythm, not one repeated block ───── */
.band { padding-block: clamp(78px, 11vw, 190px); }
.band-tight { padding-block: clamp(54px, 7vw, 110px); }
.band-dark { background: var(--dark); color: #EDE7DE; }
.band-dark .body, .band-dark .muted { color: #A8A099; }
.band-dark .meta { color: #A8A099; }

/* The introduction runs as a 12-column grid so the statement can sit off
   the left edge without being centred. */
.grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: 0 clamp(18px, 2.4vw, 40px); }
.intro-eyebrow { grid-column: 1 / span 2; }
.intro-say { grid-column: 3 / span 8; }
.intro-body { grid-column: 3 / span 5; margin-top: clamp(34px, 4vw, 62px); }
.intro-disc { grid-column: 9 / span 4; margin-top: clamp(34px, 4vw, 62px); align-self: end; }
.disc { display: grid; gap: 0; }
.disc li { padding: 11px 0; border-top: 1px solid var(--rule); font-size: 14.5px; }
.disc li:last-child { border-bottom: 1px solid var(--rule); }

/* ── projects: an editorial sequence, not a card grid ─────────────── */
.seq { display: grid; gap: clamp(64px, 9vw, 150px); }
.proj { display: block; }
.proj figure { margin: 0; overflow: hidden; background: var(--rule); }
.proj img { width: 100%; height: 100%; object-fit: cover; transition: transform 900ms cubic-bezier(.22,.61,.36,1), filter 600ms ease; }
.proj:hover img { transform: scale(1.018); }
.proj-line { display: flex; align-items: baseline; justify-content: space-between; gap: 20px; margin-top: 18px; padding-bottom: 14px; border-bottom: 1px solid var(--rule); }
.proj-line h3 { font-size: clamp(1.35rem, 2.1vw, 1.85rem); }
.proj-line .no { font-family: var(--sans); font-size: 11px; letter-spacing: .14em; color: var(--ink-3); }
.proj-meta { display: flex; gap: 22px; margin-top: 12px; }

/* The varied proportions live here rather than in the markup. */
.p-full figure { aspect-ratio: 16 / 9; }
.p-wide { grid-column: 1 / span 9; }
.p-wide figure { aspect-ratio: 3 / 2; }
.p-tall { grid-column: 6 / span 5; }
.p-tall figure { aspect-ratio: 4 / 5; }
.p-mid { grid-column: 2 / span 6; }
.p-mid figure { aspect-ratio: 5 / 4; }
.p-inset { grid-column: 9 / span 3; align-self: end; }
.p-inset figure { aspect-ratio: 3 / 4; }

/* A project with no photography yet gets a toned panel that says so, rather
   than a blank rectangle that looks like something failed to load. */
.held { position: relative; }
.held figcaption {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-family: var(--sans); font-size: 11px; font-weight: 500;
  letter-spacing: .14em; text-transform: uppercase; color: var(--ink-2);
}

/* ── case study ───────────────────────────────────────────────────── */
.facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 0; border-top: 1px solid var(--rule); }
.facts > div { padding: 18px 20px 18px 0; border-bottom: 1px solid var(--rule); }
.facts dt { margin-bottom: 6px; }
.facts dd { margin: 0; font-family: var(--display); font-size: 1.15rem; }

figure.plate { margin: 0; }
figure.plate img { width: 100%; }
figure.plate figcaption { margin-top: 12px; font-size: 13px; color: var(--ink-2); max-width: 46ch; }
.bleed { width: 100vw; margin-left: calc(50% - 50vw); }
.pair { display: grid; grid-template-columns: repeat(12, 1fr); gap: clamp(18px, 2.4vw, 40px); align-items: end; }

.filmblock { position: relative; }
.filmblock video { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; background: var(--dark); }

/* ── approach ─────────────────────────────────────────────────────── */
.steps { border-top: 1px solid var(--rule); }
.steps > li { border-bottom: 1px solid var(--rule); }
.steps .row { display: grid; grid-template-columns: 4rem minmax(0, 20ch) minmax(0, 1fr); gap: clamp(16px, 3vw, 48px); align-items: start; padding-block: clamp(26px, 3.2vw, 44px); }
.steps .no { font-family: var(--sans); font-size: 11px; letter-spacing: .14em; color: var(--ink-3); padding-top: .55em; }
.steps h3 { font-size: clamp(1.3rem, 2vw, 1.7rem); }
.steps p { color: var(--ink-2); max-width: 54ch; }

/* ── contact ──────────────────────────────────────────────────────── */
.form { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 clamp(20px, 3vw, 48px); }
.f { grid-column: span 1; padding-block: 6px 20px; }
.f-wide { grid-column: 1 / -1; }
.f label { display: block; margin-bottom: 8px; }
.f input, .f select, .f textarea {
  width: 100%; font: inherit; font-size: 16px; color: var(--ink);
  background: transparent; border: 0; border-bottom: 1px solid var(--rule);
  border-radius: 0; padding: 10px 0; min-height: 44px;
  transition: border-color 300ms ease;
}
.f textarea { resize: vertical; min-height: 110px; line-height: 1.6; }
.f input:focus, .f select:focus, .f textarea:focus { outline: 0; border-bottom-color: var(--ink); }
.f select { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--ink-2) 50%), linear-gradient(135deg, var(--ink-2) 50%, transparent 50%); background-position: right 6px center, right 1px center; background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; }
.btn {
  display: inline-flex; align-items: center; gap: 12px; padding: 15px 0 13px;
  background: none; border: 0; border-bottom: 1px solid var(--ink); border-radius: 0;
  cursor: pointer; font-size: 13px; letter-spacing: .06em;
}
.btn i { display: block; width: 26px; height: 1px; background: currentColor; transition: width 420ms cubic-bezier(.22,.61,.36,1); }
.btn:hover i { width: 42px; }
.note { font-size: 13px; color: var(--ink-3); }
.placeholder { color: var(--walnut); }

/* ── footer ───────────────────────────────────────────────────────── */
.foot { background: var(--dark); color: #B8B0A6; padding-block: clamp(54px, 6vw, 88px) clamp(26px, 3vw, 38px); }
.foot a:hover { color: #F3EFE8; }
.foot .muted, .foot .meta, .foot .note { color: #A79E94; }
.foot .placeholder, .band-dark .placeholder { color: #C0A276; }
.foot .cols { display: grid; grid-template-columns: repeat(12, 1fr); gap: 34px clamp(18px, 2.4vw, 40px); }
.foot .c1 { grid-column: 1 / span 4; }
.foot .c2 { grid-column: 6 / span 3; }
.foot .c3 { grid-column: 9 / span 4; }
.foot h4 { font-family: var(--sans); }
.foot li + li { margin-top: 8px; }
.foot .base { display: flex; flex-wrap: wrap; gap: 8px 28px; justify-content: space-between; margin-top: clamp(48px, 6vw, 84px); padding-top: 20px; border-top: 1px solid rgba(243,239,232,.14); }

/* The wordmark at the foot, set once at size, because the page has earned
   it by then and nothing else on the site is loud. */
.sign { margin-top: clamp(40px, 5vw, 76px); font-family: var(--display); font-weight: 200; line-height: .92; letter-spacing: -0.03em; font-size: clamp(3rem, 12.5vw, 12rem); color: rgba(243,239,232,.13); }
.sign .r { font-style: italic; }

/* ── the concept strip, which is TKO's and not the studio's ──────── */
.concept {
  position: fixed; inset: 0 0 auto; z-index: 60; height: var(--strip);
  background: #0F0D0C; color: #8A8178; font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
}
.concept .shell { display: flex; align-items: center; justify-content: space-between; gap: 14px; height: 100%; }
@media (max-width: 560px) { .concept .shell > span { display: none; } }
.concept a:hover { color: #E7E1D8; }

/* ── motion: opacity and 14px, and only once ─────────────────────── */
.rv { opacity: 0; transform: translateY(14px); }
.rv.in { opacity: 1; transform: none; transition: opacity 760ms cubic-bezier(.22,.61,.36,1), transform 760ms cubic-bezier(.22,.61,.36,1); }
.rv-d1.in { transition-delay: 90ms; }
.rv-d2.in { transition-delay: 180ms; }

/* Touch targets. Measured on four handsets: the wordmark came out 17px tall,
   the menu button 33, its close 26 and the film control 30 — all of them under
   the 44px a fingertip needs, and all of them primary controls.

   Scoped to coarse pointers so the desktop typography is left exactly as it is:
   this buys hit area, not size. */
@media (pointer: coarse) {
  .wordmark, .navtoggle, .navclose, .filmctl, .scroll, .btn {
    min-height: 44px; display: inline-flex; align-items: center;
  }
  /* The disclosure bar is .concept here, not .topbar — the first pass at this
     targeted a class this site does not have. Its height feeds --strip, which
     the pinned film sizes against, so raising it keeps everything in step. */
  :root { --strip: 44px; }
  .concept a { min-height: 44px; display: inline-flex; align-items: center; }
  a.meta { min-height: 44px; display: inline-flex; align-items: center; }
  .foot a, .disc a, .stackbtns a { display: inline-flex; align-items: center; min-height: 44px; }
  .foot li + li { margin-top: 2px; }
  /* The film control sits over the picture, so it needs the room on the side
     too, not just above and below. */
  .filmctl { padding: 10px 12px; margin-right: -12px; }
}

.vh { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.skip { position: absolute; left: -9999px; top: 0; z-index: 99; background: var(--ink); color: var(--stone); padding: 12px 18px; font-size: 13px; }
.skip:focus { left: 8px; top: 8px; }
[hidden] { display: none !important; }

/* ═══ narrower viewports: a different rhythm, not the same one stacked ═══ */
@media (max-width: 1080px) {
  .intro-say { grid-column: 1 / -1; }
  .intro-eyebrow { grid-column: 1 / -1; margin-bottom: 20px; }
  .intro-body { grid-column: 1 / span 7; }
  .intro-disc { grid-column: 9 / span 4; }
  .p-wide, .p-tall, .p-mid, .p-inset { grid-column: 1 / -1; }
}
@media (max-width: 820px) {
  :root { --measure: 100%; }
  .grid > *, .pair > * { grid-column: 1 / -1 !important; }
  .navtoggle { display: block; }
  .nav {
    position: fixed; inset: 0; z-index: 50; background: var(--stone); color: var(--ink);
    flex-direction: column; justify-content: center; gap: 6px;
    padding: var(--gut); transform: translateY(-100%);
    transition: transform 520ms cubic-bezier(.4,0,.2,1);
  }
  .nav[data-open="true"] { transform: none; }
  .nav a { font-family: var(--display); font-size: 2rem; font-weight: 300; padding-block: 10px; }
  .nav a::after { display: none; }
  .navclose { display: block; position: absolute; top: var(--gut); right: var(--gut); background: none; border: 0; font-size: 13px; cursor: pointer; }

  .intro-body, .intro-disc { grid-column: 1 / -1; }
  .intro-disc { margin-top: 34px; }
  .steps .row { grid-template-columns: 2.6rem 1fr; gap: 10px 18px; }
  .steps p { grid-column: 2; margin-top: 10px; }
  .form { grid-template-columns: 1fr; }
  .facts > div { padding-right: 0; }
  .foot .cols { grid-template-columns: 1fr; gap: 30px; }
  .foot .c1, .foot .c2, .foot .c3 { grid-column: 1 / -1; }
  .hero-say { max-width: 15ch; }
  .hero-say h1 { font-size: clamp(1.7rem, 7.4vw, 2.3rem); }
  .hero-foot { align-items: flex-end; }
  .scroll i { width: 30px; }
}
@media (max-width: 520px) {
  .band { padding-block: clamp(58px, 15vw, 96px); }
  .seq { gap: 56px; }
  .proj-meta { flex-wrap: wrap; gap: 4px 18px; }
  .filmctl { bottom: calc(clamp(24px, 3.4vw, 44px) + 74px); }
}

@media (prefers-reduced-motion: reduce) {
  .rv { opacity: 1; transform: none; }
  .scroll i { animation: none; transform: scaleX(1); }
  .proj:hover img { transform: none; }
  *, *::before, *::after { transition-duration: .001ms !important; }
}
