/* ============================================================
   Sillage - sensory identity consultancy
   Hand-written CSS. No framework, no build step, no dependency.
   ------------------------------------------------------------
   v7 "Ambience". Built to Website Build Specification v1.0.
   THIS COMMENT IS THE STATEMENT OF THE RULES. Keep it true.

   COLOUR. The :root block below is the single source of truth.
   Do not introduce a colour that is not in it (spec 2.1).

   --clay is #A85526, NOT the #B4602C the specification names.
   Measured, #B4602C on ivory is 4.26:1, below the 4.5:1 AA
   threshold for normal text, so the spec's own claim of "roughly
   4.6:1 and passes AA" does not hold. #A85526 measures 4.96:1 on
   ivory and 5.26:1 on white and is a barely perceptible shift.
   That single change carries the header phonetic, the venue
   arrows and the form error text. (Supersedes spec 2.1.)

   Measured on what actually ships:
     clay #A85526 on ivory ............ 4.96  pass
     clay #A85526 on white ............ 5.26  pass
     clay #A85526 on ivory-2 .......... 4.62  pass
     clay #A85526 on mineral .......... 4.21  FAIL, so never do it
     forest on ivory .................. 12.70 pass
     forest-mid on ivory .............. 7.73  pass
     forest-mid on mineral ............ 6.56  pass
     forest-soft #6E8579 on ivory ..... 3.74  FAIL, fill only
     clay-bright on forest ............ 5.84  pass
     clay-bright on ivory ............. 2.17  FAIL, fill only
     sage on ivory .................... 2.83  FAIL, fill only
     ivory 55% on forest .............. 4.97  pass  (was 50% = 4.38)
     charcoal 78% on white ............ 7.03  pass
     charcoal 72% on mineral .......... 5.15  pass  (was 65% = 4.22)
     charcoal 72% on ivory ............ 5.62  pass  (was 62% = 4.15)

   NEVER put --clay or --forest-soft on a mineral panel as text.
   NEVER use --clay-bright, --sage or --plum as text on a light
   ground; they are fills. --clay-bright appears as TEXT in exactly
   two places sitewide, both on forest: the footer slogan and the
   word "agreement" in the interplay statement.

   PROPORTION: ivory ~60%, forest ~25%, mineral or sage ~10%,
   clay ~5%. Orange appears on the phonetic, the footer slogan,
   the venue arrows and inside the blueprint drawings. Nowhere else.

   NEVER pure white or pure black as a type colour. --white is a
   legitimate BACKGROUND for the header and cards only.

   PHONETIC. The lockup reads "SEE-YAZH", set by the owner on
   2026-07-31. It SUPERSEDES the spelling given in sections 3.1, 3.2
   and 11.6 of the specification: same hyphen, different vowels, so
   that it matches the brand domain. It is still a permanent part of the
   wordmark lockup in the header AND the footer; do not remove it, and
   do not let the two copies drift apart.

   TYPE. Eyebrows are sans, uppercase: --body 12.5px, weight 600,
   letter-spacing .04em, opacity .75, colour --forest. This
   SUPERSEDES the v4 decision recorded in the private working notes,
   which made them mono and Title Case. Headings are sentence case
   with a full stop where they are statements. Never title-case one.

   COPY. No em dashes. No en dashes. No exclamation marks.
   Citations in full: author, year, journal, volume. Never
   "studies show". (spec 2.3)

   LAYOUT. Content max width 1120px, centred; section backgrounds
   are full bleed and the content inside them is capped. Section
   padding 46px horizontal desktop, 26px below 900px; 56px top and
   bottom. Radius 3px buttons, 5px cards, 2px images. No pills.
   No drop shadows on type. (spec 2.4)

   RESPONSIVE. ONE breakpoint, 900px. The header wraps and all
   three nav items stay visible. There is no hamburger and no
   #nav-toggle; both were deleted in v7. (spec 2.5)

   MOTION CONTRACT, unchanged since v4: elements opt in with
   data-animate plus optional data-anim-delay; motion.js only adds
   .in; every hiding rule is scoped under .js-motion so JS off
   means nothing is hidden; prefers-reduced-motion pins the final
   state; only transform and opacity animate.
   ============================================================ */

:root {
  /* ---- PALETTE (spec 2.1, with the --clay correction above) ---- */
  --forest:       #1E3328;  /* primary. Dark sections, headings, buttons  */
  --forest-mid:   #3A5544;  /* secondary text on light grounds, citations */
  --forest-soft:  #6E8579;  /* FILL ONLY. Fails AA as text on ivory       */
  --clay:         #A85526;  /* text-safe accent. Links, phonetic, arrows  */
  --clay-bright:  #EE9560;  /* FILL ONLY, except two places on forest     */
  --sage:         #6CA085;  /* chart fills, positive data                 */
  --mineral:      #DBE9E6;  /* evidence ground. Expander panels only      */
  --plum:         #7A5A72;  /* chart series, medium-importance markers    */
  --ivory:        #FBF8F1;  /* default page background                    */
  --ivory-2:      #F4F0E6;  /* active nav state                           */
  --white:        #FFFFFF;  /* header and card BACKGROUND only            */
  --charcoal:     #2A2A28;  /* body ink                                   */
  --rule:         rgba(30, 51, 40, .14);  /* all hairline borders         */

  /* Ratings on venue pages. Colour is carried by a swatch; the word
     High / Medium / Low is always present as text in --forest. */
  --rate-high:    #A8492F;
  --rate-medium:  var(--plum);
  --rate-low:     var(--sage);

  /* Blueprint drawing inks. Line work only, never type on a page. */
  --bp-line:      #5E8B93;
  --bp-ground:    #FCFAF4;

  /* ---- TYPE (spec 2.2) ----
     'New York' and 'SF Pro Text' resolve natively on Apple devices,
     where Apple's licence covers them. They are NOT self-hosted:
     that licence does not grant redistribution as a webfont served
     to arbitrary browsers, and doing it would put a licence
     violation on a client-facing site. (Supersedes spec 2.2.)

     The self-hosted display face is Source Serif 4 (SIL OFL), which
     is licensed for this. The binaries are not in the repo yet, so
     the stack currently falls through to Georgia, an upright serif
     present on Windows, macOS and Android. When the woff2 files
     land, drop them in assets/fonts/ and uncomment the block below.
     No Google Fonts: spec 9.2 forbids third-party font requests. */
  --display: 'New York', 'Source Serif 4', ui-serif, 'Iowan Old Style',
             Palatino, Georgia, serif;
  --body:    -apple-system, BlinkMacSystemFont, 'SF Pro Text',
             'Helvetica Neue', Helvetica, Arial, sans-serif;
  --mono:    ui-monospace, 'SF Mono', SFMono-Regular, Menlo,
             Consolas, monospace;

  /* ---- RHYTHM (spec 2.4) ---- */
  --maxw:  1120px;
  --pad-x: 46px;
  --pad-y: 56px;
  --r-btn:  3px;
  --r-card: 5px;
  --r-img:  2px;
}

/* Self-hosted display face. Activate when the OFL binaries exist.
@font-face {
  font-family: 'Source Serif 4';
  src: url('assets/fonts/SourceSerif4-Regular.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Source Serif 4';
  src: url('assets/fonts/SourceSerif4-Semibold.woff2') format('woff2');
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Source Serif 4';
  src: url('assets/fonts/SourceSerif4-It.woff2') format('woff2');
  font-weight: 400; font-style: italic; font-display: swap;
}
*/

/* ============================================================
   RESET AND BASE
   ============================================================ */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--ivory);
  color: var(--charcoal);
  font-family: var(--body);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img, svg { max-width: 100%; display: block; }
a { color: inherit; }
p { margin: 0 0 14px; }
ul { margin: 0; }
figure { margin: 0; }

h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 600;
  letter-spacing: -.015em;
  line-height: 1.12;
  margin: 0;
  color: var(--forest);
}

/* Section eyebrow. v7: sans, uppercase. Supersedes the v4 mono Title
   Case rule in the private working notes. Applies to every equivalent
   label sitewide. */
.eyebrow {
  font-family: var(--body);
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  opacity: .75;
  color: var(--forest);
  margin: 0 0 12px;
}
.eyebrow.on-dark { color: rgba(251, 248, 241, .96); opacity: .75; }

.skip-link {
  position: absolute; left: -999px; top: 0; z-index: 100;
  background: var(--forest); color: var(--ivory);
  padding: 10px 16px; border-radius: 0 0 var(--r-btn) 0;
}
.skip-link:focus { left: 0; }

/* Visible focus on every interactive element. Never removed without
   a replacement. (spec 9.3) */
a:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, textarea:focus-visible, [tabindex]:focus-visible {
  outline: 3px solid var(--clay);
  outline-offset: 3px;
  border-radius: 2px;
}
.on-forest :focus-visible,
.hero :focus-visible, .inter :focus-visible, .foot :focus-visible,
.vhero :focus-visible {
  outline-color: var(--clay-bright);
}

/* ============================================================
   LAYOUT SHELL
   Section backgrounds are full bleed; the content inside them is
   capped at 1120px and centred. (spec 2.4)
   ============================================================ */
.sec { padding: var(--pad-y) var(--pad-x); }
.wrap { max-width: var(--maxw); margin-inline: auto; }

/* ============================================================
   HEADER (spec 3.1)
   ============================================================ */
.hdr {
  background: var(--white);
  border-bottom: 1px solid var(--rule);
  padding: 18px var(--pad-x);
}
.hdr__inner {
  max-width: var(--maxw); margin-inline: auto;
  display: flex; align-items: center; justify-content: space-between;
  gap: 18px; flex-wrap: wrap;
}
.wordmark {
  font-family: var(--display); font-size: 25px; line-height: 1.05;
  color: var(--forest); text-decoration: none;
}
/* The phonetic is a permanent part of the lockup, header and footer.
   Do not remove it. The old slogan does NOT belong here; it lives in
   the footer. (spec 3.1) */
.wordmark .phon {
  display: block; margin-top: 4px;
  font-family: var(--mono); font-size: 9.5px;
  letter-spacing: .22em; color: var(--clay);
}
.hdr nav { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.navbtn {
  font-family: var(--body); font-size: 13.5px; color: var(--forest);
  text-decoration: none; padding: 9px 20px;
  border: 1px solid var(--rule); border-radius: var(--r-btn);
  background: transparent; white-space: nowrap;
}
.navbtn:hover { border-color: rgba(30, 51, 40, .4); }
.navbtn[aria-current="page"] {
  background: var(--ivory-2); border-color: rgba(30, 51, 40, .28);
}
.bookbtn {
  background: var(--forest); color: var(--ivory); text-decoration: none;
  font-family: var(--body); font-size: 13.5px; font-weight: 600;
  padding: 11px 22px; border-radius: var(--r-btn);
  border: 1px solid var(--forest); white-space: nowrap;
}
.bookbtn:hover { background: #16261D; }

/* ============================================================
   BUTTONS
   ============================================================ */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--body); font-weight: 600; font-size: 14.5px;
  text-decoration: none; cursor: pointer;
  padding: 14px 26px; border-radius: var(--r-btn);
  border: 1px solid transparent;
}
.btn--solid { background: var(--forest); color: var(--ivory); border-color: var(--forest); }
.btn--solid:hover { background: #16261D; }
/* On a forest ground the primary inverts. */
.on-forest .btn--solid { background: var(--ivory); color: var(--forest); border-color: var(--ivory); }
.on-forest .btn--solid:hover { background: var(--white); }
.btn--ghost {
  background: transparent; color: var(--ivory);
  border: 1.5px solid rgba(251, 248, 241, .55); padding: 13px 26px;
}
.btn--ghost:hover { border-color: rgba(251, 248, 241, .9); background: rgba(251, 248, 241, .08); }

/* ============================================================
   HERO (spec 4.1)
   ============================================================ */
.hero { background: var(--forest); }
.hero__inner {
  max-width: var(--maxw); margin-inline: auto;
  display: grid; grid-template-columns: 1.02fr .98fr;
  min-height: 430px;
}
.hero__inner > * { min-width: 0; }
.hero .txt {
  padding: 74px 0 66px var(--pad-x);
  display: flex; flex-direction: column; justify-content: center;
}
.hero h1 {
  font-size: 56px; line-height: 1.04; color: var(--ivory); max-width: 11ch;
}
.hero .sub {
  font-family: var(--display); font-style: italic; font-size: 19px;
  color: rgba(251, 248, 241, .82); margin: 20px 0 0; max-width: 32ch;
}
.btnrow { display: flex; gap: 12px; margin-top: 30px; flex-wrap: wrap; }

/* Hero photograph.
   OWNER OVERRIDE of spec 4.1, 2026-08-01. The spec asked for
   filter: saturate(.55) sepia(.14) contrast(1.02) plus a gradient
   running to 70% of the width. Together those did more than pull the
   image toward the palette: they drained it, and roughly the left third
   of the photograph disappeared into flat green. The picture is the only
   thing in the hero carrying any warmth, so it now keeps its colour.

   What is kept is the PURPOSE of both: the image still feathers into the
   green so there is no hard seam where the two columns meet, and it still
   sits in the brand's register. But the feather is now a soft EDGE, about
   a third of the image at most, instead of a curtain over half of it.
   Past 34% the photograph is completely clean. */
.hero .imgside { position: relative; overflow: hidden; }
.hero .imgside img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  filter: saturate(.95) contrast(1.05) brightness(1.02);
}
.hero .imgside::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(90deg,
    rgba(30, 51, 40, .88) 0%,
    rgba(30, 51, 40, .46) 7%,
    rgba(30, 51, 40, .14) 19%,
    rgba(30, 51, 40, 0) 34%);
}
.hero .capt {
  position: absolute; bottom: 16px; right: 18px; z-index: 2;
  font-family: var(--mono); font-size: 8.5px; letter-spacing: .16em;
  color: rgba(251, 248, 241, .55);
}

/* ============================================================
   AMBIENCE ROWS (spec 4.2)
   ============================================================ */
.amb { background: var(--ivory); padding: var(--pad-y) var(--pad-x) 30px; }
.amb h2 { font-size: 32px; }
.amb .stand {
  max-width: 64ch; font-size: 15.5px; color: rgba(42, 42, 40, .8);
  margin-top: 10px;
}

.row3 {
  background: var(--white); border: 1px solid var(--rule);
  border-radius: var(--r-card); margin-top: 22px; overflow: hidden;
}
.rowhead {
  display: grid; grid-template-columns: 190px 1fr auto;
  gap: 26px; align-items: center; padding: 26px 28px;
}
.rowhead > * { min-width: 0; }
.rowhead .nm { font-family: var(--display); font-size: 26px; color: var(--forest); }
.rowimg {
  width: 158px; height: 110px; object-fit: cover; display: block;
  margin-top: 12px; border: 1px solid var(--rule); border-radius: var(--r-img);
}
/* The Music slot carried a blueprint drawing for part of a day. It now
   holds a real photograph like the other two rows, so .rowimg covers it
   and the drawing rule is gone rather than left behind. */
.rowhead .what {
  font-size: 14px; color: rgba(42, 42, 40, .78); max-width: 56ch; margin: 0;
}

/* Expander toggle. A real button, square corners, mineral when open. */
.see {
  font-family: var(--body); font-size: 12px; font-weight: 600;
  letter-spacing: .03em; color: var(--forest);
  background: transparent; border: 1px solid rgba(30, 51, 40, .35);
  border-radius: 0; padding: 9px 16px; white-space: nowrap; cursor: pointer;
}
.see[aria-expanded="true"] { background: var(--mineral); }
.see .sign { display: inline-block; margin-left: 6px; }

/* Expander panel. Present in the DOM whether open or closed, so it is
   readable by search engines and screen readers. Collapsed with
   max-height, never with display:none injected after load. The whole
   collapse is scoped under .js: with JavaScript off every panel is
   simply open. (spec 4.2) */
.expander {
  background: var(--mineral); border-top: 1px solid var(--rule);
  padding: 26px 28px;
  display: grid; grid-template-columns: 1.1fr .9fr; gap: 34px;
}
.expander > * { min-width: 0; }
.js .exp {
  max-height: 0; overflow: hidden; visibility: hidden;
  transition: max-height 250ms ease, visibility 0s linear 250ms;
}
.js .exp.is-open {
  visibility: visible;
  transition: max-height 250ms ease, visibility 0s linear 0s;
}
@media (prefers-reduced-motion: reduce) {
  .js .exp, .js .exp.is-open { transition: none; }
}
.expander h4 { font-size: 16px; }
.expander .src {
  font-family: var(--mono); font-size: 9.5px; color: var(--forest-mid);
  margin-top: 12px; line-height: 1.6;
}
.exnote { font-size: 12.5px; color: rgba(42, 42, 40, .72); line-height: 1.6; margin: 0; }
.exnote + .exnote { margin-top: 10px; }

/* Diverging scent ladder, zero at centre. */
.bars { margin-top: 14px; }
.bar {
  display: grid; grid-template-columns: 128px 1fr 52px;
  align-items: center; gap: 10px; margin-bottom: 8px;
}
.bar > * { min-width: 0; }
/* forest-mid on mineral is 6.56:1. The mockup's rgba(42,42,40,.65)
   measured 4.22:1 on this ground and failed. */
.bar .bl { font-family: var(--mono); font-size: 9.5px; color: var(--forest-mid); line-height: 1.35; }
.bar .track { height: 15px; background: rgba(30, 51, 40, .09); border-radius: var(--r-img); position: relative; overflow: hidden; }
.bar .fill { position: absolute; top: 0; bottom: 0; border-radius: var(--r-img); }
.bar .val { font-family: var(--display); font-size: 14px; color: var(--forest); text-align: right; }

/* Music: congruent versus incongruent pair. */
.duo { display: flex; gap: 10px; margin-top: 14px; flex-wrap: wrap; }
.duo > div { flex: 1 1 180px; min-width: 0; border-radius: var(--r-btn); padding: 12px 13px; }
.duo .yes { background: rgba(108, 160, 133, .28); border: 1px solid rgba(30, 51, 40, .2); }
.duo .no  { background: rgba(30, 51, 40, .06); border: 1px solid rgba(30, 51, 40, .2); }
.duo b { display: block; font-size: 12.5px; margin-bottom: 4px; color: var(--forest); }
.duo p { margin: 0; font-size: 12px; line-height: 1.55; color: rgba(42, 42, 40, .78); }

/* Climate: TWO bars. Never add a third for a hot condition; the study
   ran two and neither was uncomfortable. (spec 11.2) */
.cbars { margin-top: 14px; }
.cbar { display: grid; grid-template-columns: 128px 1fr 64px; align-items: center; gap: 10px; margin-bottom: 10px; }
.cbar > * { min-width: 0; }
.cbar .cl { font-family: var(--mono); font-size: 9.5px; color: var(--forest-mid); line-height: 1.4; }
.cbar .cl b { display: block; font-weight: 600; }
.cbar .track { height: 20px; background: rgba(30, 51, 40, .09); border-radius: var(--r-img); position: relative; overflow: hidden; }
.cbar .fill { position: absolute; top: 0; bottom: 0; left: 0; border-radius: var(--r-img); }
.cbar .cv { font-family: var(--display); font-size: 14px; color: var(--forest); text-align: right; }
.caveat { font-size: 11.5px; color: rgba(42, 42, 40, .72); line-height: 1.6; margin-top: 12px; }

/* ============================================================
   INTERPLAY BAND (spec 4.3)
   ============================================================ */
.inter { background: var(--forest); padding: 50px var(--pad-x); }
.inter .q {
  font-family: var(--display); font-size: 24px; line-height: 1.35;
  color: var(--ivory); max-width: 52ch;
}
/* One of exactly two places --clay-bright is text, and it is on forest. */
.inter .q em { color: var(--clay-bright); font-style: italic; }
.inter .cite {
  font-family: var(--mono); font-size: 10px; letter-spacing: .08em;
  color: rgba(251, 248, 241, .6); margin-top: 16px; line-height: 1.7;
}
.inter .btn { margin-top: 24px; }

/* ============================================================
   VENUES (spec 4.4)
   ============================================================ */
.ven { background: var(--ivory); padding: var(--pad-y) var(--pad-x); }
.ven h2 { font-size: 32px; }
.ven .stand { font-size: 15px; color: rgba(42, 42, 40, .78); max-width: 62ch; margin-top: 10px; }
.vgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; margin-top: 30px; }
.vgrid > * { min-width: 0; }
.vcard {
  background: var(--white); border: 1px solid var(--rule);
  border-radius: var(--r-card); overflow: hidden;
  display: flex; flex-direction: column;
}
/* The whole card is the hit area and the visible link carries the same
   href. Hover darkens the border only: no lift, no shadow animation. */
a.vcard { text-decoration: none; color: inherit; }
a.vcard:hover { border-color: rgba(30, 51, 40, .38); }
.vcard .draw { background: var(--bp-ground); border-bottom: 1px solid var(--rule); }
.vcard .bd { padding: 20px 22px; }
.vcard h3 { font-size: 19px; }
.vcard p { font-size: 13px; color: rgba(42, 42, 40, .78); margin: 8px 0 12px; }
.vlink {
  font-family: var(--mono); font-size: 10px; letter-spacing: .1em;
  color: var(--clay); border-bottom: 1px solid rgba(168, 85, 38, .4);
  padding-bottom: 2px; display: inline-block;
}
/* Venue pages are held back until Kevin's research exists: a thin venue
   page is worse than no venue page (spec 8.2, 12.4). Until then the card
   is not a link and carries no dead arrow. To publish, swap the <div
   class="vcard"> for <a class="vcard" href="venues/<slug>/"> and
   uncomment the .vlink span into an anchor. Nothing else changes. */
.vcard--pending .vlink {
  color: var(--forest-mid); border-bottom-color: transparent; opacity: .8;
}

/* ============================================================
   TESTIMONIALS
   Component built, rendered disabled. It emits nothing until an
   approved, signed-off testimonial exists. Never publish a
   placeholder, a lorem quote or an invented logo. (spec 4.5, 13)
   ============================================================ */
.testi[hidden] { display: none; }
.testi { background: var(--ivory); padding: 0 var(--pad-x) var(--pad-y); }
.tgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
.tcard {
  background: var(--white); border: 1px solid var(--rule);
  border-radius: var(--r-card); padding: 22px;
}
.tcard blockquote { margin: 0; font-family: var(--display); font-size: 17px; color: var(--forest); line-height: 1.4; }
.tcard .biz { font-family: var(--mono); font-size: 10px; letter-spacing: .08em; color: var(--forest-mid); margin-top: 14px; }
.tcard .logo { max-height: 26px; width: auto; margin-top: 12px; }
.tcard .stars { color: var(--clay); font-size: 13px; margin-top: 8px; letter-spacing: .1em; }

/* ============================================================
   ABOUT (spec 7)
   ============================================================ */
.vhero, .abouthero { background: var(--forest); padding: var(--pad-y) var(--pad-x); }
.abouthero h1 { color: var(--ivory); font-size: 44px; max-width: 16ch; }
.abouthero .stand { color: rgba(251, 248, 241, .82); max-width: 54ch; margin-top: 14px; font-size: 16px; }

.sec--light { background: var(--ivory); }
/* Two 56px paddings back to back put 112px of nothing between one block and
   the next, which read as the page having lost its place. The hairline
   already does the separating, so the second section only needs enough top
   padding to breathe. (spec 2.4 keeps its 56px; this is the JOIN between
   two sections, which the spec does not describe.) */
.sec--light + .sec--light,
.sec--light + .contact { padding-top: 24px; }
.sec--light + .sec--light { border-top: 1px solid var(--rule); }
.sec h2 { font-size: 32px; }
.sec .stand { max-width: 64ch; font-size: 15.5px; color: rgba(42, 42, 40, .8); margin-top: 10px; }

/* One or two words in --clay, never the whole line. This sits on a
   light ground, so it is --clay, not --clay-bright. */
.hl { color: var(--clay); }

/* The team block. The forest ground encloses the group photograph:
   the photo sits INSIDE the green section, not on ivory below it. */
.team { background: var(--forest); padding: var(--pad-y) var(--pad-x); }
/* "Three noses, one method." lives on this green ground from v7.1, in
   --ivory, matching every other section heading at 32px. It is NOT
   #FFFFFF: pure white is never a type colour here, and --ivory is the
   white variant the homepage H1 already uses on this exact ground
   (12.70:1). No clay highlight, because clay on forest is dark on dark. */
.team h2 { color: var(--ivory); font-size: 32px; }
.team .stand { color: rgba(251, 248, 241, .82); }
/* The group photograph BLENDS into the forest ground rather than sitting
   on it as a rectangle. The hairline that used to frame it is gone: a hard
   border is the opposite of blending. Instead the forest is painted back
   over the bottom and both side edges, so the picture dissolves into the
   panel it lives in. The bottom carries most of it, because that is where
   the caption follows and the seam would otherwise be most obvious.

   Graded monochrome in the file itself, like the three portraits, so all
   four photographs on this page read as one set. */
.team__group {
  position: relative;
  margin-top: 20px; max-width: 560px;
  border-radius: var(--r-img); overflow: hidden;
}
.team__group::after {
  content: ""; position: absolute; inset: 0; z-index: 3; pointer-events: none;
  background:
    linear-gradient(to bottom,
      rgba(30, 51, 40, 0) 46%,
      rgba(30, 51, 40, .40) 76%,
      rgba(30, 51, 40, .92) 100%),
    linear-gradient(to right,
      rgba(30, 51, 40, .55) 0%,
      rgba(30, 51, 40, 0) 13%,
      rgba(30, 51, 40, 0) 87%,
      rgba(30, 51, 40, .55) 100%);
}
.team__cap {
  font-family: var(--mono); font-size: 10px; letter-spacing: .08em;
  color: rgba(251, 248, 241, .75); margin-top: 10px;
}
/* The portrait row is capped so the three pictures are noticeably smaller
   than the full column width, without leaving dead space beside them. */
.team__grid { max-width: 900px; }
.team__story { color: rgba(251, 248, 241, .82); max-width: 60ch; margin-top: 18px; font-size: 15px; }
.team h3.sub-h { color: var(--ivory); font-size: 24px; margin-top: 30px; }
.team__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-top: 18px; }
.team__grid > * { min-width: 0; }
/* Individual portraits, restored 2026-07-31 at the owner's instruction.
   Cropped 4:5 around the face upstream, so object-fit has nothing left to
   cut off, and served at the largest size the source actually contains.

   MONOCHROME, graded in the FILE, not with a CSS filter. The earlier
   grayscale looked dead because it was a flat desaturation with a forest
   blend on top: every tone bunched in the middle and went green. These are
   converted with a real black and white point set per image, then contrast,
   then an unsharp mask. Prithvish's frame is a soft candid, so his gets a
   much stronger sharpen than the other two.

   Doing it in the file rather than in CSS means the three photographs, which
   were taken in three completely different conditions, arrive already
   matched to each other instead of relying on the browser to do it.

   A hairline seats the picture on the green so it reads as a photograph
   and not as a hole cut in the panel. */
.tphoto {
  aspect-ratio: 4 / 5; position: relative; overflow: hidden;
  border-radius: var(--r-img);
  background: rgba(251, 248, 241, .06);
  box-shadow: inset 0 0 0 1px rgba(251, 248, 241, .16);
  margin-bottom: 12px;
}
.tphoto img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transform: scale(1.001);           /* kills a sub-pixel edge seam */
  transition: transform .5s ease;
}
.tperson:hover .tphoto img,
.tperson:focus-within .tphoto img { transform: scale(1.03); }
@media (prefers-reduced-motion: reduce) {
  .tphoto img { transition: none; }
  .tperson:hover .tphoto img,
  .tperson:focus-within .tphoto img { transform: scale(1.001); }
}
.tperson .nm { font-family: var(--display); font-size: 19px; color: var(--ivory); }
.tperson .city { font-family: var(--mono); font-size: 10px; letter-spacing: .1em; color: rgba(251, 248, 241, .75); margin-top: 6px; }
.tperson .brings { font-size: 13.5px; color: rgba(251, 248, 241, .82); margin: 10px 0 0; }
.tperson .langs {
  font-family: var(--mono); font-size: 10px; letter-spacing: .06em;
  color: rgba(251, 248, 241, .75); margin-top: 10px; line-height: 1.6;
}

/* The method, moved here from the homepage. */
.timeline { margin-top: 22px; position: relative; padding-left: 34px; }
.timeline::before {
  content: ""; position: absolute; left: 8px; top: 8px; bottom: 8px;
  width: 2px; background: rgba(30, 51, 40, .22);
}
.stage { position: relative; padding-bottom: 20px; max-width: 68ch; }
.stage:last-child { padding-bottom: 0; }
.stage::before {
  content: ""; position: absolute; left: -31px; top: 5px;
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--forest); border: 3px solid var(--ivory);
}
.stage .n { font-family: var(--mono); font-size: 10px; letter-spacing: .1em; color: var(--forest-mid); }
.stage h3 { font-family: var(--display); font-size: 19px; margin: 4px 0 6px; }
.stage p { font-size: 14px; color: rgba(42, 42, 40, .78); margin: 0; }

/* The three artefacts, moved here from the homepage with the method. */
.artefacts { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; margin-top: 26px; }
.artefacts > * { min-width: 0; }
.acard { background: var(--white); border: 1px solid var(--rule); border-radius: var(--r-card); padding: 22px; }
.acard .n { font-family: var(--mono); font-size: 10px; letter-spacing: .1em; color: var(--forest-mid); }
.acard h3 { font-family: var(--display); font-size: 19px; margin: 6px 0 0; }
.acard p { font-size: 13px; color: rgba(42, 42, 40, .78); margin: 8px 0 0; }

/* Scope statement. Its own block, not a footnote. This is a legal
   boundary, not marketing copy: do not paraphrase or shorten it.
   (spec 0, 7, 11.5) */
.scopegrid { display: grid; grid-template-columns: 1.1fr .9fr; gap: 34px; align-items: start; margin-top: 12px; }
.scopegrid > * { min-width: 0; }
.scope {
  background: var(--white); border: 1px solid var(--rule);
  border-left: 3px solid var(--forest); border-radius: var(--r-card);
  padding: 26px 28px; max-width: 74ch;
}
.scope p { font-size: 14.5px; color: rgba(42, 42, 40, .82); margin: 0; }
.diffuser { background: var(--white); border: 1px solid var(--rule); border-radius: var(--r-card); padding: 16px; }
.diffuser svg { width: 100%; height: auto; }

/* Markets: United Kingdom, Germany, Greece. */
.mkgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; margin-top: 20px; }
.mkgrid > * { min-width: 0; }
.market {
  background: var(--white); border: 1px solid var(--rule);
  border-radius: var(--r-card); padding: 22px;
}
.market .country { font-family: var(--display); font-size: 19px; color: var(--forest); margin: 0; }
.market .cities { font-family: var(--mono); font-size: 10px; letter-spacing: .1em; color: var(--forest-mid); margin: 8px 0 0; line-height: 1.8; }

/* The direct email line beside the form. */
.contact-direct { font-size: 13px; color: rgba(42, 42, 40, .78); margin-top: 20px; }
.contact-direct a { color: var(--clay); }

/* ============================================================
   CONTACT FORM (spec 6)
   ============================================================ */
.contact { background: var(--ivory); padding: var(--pad-y) var(--pad-x); }
.cgrid { display: grid; grid-template-columns: .9fr 1.1fr; gap: 40px; align-items: start; }
.cgrid > * { min-width: 0; }
.cform { background: var(--white); border: 1px solid var(--rule); border-radius: var(--r-card); padding: 28px 26px; }
.field { margin-bottom: 16px; }
.field:last-of-type { margin-bottom: 0; }
.cf-lab {
  display: block; font-family: var(--mono); font-size: 10.5px;
  letter-spacing: .06em; color: var(--forest-mid); margin-bottom: 6px;
}
.cf-in {
  width: 100%; font-family: var(--body); font-size: 14px; color: var(--charcoal);
  background: var(--ivory); border: 1px solid var(--rule);
  border-radius: var(--r-btn); padding: 11px 12px;
}
textarea.cf-in { min-height: 96px; resize: vertical; }
/* The better dropdown: same box as the other inputs, custom chevron,
   native select underneath so it stays keyboard and screen-reader
   operable. */
select.cf-in {
  appearance: none; -webkit-appearance: none;
  padding-right: 38px; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%233A5544' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 13px center;
  background-size: 12px 8px;
}
.cf-in:focus { border-color: var(--forest-mid); }
.cf-in[aria-invalid="true"] { border-color: var(--clay); }
/* Errors are never colour alone. Every one carries text. (spec 6.2, 9.3) */
.cf-err { font-size: 12.5px; color: var(--clay); margin: 6px 0 0; }
.cf-err:empty { display: none; }

.consent { display: flex; gap: 10px; align-items: flex-start; margin-top: 18px; }
.consent input { margin-top: 3px; flex: none; width: 16px; height: 16px; }
.consent label { font-size: 13px; color: rgba(42, 42, 40, .82); }
.cform .btn { margin-top: 18px; width: 100%; }
/* rgba(42,42,40,.72) on white is 6.35:1. The 11px note must stay
   legible; the mockup's .62 measured 4.15:1 on ivory and failed. */
.cf-note { font-size: 11px; color: rgba(42, 42, 40, .72); margin-top: 12px; line-height: 1.6; }
.cf-note a { color: var(--clay); }
/* Honeypot. Off-screen rather than display:none so a bot that checks
   computed style still fills it. Never focusable by a person. */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.cf-done {
  background: var(--mineral); border: 1px solid var(--rule);
  border-radius: var(--r-card); padding: 26px 28px;
}
.cf-done p { margin: 0; font-family: var(--display); font-size: 19px; color: var(--forest); }
.cf-fail { border-left: 3px solid var(--clay); padding-left: 14px; margin-top: 16px; }
.cf-fail p { font-size: 13.5px; color: rgba(42, 42, 40, .82); margin: 0; }
.cf-fail a { color: var(--clay); }

/* ============================================================
   VENUE PAGES (spec 8) - importance grid
   Never colour alone. Every cell carries the word High, Medium or
   Low as text, in --forest, with the colour on a swatch beside it.
   sage on ivory is 2.83:1, so the word could not be sage. (spec 8.1)
   ============================================================ */
.vhero h1 { color: var(--ivory); font-size: 44px; max-width: 16ch; }
.vhero .stand { color: rgba(251, 248, 241, .82); max-width: 54ch; margin-top: 14px; font-size: 16px; }
.igrid { width: 100%; border-collapse: collapse; margin-top: 24px; background: var(--white); border: 1px solid var(--rule); }
.igrid caption { text-align: left; font-size: 13px; color: rgba(42, 42, 40, .78); padding-bottom: 10px; }
.igrid th, .igrid td { border: 1px solid var(--rule); padding: 12px 14px; text-align: left; }
.igrid th { font-family: var(--mono); font-size: 10px; letter-spacing: .08em; color: var(--forest-mid); font-weight: 400; }
.igrid td { font-size: 13px; color: var(--forest); }
.rate { display: inline-flex; align-items: center; gap: 8px; }
.rate .sw { width: 11px; height: 11px; border-radius: 2px; flex: none; }
.rate--high .sw { background: var(--rate-high); }
.rate--medium .sw { background: var(--rate-medium); }
.rate--low .sw { background: var(--rate-low); }
/* A block whose content has not arrived. Labelled, never invented.
   Do not fill this with a statistic, percentage or citation that is
   not in the specification. (spec 8.2, 13) */
.pending {
  border: 1px dashed rgba(30, 51, 40, .3); border-radius: var(--r-card);
  padding: 22px 24px; margin-top: 20px;
}
.pending .t { font-family: var(--mono); font-size: 10px; letter-spacing: .12em; color: var(--forest-mid); margin: 0; }
.pending p { font-size: 13px; color: rgba(42, 42, 40, .78); margin: 8px 0 0; max-width: 60ch; }
.pending + .pending { margin-top: 12px; }
.pending-cell { font-family: var(--mono); font-size: 10px; letter-spacing: .1em; color: var(--forest-mid); }
.venue-plan { margin-top: 20px; }

/* ============================================================
   FOOTER (spec 3.2)
   ============================================================ */
.foot { background: var(--forest); padding: 40px var(--pad-x); color: rgba(251, 248, 241, .75); font-size: 13px; }
.foot__inner { max-width: var(--maxw); margin-inline: auto; }
/* The slogan's new home. Second and last place --clay-bright is text. */
.foot .slog {
  font-family: var(--display); font-style: italic; font-size: 20px;
  color: var(--clay-bright); margin-bottom: 14px;
}
.foot .cols { display: flex; justify-content: space-between; gap: 20px; flex-wrap: wrap; align-items: baseline; }
.foot .fm { font-family: var(--display); font-size: 17px; color: var(--ivory); }
/* 55%, not the 50% in the spec: 8.5px at 50% measured 4.38:1 and
   failed AA. 55% measures 4.97:1. */
.foot .fm span { font-family: var(--mono); font-size: 8.5px; letter-spacing: .2em; color: rgba(251, 248, 241, .55); margin-left: 10px; }
.foot .meta { text-align: right; }
/* The location list is plain text, not links. The email is a mailto. */
.foot .meta a { color: rgba(251, 248, 241, .9); }
.foot__links { margin-top: 16px; padding-top: 14px; border-top: 1px solid rgba(251, 248, 241, .18); display: flex; gap: 16px; flex-wrap: wrap; font-family: var(--mono); font-size: 10px; letter-spacing: .08em; }
.foot__links a { color: rgba(251, 248, 241, .8); text-decoration: none; }
.foot__links a:hover { color: var(--ivory); }

/* ============================================================
   DOCUMENT PAGES (privacy, redirect stubs, 404)
   ============================================================ */
.doc { padding: var(--pad-y) var(--pad-x); }
.doc__inner { max-width: 760px; margin-inline: auto; }
.doc h1 { font-size: 32px; margin-bottom: 16px; }
.doc h2 { font-size: 19px; margin-top: 28px; margin-bottom: 6px; }
.doc p, .doc li { color: rgba(42, 42, 40, .88); }
.doc ul { padding-left: 20px; }
.doc a { color: var(--clay); }
.doc__back { font-family: var(--mono); font-size: 11px; letter-spacing: .08em; text-decoration: none; }
.doc__cta { margin-top: 34px; }
.e404 { text-align: center; padding: 90px var(--pad-x); }
.e404 h1 { font-size: 44px; }
.e404 p { max-width: 46ch; margin: 14px auto 26px; color: rgba(42, 42, 40, .8); }

/* ============================================================
   IMAGE MEDIA SYSTEM
   A delegated img-onerror handler adds .img--failed, so a missing
   file shows the branded placeholder, never a broken icon.
   ============================================================ */
.media { position: relative; overflow: hidden; border-radius: var(--r-img); background: linear-gradient(160deg, var(--ivory), var(--mineral)); }
.media--3-2 { aspect-ratio: 3 / 2; }
.media__ph {
  position: absolute; inset: 0; z-index: 0;
  display: grid; place-content: center; gap: 8px; justify-items: center;
  font-family: var(--mono); font-size: 10px; letter-spacing: .12em;
  color: var(--forest-mid);
}
.media__ph::before { content: ""; width: 32px; height: 42px; background: url("favicon.svg") center / contain no-repeat; opacity: .7; }
.media img { position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%; object-fit: cover; }
.media img.img--failed { display: none; }
/* The duotone treatment was REMOVED on 2026-08-01. It grayscaled every
   photograph and blended forest over it. That was tuned for photos on an
   ivory ground; once the team block became green it turned three faces
   flat and sickly. Nothing uses it now, so the rules are gone rather than
   left lying around for someone to reapply by habit. Photographs on this
   site are in colour, with a light grade only. */

/* ============================================================
   RESPONSIVE. ONE breakpoint (spec 2.5).
   All multi-column grids collapse to one. Hero text stacks above
   the image. Hero H1 drops 56px to 38px. Section padding to 26px.
   The header wraps and all three nav items stay visible; there is
   no hamburger.
   ============================================================ */
@media (max-width: 900px) {
  :root { --pad-x: 26px; }

  .hero__inner { grid-template-columns: 1fr; }
  .hero .txt { padding: 46px var(--pad-x) 40px; order: 1; }
  .hero .imgside { order: 2; min-height: 240px; }
  .hero .imgside::after {
    background: linear-gradient(180deg, rgba(30, 51, 40, .72) 0%, rgba(30, 51, 40, .18) 70%);
  }
  .hero h1 { font-size: 38px; max-width: none; }

  .rowhead { grid-template-columns: 1fr; gap: 14px; }
  .expander { grid-template-columns: 1fr; gap: 22px; }
  .vgrid, .tgrid, .mkgrid, .team__grid, .cgrid,
  .artefacts, .scopegrid { grid-template-columns: 1fr; }
  .cgrid { gap: 28px; }
  .bar { grid-template-columns: 104px 1fr 46px; }
  .cbar { grid-template-columns: 104px 1fr 58px; }

  .hdr__inner { justify-content: flex-start; }
  .hdr nav { width: 100%; }

  .foot .cols { flex-direction: column; }
  .foot .meta { text-align: left; }

  .amb h2, .ven h2, .sec h2, .team h2 { font-size: 26px; }
  .abouthero h1, .vhero h1 { font-size: 34px; }
  .igrid, .igrid thead, .igrid tbody, .igrid th, .igrid td, .igrid tr { display: block; }
  .igrid thead { display: none; }
  .igrid td { border-top: none; }
  .igrid tr { border-top: 1px solid var(--rule); padding: 6px 0; }
  .igrid td::before { content: attr(data-th) "  "; font-family: var(--mono); font-size: 10px; letter-spacing: .08em; color: var(--forest-mid); }
}

/* ============================================================
   MOTION
   Every hiding rule is scoped under .js-motion, so with JavaScript
   off nothing is ever hidden. Only transform and opacity animate.
   ============================================================ */
.js-motion [data-animate] { opacity: 0; transform: translateY(16px); }
.js-motion [data-animate].in {
  opacity: 1; transform: none;
  transition: opacity 420ms cubic-bezier(.22, .61, .36, 1),
              transform 420ms cubic-bezier(.22, .61, .36, 1);
}

@media (prefers-reduced-motion: reduce) {
  .js-motion [data-animate], .js-motion [data-animate].in {
    opacity: 1; transform: none; transition: none;
  }
}
