/* ==========================================================================
   Movement Ecology — shared mechanics for the three directions.
   Fonts, tokens, reset, header/menu behaviour, accordion behaviour, focus, reduced motion.
   Every visual and layout decision lives in the direction's own stylesheet.
   ========================================================================== */

/* Newsreader (Production Type, OFL) — variable, with optical sizes: A */
@font-face { font-family: "Newsreader"; src: url("../assets/fonts/newsreader-roman-var.woff2") format("woff2"); font-weight: 200 800; font-style: normal; font-display: swap; }
@font-face { font-family: "Newsreader"; src: url("../assets/fonts/newsreader-italic-var.woff2") format("woff2"); font-weight: 200 800; font-style: italic; font-display: swap; }
/* Boska (Indian Type Foundry, ITF Free Font License): C */
@font-face { font-family: "Boska"; src: url("../assets/fonts/boska-200.woff2") format("woff2"); font-weight: 200; font-style: normal; font-display: swap; }
@font-face { font-family: "Boska"; src: url("../assets/fonts/boska-300.woff2") format("woff2"); font-weight: 300; font-style: normal; font-display: swap; }
@font-face { font-family: "Boska"; src: url("../assets/fonts/boska-400.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Boska"; src: url("../assets/fonts/boska-300i.woff2") format("woff2"); font-weight: 300; font-style: italic; font-display: swap; }
@font-face { font-family: "Boska"; src: url("../assets/fonts/boska-400i.woff2") format("woff2"); font-weight: 400; font-style: italic; font-display: swap; }
/* Imbue (Tyler Finck, OFL) — variable condensed didone: B */
@font-face { font-family: "Imbue"; src: url("../assets/fonts/imbue-roman-var.woff2") format("woff2"); font-weight: 100 900; font-style: normal; font-display: swap; }
/* Switzer (Indian Type Foundry, ITF Free Font License): UI in all three */
@font-face { font-family: "Switzer"; src: url("../assets/fonts/switzer-400.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Switzer"; src: url("../assets/fonts/switzer-500.woff2") format("woff2"); font-weight: 500; font-style: normal; font-display: swap; }

:root {
  --paper: #EFF0E9;
  --mist: #E4E7DD;
  --spruce: #26342C;
  --spruce-deep: #18231D;
  --spruce-ink: #111A15;
  --ink: #16211B;
  --ink-soft: #43514A;
  --ink-mute: #5B685F;
  --on-dark: #F1F2EB;
  --on-dark-soft: #C5CEC1;
  --on-dark-mute: #9DAA9A;
  --line: rgba(22, 33, 27, 0.18);
  --line-strong: rgba(22, 33, 27, 0.34);
  --line-dark: rgba(241, 242, 235, 0.2);

  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;   /* each direction sets its own */
  --sans: "Switzer", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  --gutter: clamp(1.25rem, 5vw, 4.5rem);
  --maxw: 1360px;
  --header-h: 4.75rem;

  /* header colours — each direction overrides these */
  --hdr-fg: var(--ink);
  --hdr-fg-solid: var(--ink);
  --hdr-bg-solid: var(--paper);
  --menu-bg: var(--spruce-deep);
  --menu-fg: var(--on-dark);
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: 5rem; -webkit-text-size-adjust: 100%; }
body {
  margin: 0; overflow-x: clip;
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(1.0625rem, 0.98rem + 0.3vw, 1.1875rem); line-height: 1.66;
  font-kerning: normal; text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
}
img { display: block; max-width: 100%; height: auto; }
h1, h2, h3, h4, p, figure, blockquote { margin: 0; }
h1, h2, h3, h4 { font-weight: 300; text-wrap: balance; }
p { text-wrap: pretty; }
strong { font-weight: 500; }
a { color: inherit; }
ol, ul { margin: 0; padding: 0; list-style: none; }
:focus-visible { outline: 2px solid currentColor; outline-offset: 4px; border-radius: 2px; }

.wrap { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gutter); }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

.skip {
  position: fixed; top: 0.75rem; left: 0.75rem; z-index: 100;
  padding: 0.7rem 1.1rem; background: var(--paper); color: var(--ink);
  font: 500 0.8rem/1 var(--sans); letter-spacing: 0.08em; text-transform: uppercase; text-decoration: none;
  transform: translateY(-200%); transition: transform 0.2s var(--ease);
}
.skip:focus { transform: none; }

/* ---------- Header + menu (behaviour) ---------- */
.site-header {
  position: fixed; inset: 0 0 auto 0; z-index: 50;
  display: flex; align-items: center; justify-content: space-between;
  height: var(--header-h);
  padding-inline: max(var(--gutter), calc((100% - var(--maxw)) / 2 + var(--gutter)));
  color: var(--hdr-fg);
  transition: color 0.45s var(--ease), height 0.45s var(--ease);
}
.site-header::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: color-mix(in srgb, var(--hdr-bg-solid) 95%, transparent);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  opacity: 0; transition: opacity 0.45s var(--ease);
}
.site-header.is-solid { color: var(--hdr-fg-solid); height: 4rem; }
.site-header.is-solid::before { opacity: 1; }
.wordmark { text-decoration: none; white-space: nowrap; }
.site-nav { display: flex; }
.site-nav a { text-decoration: none; }
.menu-toggle { display: none; padding: 0.6rem 0; background: none; border: 0; cursor: pointer; color: inherit; font: inherit; }

@media (max-width: 760px) {
  :root { --header-h: 4rem; }
  .menu-toggle { display: inline-flex; position: relative; z-index: 2; }
  .site-nav {
    position: fixed; inset: 0; z-index: 1; flex-direction: column; justify-content: center;
    padding: calc(var(--header-h) + 2rem) var(--gutter) 2rem;
    background: var(--menu-bg); color: var(--menu-fg);
    opacity: 0; visibility: hidden; transition: opacity 0.35s var(--ease), visibility 0s linear 0.35s;
  }
  .site-header.menu-open { color: var(--menu-fg); }
  .site-header.menu-open::before { opacity: 0; }
  .site-header.menu-open .wordmark { position: relative; z-index: 2; }
  .site-header.menu-open .site-nav { opacity: 1; visibility: visible; transition: opacity 0.35s var(--ease), visibility 0s; }
}

/* ---------- Accordion (behaviour) ---------- */
.offering summary { list-style: none; cursor: pointer; }
.offering summary::-webkit-details-marker { display: none; }
.toggle { position: relative; display: inline-block; flex: none; }
.toggle::before, .toggle::after {
  content: ""; position: absolute; top: 50%; left: 50%; width: 0.8rem; height: 1px; background: currentColor;
  transform: translate(-50%, -50%);
}
.toggle::after { transform: translate(-50%, -50%) rotate(90deg); transition: transform 0.45s var(--ease); }
.offering[open] .toggle::after { transform: translate(-50%, -50%) rotate(0deg); }
@supports (interpolate-size: allow-keywords) {
  :root { interpolate-size: allow-keywords; }
  .offering::details-content { block-size: 0; overflow: hidden; transition: block-size 0.55s var(--ease), content-visibility 0.55s allow-discrete; }
  .offering[open]::details-content { block-size: auto; }
}

/* ---------- Reveal on scroll (hidden state only when JS is running) ---------- */
.js [data-reveal] { opacity: 0; transform: translateY(1.25rem); transition: opacity 1.1s var(--ease-out), transform 1.1s var(--ease-out); transition-delay: var(--d, 0s); }
.js [data-reveal].is-in { opacity: 1; transform: none; }
/* Image reveals clip the child <img>, never the observed element: IntersectionObserver reports a fully clipped target as 0% visible and it would never reveal. */
.js [data-reveal="img"] { opacity: 1; transform: none; }
.js [data-reveal="img"] > img { clip-path: inset(0 0 100% 0); transform: scale(1.06); transition: clip-path 1.4s var(--ease-out), transform 2.2s var(--ease-out); transition-delay: var(--d, 0s); }
.js [data-reveal="img"].is-in > img { clip-path: inset(0 0 0 0); transform: none; }

/* ---------- Photographs: they arrive, they do not blip in ----------
   A frame marked data-photo wears its photograph's own colours as a blurred placeholder (--lqip: the same picture at 28px, inline),
   so it is never an empty box. The real image is held back until it has downloaded and decoded and its frame is on screen
   (main.js), then it comes up out of the placeholder: opacity and a slow settle, like a print developing.
   Focus point (--pos) lives on the frame so the placeholder sits where the photograph does. */
picture { display: contents; }
[data-photo] img { object-position: var(--pos, 50% 50%); }
.js [data-photo] { background-color: var(--stone, #E4E7DD); background-image: var(--lqip); background-size: cover; background-position: var(--pos, 50% 50%); background-repeat: no-repeat; }
.js [data-photo] img { opacity: 0; scale: 1.035; transition: opacity 1.5s var(--ease-out), scale 2.6s var(--ease-out); }
.js [data-photo].is-shown img { opacity: 1; scale: 1; }

/* ---------- Motion ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; }
  .js [data-reveal], .js [data-reveal="img"], .js [data-reveal="img"] > img { opacity: 1; transform: none; clip-path: none; }
}
