/* Combination Technologies, Version 3: shared styles for every page.
   The rules and the HTML for each component are in ../../../DESIGN-SYSTEM.md. Page-only styles go in page-<name>.css.
   Never put overflow: hidden|auto, transform, filter or contain: paint on html, body, main or any element that
   wraps the scroll story: each of these stops the story's stage from pinning. */

/* ---------- 1. Font: one Manrope file serves the site and the story ---------- */
@font-face {
  font-family: "Manrope";
  src: url("/story/fonts/manrope-latin-wght-normal.woff2") format("woff2");
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
}

/* ---------- 2. Tokens ---------- */
:root {
  /* colour (V3-VISION 3.3) */
  --paper: #FFFFFF;
  --ink: #0B0B0B;
  --ink-hover: #2B2B2B;
  --grey: #5C5C5C;
  --hairline: #E3E3E3;
  --panel: #F4F4F4;
  --dark: #0B0B0B;
  --on-dark: #F5F5F5;
  --on-dark-hover: #D9D9D9;
  --grey-on-dark: #A3A3A3;
  --rule-on-dark: #2A2A2A;
  --panel-on-dark: #1C1C1C;

  /* type (3.2): fluid from 390 px to 1440 px wide, clamp(phone, ..., desktop) */
  --font: "Manrope", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --fs-h1: clamp(44px, 27.66px + 4.19vw, 88px);    --lh-h1: clamp(46px, 30.4px + 4vw, 88px);
  --fs-h2: clamp(32px, 24.57px + 1.905vw, 52px);   --lh-h2: clamp(36px, 28.57px + 1.905vw, 56px);
  --fs-h3: clamp(20px, 18.51px + .381vw, 24px);    --lh-h3: clamp(26px, 24.51px + .381vw, 30px);
  --fs-lead: clamp(19px, 17.14px + .476vw, 24px);  --lh-lead: clamp(28px, 25.77px + .571vw, 34px);
  --fs-buyer: clamp(17px, 15.89px + .286vw, 20px); --lh-buyer: clamp(26px, 24.51px + .381vw, 30px);
  --fs-body: clamp(17px, 16.63px + .095vw, 18px);  --lh-body: clamp(27px, 26.26px + .19vw, 29px);
  --fs-small: 15px; --lh-small: 22px;
  --fs-button: 16px;

  /* space: a 4 px base */
  --s-1: 4px; --s-2: 8px; --s-3: 12px; --s-4: 16px; --s-5: 24px; --s-6: 32px;
  --s-7: 48px; --s-8: 64px; --s-9: 96px; --s-10: 128px;

  /* grid (3.4): 12 columns, 1280 px of content at 1440 (80 px margins), 16 px margins at 390 */
  --content: 1280px;
  --margin: clamp(16px, 6.095vw - 7.77px, 80px);
  --gap: 24px;
  --section-y: clamp(72px, 51.2px + 5.333vw, 128px);
  --header-h: 64px;
  --radius: 8px;

  /* motion */
  --dur-fast: 120ms;
  --ease-out: cubic-bezier(.22, .61, .36, 1);
}
@media (max-width: 767.98px) { :root { --header-h: 56px; } }

/* ---------- 3. Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; background: var(--paper); scroll-padding-top: calc(var(--header-h) + 16px); }
body {
  margin: 0; min-width: 320px;
  background: var(--paper); color: var(--ink);
  font-family: var(--font); font-size: var(--fs-body); line-height: var(--lh-body); font-weight: 500;
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
  font-kerning: normal; font-synthesis: none;
}
h1, h2, h3, h4, p, ul, ol, dl, dd, figure, blockquote, table { margin: 0; }
ul, ol { padding: 0; }
img, svg, video, picture { display: block; max-width: 100%; }
img { height: auto; }
a { color: inherit; }
b, strong { font-weight: 700; }
button { font: inherit; color: inherit; }
::selection { background: var(--ink); color: var(--paper); }

h1, .h1 { font-size: var(--fs-h1); line-height: var(--lh-h1); font-weight: 700; letter-spacing: -.035em; text-wrap: balance; }
h2, .h2 { font-size: var(--fs-h2); line-height: var(--lh-h2); font-weight: 600; letter-spacing: -.02em; text-wrap: balance; }
h3, .h3 { font-size: var(--fs-h3); line-height: var(--lh-h3); font-weight: 600; letter-spacing: -.01em; text-wrap: balance; }
.lead { font-size: var(--fs-lead); line-height: var(--lh-lead); font-weight: 500; max-width: 27em; text-wrap: pretty; }   /* about 54 characters a line */
.buyer { font-size: var(--fs-buyer); line-height: var(--lh-buyer); font-weight: 500; color: var(--grey); max-width: 30em; text-wrap: pretty; } /* about 60 */
.body, .prose p, .prose li { max-width: 34em; text-wrap: pretty; }   /* about 68 characters a line */
.label { font-size: var(--fs-small); line-height: var(--lh-small); font-weight: 600; }
.small { font-size: var(--fs-small); line-height: var(--lh-small); font-weight: 500; color: var(--grey); }
.grey { color: var(--grey); }
.num { font-variant-numeric: tabular-nums; }

.sr-only { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
.print-only { display: none; }

/* ---------- 4. Layout: container, grid, column widths, sections ---------- */
.container { width: min(100% - 2 * var(--margin), var(--content)); margin-inline: auto; }
.grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap); }
/* width of N columns of the container, for blocks that are not in a .grid */
.w-7  { max-width: calc((100% + var(--gap)) * 7 / 12 - var(--gap)); }
.w-8  { max-width: calc((100% + var(--gap)) * 8 / 12 - var(--gap)); }
.w-10 { max-width: calc((100% + var(--gap)) * 10 / 12 - var(--gap)); }
@media (max-width: 899.98px) { .w-7, .w-8, .w-10 { max-width: none; } }
.section { padding-block: var(--section-y); }
.section + .section { padding-top: 0; }          /* two Paper sections in a row share one gap */

/* ---------- 5. Skip link and focus ---------- */
.skip {
  position: absolute; z-index: 200; left: var(--margin); top: -200px;
  display: inline-flex; align-items: center; min-height: 48px; padding: 0 18px;
  background: var(--ink); color: var(--paper); border-radius: var(--radius);
  font-size: var(--fs-button); font-weight: 600; text-decoration: none;
}
.skip:focus { top: 8px; }
:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.on-dark :focus-visible { outline-color: var(--on-dark); }
main:focus { outline: none; }   /* the skip link's target: a landmark, not a control */

/* ---------- 6. Buttons and text links ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  min-height: 48px; min-width: 48px; padding: 0 22px;
  border: 1.5px solid transparent; border-radius: var(--radius);
  font-family: var(--font); font-size: var(--fs-button); line-height: 1; font-weight: 600; letter-spacing: 0;
  text-decoration: none; white-space: nowrap; cursor: pointer;
  transition: background-color var(--dur-fast) linear, color var(--dur-fast) linear, border-color var(--dur-fast) linear;
}
.btn--primary { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.btn--secondary { background: transparent; color: var(--ink); border-color: var(--ink); }
.on-dark .btn--primary { background: var(--on-dark); color: var(--ink); border-color: var(--on-dark); }
.on-dark .btn--secondary { color: var(--on-dark); border-color: var(--on-dark); }
.btn[hidden] { display: none; }   /* .btn's inline-flex would otherwise beat the hidden attribute (the video button without scripts) */
.btn--block { display: flex; width: 100%; }
.btn-row { display: flex; flex-wrap: wrap; gap: var(--s-3); }

.link {
  color: inherit; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 4px;
  transition: text-decoration-thickness var(--dur-fast) linear;
}

/* Hover states only where there is a real pointer: on a touch phone a tapped button would otherwise stay filled. */
@media (hover: hover) {
  .btn--primary:hover { background: var(--ink-hover); border-color: var(--ink-hover); }
  .btn--secondary:hover { background: var(--panel); }
  .on-dark .btn--primary:hover { background: var(--on-dark-hover); border-color: var(--on-dark-hover); }
  .on-dark .btn--secondary:hover { background: var(--panel-on-dark); }
  .link:hover { text-decoration-thickness: 2px; }
  .nav a:hover { text-decoration-line: underline; }
  .site-footer a:hover { text-decoration-color: var(--on-dark); text-decoration-thickness: 2px; }
}

/* ---------- 7. Header (sticky, never hides, never shrinks) ---------- */
.site-header {
  position: sticky; top: 0; z-index: 50; height: var(--header-h);
  background: var(--paper); color: var(--ink); border-bottom: 1px solid var(--hairline);
  view-transition-name: site-header;
}
.site-header__in { height: 100%; display: flex; align-items: center; gap: var(--s-6); }
.logo { display: inline-flex; align-items: center; flex: none; margin-right: auto; min-height: 48px; }
.logo img { height: 22px; width: auto; }
@media (min-width: 900px) { .logo img { height: 26px; } }
.nav ul { list-style: none; display: flex; gap: var(--s-6); }
.nav a {
  display: inline-flex; align-items: center; min-height: 48px;
  font-size: var(--fs-button); font-weight: 600; text-decoration: none;
  text-decoration-thickness: 1px; text-underline-offset: 6px;
}
.nav a[aria-current='page'] { text-decoration-line: underline; text-decoration-thickness: 2px; }
.btn--header { min-height: 40px; padding: 0 18px; }    /* the one smaller button: desktop header only */
@media (hover: none) { .btn--header { min-height: 48px; } }   /* touch tablets from 768 px: a full 48 px target */
.menu-btn {
  display: none; align-items: center; justify-content: center; min-width: 48px; min-height: 48px;
  margin-right: -10px; padding: 0 10px; background: none; border: 0; border-radius: var(--radius);
  font-size: var(--fs-button); font-weight: 600; line-height: 1; text-decoration: none; cursor: pointer;
}
@media (max-width: 767.98px) {
  .nav, .btn--header { display: none; }
  .menu-btn { display: inline-flex; }
}
html:not(.js) .menu-btn--js, html.js .menu-btn--nojs { display: none !important; }

/* phone menu: a full-screen native <dialog> (focus stays inside, Escape closes it) */
.menu {
  position: fixed; inset: 0; width: 100%; max-width: none; height: 100%; max-height: none;
  margin: 0; padding: 0; border: 0; background: var(--paper); color: var(--ink); overflow-y: auto;
}
.menu::backdrop { background: transparent; }
.menu__top { border-bottom: 1px solid var(--hairline); }   /* the same full-width rule as the header */
.menu__bar { height: calc(var(--header-h) - 1px); display: flex; align-items: center; justify-content: space-between; }
.menu__top .menu-btn { display: inline-flex; }
.menu__nav { display: flex; flex-direction: column; padding-top: var(--s-4); }
.menu__nav a {
  display: flex; align-items: center; min-height: 64px; border-bottom: 1px solid var(--hairline);
  font-size: 28px; line-height: 1.1; font-weight: 600; letter-spacing: -.02em; text-decoration: none;
  text-underline-offset: 6px;
}
.menu__nav a[aria-current='page'] { text-decoration: underline; text-decoration-thickness: 2px; }
.menu__cta { padding-block: var(--s-6) var(--s-7); }
@media (prefers-reduced-motion: no-preference) {
  .menu { opacity: 0; transition: opacity 160ms linear, overlay 160ms allow-discrete, display 160ms allow-discrete; }
  .menu[open] { opacity: 1; }
  @starting-style { .menu[open] { opacity: 0; } }
}

/* ---------- 8. Section header: rule, label, 24 px, H2 ---------- */
.sh { border-top: 1px solid var(--hairline); padding-top: 20px; }
.sh__label { font-size: var(--fs-small); line-height: var(--lh-small); font-weight: 600; color: var(--ink); margin-bottom: var(--s-5); }
.on-dark .sh { border-top-color: var(--rule-on-dark); }
.on-dark .sh__label { color: var(--on-dark); }
.sh--plain { padding-top: var(--s-6); }   /* a rule and the H2, no label (Projects groups, Contact's "What happens next") */

/* ---------- 9. Rows: name or thumbnail in columns 1-4, text in 5-12 ---------- */
.rows { list-style: none; border-bottom: 1px solid var(--hairline); }
/* A list that ends its section closes with the section's own white space, not a rule: otherwise its last rule and the
   next section header's rule read as a double line. A list followed by a line of text (About's ways) keeps it. */
.rows:last-child { border-bottom: 0; }
.row { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap); padding-block: var(--s-6); border-top: 1px solid var(--hairline); }
.row__name { grid-column: 1 / span 4; }
.row__text { grid-column: 5 / -1; max-width: 34em; }
.row--compact .row__name { grid-column: 1 / span 3; }   /* Projects compact entries: thumbnail 1-3, text 4-12 (4.2) */
.row--compact .row__text { grid-column: 4 / -1; }
@media (max-width: 699.98px) {
  .row { display: block; }
  .row__name { margin-bottom: var(--s-2); }
  .row--compact .row__name { margin-bottom: var(--s-4); }
}

/* Panel: a slim full-width block on Panel grey (the withheld project) */
.panel { background: var(--panel); padding: var(--s-6); }
/* Field labels inside an entry ("What it is", "The job", "What we did"), and the Result line */
.field { font-size: var(--fs-small); line-height: var(--lh-small); font-weight: 600; color: var(--grey); margin-bottom: var(--s-1); }
.result b { font-weight: 600; }

/* ---------- 10. Table: real <table>, header row on Panel, stacks on phones ---------- */
/* The text of both columns sits on the content edge, like the H2 and lead above it. The Panel header and the row
   rules hang 24 px past the text on both sides (the table is 48 px wider than the content, pulled 24 px left), so the
   header's text keeps its inset inside the fill. */
.table {
  width: calc(100% + 2 * var(--s-5)); margin-inline: calc(-1 * var(--s-5));
  border-collapse: collapse; table-layout: fixed; font-size: var(--fs-body); line-height: var(--lh-body); font-variant-numeric: tabular-nums;
}
.table col.table__first { width: 34.6%; }   /* column 2 starts on grid column 5 (to within a pixel at 1440, 8 px at 700) */
.table th, .table td { text-align: left; vertical-align: top; padding: var(--s-5) var(--s-5) var(--s-5) 0; border-bottom: 1px solid var(--hairline); }
.table tr > :first-child { padding-left: var(--s-5); }
.table thead th { background: var(--panel); padding-block: 13px; border-bottom: 0; font-size: var(--fs-small); line-height: var(--lh-small); font-weight: 600; }
.table tbody th { font-weight: 600; }
/* max-width does nothing on a cell of a fixed-layout table, so the text is held in a block inside it:
   at most 68 characters a line, and no one-word last line ("build.") */
.table td .cell { display: block; max-width: 34em; text-wrap: pretty; }
@media (max-width: 699.98px) {
  .table { width: 100%; margin-inline: 0; }
  .table, .table tbody, .table tr, .table th, .table td { display: block; }
  .table colgroup { display: none; }
  .table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .table tbody tr { padding-block: 20px; border-bottom: 1px solid var(--hairline); }
  .table tbody tr:first-child { border-top: 1px solid var(--hairline); }
  .table tbody tr > :first-child, .table tbody tr > :last-child { padding: 0; border: 0; }
  .table tbody th { margin-bottom: var(--s-1); }
}

/* ---------- 11. Image frames: 4:3 with a hairline; photos cover, renders and CAD sit on a Panel plate ---------- */
.frame { position: relative; aspect-ratio: 4 / 3; border: 1px solid var(--hairline); background: var(--paper); overflow: hidden; }
.frame > picture { width: 100%; height: 100%; }
.frame img, .frame video { width: 100%; height: 100%; object-fit: cover; }
/* A render or CAD on white sits on a deliberate Panel plate: multiply turns the file's white into the plate, so its
   edges never show as a white box. --plate fills the frame (Home card); --contain shows the whole render (the render
   files are trimmed, with an even margin of 6% baked in, so 2% of padding is enough). */
.frame--plate, .frame--contain { background: var(--panel); isolation: isolate; }
.frame--plate img, .frame--contain img { mix-blend-mode: multiply; }
.frame--contain img { object-fit: contain; padding: 2%; }
.frame--wide { aspect-ratio: 16 / 9; }
.frame--portrait { aspect-ratio: 4 / 5; }
.frame--portrait img { filter: grayscale(1); }
.credit { margin-top: var(--s-3); font-size: var(--fs-small); line-height: var(--lh-small); font-weight: 500; color: var(--grey); }

/* ---------- 12. Closing band and footer (Dark) ---------- */
.on-dark { background: var(--dark); color: var(--on-dark); }
.closing { padding-block: var(--section-y); }
.closing h2 { max-width: 14em; }
.closing__lead { margin-top: var(--s-5); color: var(--grey-on-dark); text-wrap: balance; }   /* two even lines, not "email us." alone */
.closing .btn-row { margin-top: var(--s-7); }

.site-footer { padding-bottom: var(--s-7); overflow-wrap: anywhere; }
/* The Rule-on-dark line is the seam between the closing band and the footer. On Contact and the 404 there is no band
   (main ends on Paper), so the line would sit on the paper/dark edge as a stray grey line: it is drawn only when
   main ends with the closing band. The markup of the footer is the same on every page. */
.site-footer > .container { border-top: 1px solid transparent; padding-top: var(--s-8); }
body:has(main > .closing:last-child) .site-footer > .container { border-top-color: var(--rule-on-dark); }
/* Where the closing band already offers "Book a call" right above, the footer keeps only the email (critique, 14 Nov) */
body:has(main > .closing:last-child) .footer__book { display: none; }
.nowrap { white-space: nowrap; }
.phrase { display: inline-block; }   /* a headline sentence that should wrap as a whole, before it wraps inside */
.arrow { display: inline-block; margin-left: .25em; text-decoration: none; }   /* → and ↗ after a link's words, never underlined */
.footer__cols { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap); row-gap: var(--s-6); }
.footer__cols > :nth-child(1) { grid-column: span 3; }
.footer__cols > :nth-child(2) { grid-column: span 4; }
.footer__cols > :nth-child(3) { grid-column: span 2; }
.footer__cols > :nth-child(4) { grid-column: span 3; }
.footer__cols p + p { margin-top: var(--s-2); }
.footer__co { font-weight: 600; }
.footer__muted { color: var(--grey-on-dark); }
.footer__cols ul { list-style: none; display: grid; gap: var(--s-2); }
.site-footer a { color: var(--on-dark); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 4px; text-decoration-color: rgba(245, 245, 245, .45); transition: text-decoration-color var(--dur-fast) linear, text-decoration-thickness var(--dur-fast) linear; }
.footer__bottom { margin-top: var(--s-8); padding-top: var(--s-5); border-top: 1px solid var(--rule-on-dark); display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap); row-gap: var(--s-2); font-size: var(--fs-small); line-height: var(--lh-small); color: var(--grey-on-dark); }
.footer__bottom p { text-wrap: pretty; }   /* no "reserved." alone on a line */
.footer__bottom > :nth-child(1) { grid-column: span 3; }
.footer__bottom > :nth-child(2) { grid-column: span 4; }
.footer__bottom > :nth-child(3) { grid-column: span 5; }
@media (max-width: 1099.98px) {
  .footer__cols > :nth-child(n), .footer__bottom > :nth-child(n) { grid-column: span 6; }
  .footer__bottom > :nth-child(2) { grid-column: span 12; order: 3; }
}
@media (max-width: 599.98px) {
  .footer__cols > :nth-child(n), .footer__bottom > :nth-child(n) { grid-column: 1 / -1; }
  .footer__bottom > :nth-child(2) { order: 0; }
  .footer__cols { row-gap: var(--s-5); }
  .footer__cols a { display: inline-block; padding-block: 10px; }   /* 48 px tall targets on phones */
  .footer__cols p + p { margin-top: 0; }
  .footer__cols > div:first-child p + p { margin-top: var(--s-1); }
  .footer__cols ul { gap: 0; }
}

/* ---------- 13. Restrained motion (Claude's review): off with reduced motion; nothing is hidden unless site.js runs ---------- */
@media (prefers-reduced-motion: no-preference) {
  .rv { opacity: 0; transform: translateY(12px); }
  .rv.rv-in { opacity: 1; transform: none; transition: opacity 500ms var(--ease-out) var(--rv-d, 0ms), transform 500ms var(--ease-out) var(--rv-d, 0ms); }
  /* an element reached by its anchor (/work#slug, /about#team, /contact#book) fades in without the 12 px rise, so it
     lands exactly under the header (scroll-padding-top above) */
  .rv:target { transform: none; }
  /* project and card images: 1.02 on hover */
  .zoom img { transition: transform 400ms var(--ease-out); }
}
@media (prefers-reduced-motion: no-preference) and (hover: hover) {
  a:hover .zoom img { transform: scale(1.02); }
}
/* page cross-fade between pages of the site */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
  ::view-transition-old(root), ::view-transition-new(root) { animation-duration: 220ms; animation-timing-function: linear; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0ms !important; animation-duration: 0ms !important; }
}

/* ---------- 14. Print: a clean document, no dark bands, no controls ---------- */
@media print {
  @page { margin: 16mm 14mm; }
  :root { --section-y: 18pt; --margin: 0px; }
  html, body { background: #fff !important; color: #000 !important; font-size: 10.5pt; line-height: 1.45; }
  .container { width: 100%; }
  .site-header { position: static; height: auto; padding: 0 0 10pt; border: 0; }
  .site-header .nav, .site-header .btn, .menu-btn, .menu, .skip, .closing, .site-footer .footer__cols, .site-footer .footer__bottom, .btn-row, .no-print { display: none !important; }
  .print-only { display: block !important; }
  .site-footer { background: #fff !important; color: #000 !important; padding: 0; font-size: 9pt; }
  .site-footer > .container { border-top: 1px solid #999 !important; padding-top: 8pt; }   /* over the screen-only :has() seam rule */
  .on-dark { background: #fff !important; color: #000 !important; }
  .rv { opacity: 1 !important; transform: none !important; }
  h1, h2, h3 { break-after: avoid; color: #000; }
  .frame, .row, .table tr, figure { break-inside: avoid; }
  a { text-decoration: none; }
  .sh { border-top-color: #999; }
}
