/* ==========================================================================
   MYNT MODELS — shared foundation for every concept
   Palette, type, reset and the primitives each concept builds on.
   Layout, structure and rhythm live in the per-concept stylesheet.
   ========================================================================== */

/* Visually hidden, still read aloud. Deliberately not `.skip`: that is a
   focusable control parked above the viewport until it is tabbed to, and it
   only stays out of sight while the page root is its containing block. A
   <label> never takes focus, so inside any positioned ancestor `.skip` leaves
   it permanently on display. */
.vh {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  border: 0; clip-path: inset(50%); overflow: hidden; white-space: nowrap;
}

:root {
  /* Supplied palette. Deep green is an INK — headings, buttons, the thin
     strip above the fold, and image overlays. It is never a section ground. */
  --paper:      #EFF8EB;
  --mint-100:   #E6F8E1;
  --mint-200:   #E3F5DE;
  --mint-300:   #E1F0DC;
  --band:       #E1F0DC;
  --sage:       #7BA673;
  --forest:     #384D34;

  /* Ink. Every value clears WCAG AA on both grounds. */
  --ink:        #384D34;
  --ink-2:      #55694F;
  --ink-3:      #54684F;
  --ink-on-dark:  #E6F8E1;
  --ink-on-dark-2:#B7CFB0;

  /* Aged brass — ornament, and a darker cut for brass that carries words. */
  --gilt:       #A98F5F;
  --gilt-ink:   #7A5F30;
  --gilt-soft:  #CDB88C;

  --rule:       rgba(56, 77, 52, .16);
  --rule-gilt:  rgba(169, 143, 95, .42);
  --rule-dark:  rgba(230, 248, 225, .18);
  --mount:      rgba(255, 255, 255, .58);

  --serif: "DM Serif Display", "Iowan Old Style", "Times New Roman", serif;
  --sans:  "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  --gutter: clamp(1.25rem, 4vw, 3.25rem);
  --header-h: 11rem;
  --ease: cubic-bezier(.22, 1, .36, 1);
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: 8rem; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink-2);
  font-family: var(--sans);
  /* Water-like: every size is a fluid function of the viewport, not a step. */
  font-size: clamp(1rem, .955rem + .19vw, 1.0625rem);
  line-height: 1.78;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

/* Grain — flat mint reads like a screen fill; a whisper of tooth reads
   like stock. */
body::after {
  content: "";
  position: fixed; inset: 0; z-index: 3;
  pointer-events: none; opacity: .038;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
}

img, svg { display: block; max-width: 100%; height: auto; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; }
ul, ol { margin: 0; padding: 0; list-style: none; }
h1, h2, h3, h4, h5, h6, p, figure, blockquote { margin: 0; }

:focus-visible { outline: 2px solid var(--gilt-ink); outline-offset: 3px; border-radius: 1px; }
::selection { background: var(--sage); color: var(--paper); }

/* --------------------------------------------------------------------------
   TYPE PRIMITIVES
   -------------------------------------------------------------------------- */
.d1, .d2, .d3, .d4 { font-family: var(--serif); font-weight: 400; color: var(--ink); letter-spacing: -.02em; }
.d1 { font-size: clamp(2.35rem, .95rem + 5.1vw, 5.25rem); line-height: .98; }
.d2 { font-size: clamp(2.05rem, 1.1rem + 2.9vw, 3.6rem);  line-height: 1.06; }
.d3 { font-size: clamp(1.45rem, 1.15rem + .95vw, 2.05rem); line-height: 1.18; letter-spacing: -.014em; }
.d4 { font-size: clamp(1.12rem, 1rem + .4vw, 1.4rem);      line-height: 1.3;  letter-spacing: -.008em; }

.em { font-style: italic; }

.eyebrow {
  display: block;
  margin: 0 0 clamp(1rem, 2vw, 1.6rem);
  font-size: clamp(.625rem, .59rem + .14vw, .6875rem);
  font-weight: 500; letter-spacing: .26em; line-height: 1.7;
  text-transform: uppercase; color: var(--gilt-ink);
}
.eyebrow::before { content: "\2756"; margin-right: .9em; font-size: .8em; letter-spacing: 0; opacity: .85; }

.lede {
  font-family: var(--serif); font-style: italic;
  font-size: clamp(1.25rem, 1rem + 1.05vw, 1.9rem);
  line-height: 1.42; letter-spacing: -.012em; color: var(--ink);
}

.prose > * + * { margin-top: 1.4em; }
.prose p { line-height: 1.85; }
.note { font-size: .875rem; line-height: 1.7; color: var(--ink-3); }

/* FULL-MEASURE PROSE.
   A passage capped at 44rem leaves half a widescreen empty either side and
   reads as a ribbon stranded in the middle of the page. These are paragraphs
   of continuous argument, so they stay a single column and simply take the
   full width of the content around them — the same width as the grid rows
   above and below them. */
.prose--fill {
  /* !important because this single utility has to defeat a different measure
     cap in each of the five concept stylesheets — .measure, .prose--wide and
     .chapter__body > .prose — all of which load after this file and would
     otherwise win on source order. The alternative is the same declaration
     repeated five times with escalating selectors. */
  max-width: none !important;
}
/* A long line needs a little more leading to stay trackable, and a fraction
   more size so the measure does not read as thin. */
.prose--fill p { line-height: 1.95; }

.prose a, .note a, .linkish {
  color: var(--ink);
  background-image: linear-gradient(var(--gilt), var(--gilt));
  background-repeat: no-repeat; background-position: 0 100%; background-size: 100% 1px;
  padding-bottom: .08em;
  transition: background-size .35s var(--ease), color .35s ease;
}
.prose a:hover, .note a:hover, .linkish:hover { background-size: 100% 2px; color: var(--gilt-ink); }

/* --------------------------------------------------------------------------
   THE MOUNT & THE VEIL — photography treatment, shared by every concept
   -------------------------------------------------------------------------- */
.plate { position: relative; overflow: hidden; background: var(--mint-300); isolation: isolate; }
.plate img {
  width: 100%; height: 100%; object-fit: cover;
  filter: saturate(.88) contrast(.98);
  transform: scale(1.015);
  transition: transform 1.4s var(--ease), filter 1s ease;
}
.plate::before {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(158deg, rgba(56,77,52,.14) 0%, rgba(56,77,52,.26) 48%, rgba(56,77,52,.46) 100%);
  transition: opacity .9s var(--ease);
}
.plate::after {
  content: ""; position: absolute; inset: clamp(.6rem, 1.3vw, 1.05rem);
  z-index: 2; pointer-events: none; border: 1px solid var(--mount);
}
.plate:hover img, .plate:focus-within img { transform: scale(1.045); filter: saturate(1) contrast(1); }
.plate:hover::before, .plate:focus-within::before { opacity: .38; }

.plate--wide { aspect-ratio: 21 / 9; }
.plate--cinema { aspect-ratio: 16 / 7; }
.plate--landscape { aspect-ratio: 4 / 3; }
.plate--portrait { aspect-ratio: 4 / 5; }
.plate--tall { aspect-ratio: 3 / 4; }
.plate--square { aspect-ratio: 1; }

/* --------------------------------------------------------------------------
   THE HERO FILM — shared by every concept
   Never scaled, never zoomed: the footage plays at its own framing. It sits
   on a deep brand-green field so that before it arrives, and behind its own
   letterboxing, the eye sees the house colour rather than a hole.
   -------------------------------------------------------------------------- */
.hero__media { background: linear-gradient(165deg, #2E3F2B, #1F2B1D); }
.hero__video {
  width: 100%; height: 100%;
  object-fit: cover; object-position: center;
  /* Pulled towards the palette so the footage reads as part of the house
     rather than as stock laid underneath it. */
  filter: saturate(.68) contrast(1.04) brightness(.9);
  opacity: 0;
  transition: opacity 1.6s ease;
}
.hero__video.is-playing { opacity: 1; }
/* The still fallback keeps the photograph — and its alt text — in the source
   for any client that will not play video. */
.hero__video > img { width: 100%; height: 100%; object-fit: cover; }

/* THE FOCAL POINT.
   The film is 540x960 — portrait. In a portrait frame it is taller than it is
   wide relative to the box, so `cover` scales by height and the whole figure
   is shown: nothing is cropped vertically and she reads head to foot. That is
   why phones already look right.

   In a landscape frame the maths inverts. `cover` scales by width, and at a
   typical desktop hero only ~26% of the film's height survives. Centred, that
   window lands on her waist and the face is cut away entirely. Her face sits
   at roughly 25% down the frame, so the window is biased towards the top
   instead — head and shoulders, not torso.

   Scoped to orientation rather than to a width, because a phone held sideways
   has exactly the desktop problem. */
@media (orientation: landscape) {
  .hero__video,
  .hero__video > img { object-position: center 18%; }
}

/* --------------------------------------------------------------------------
   BUTTONS
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; gap: .8em;
  padding: 1.05em 2.3em;
  font-family: var(--serif);
  font-size: clamp(.8125rem, .78rem + .12vw, .9375rem);
  letter-spacing: .17em; text-transform: uppercase; line-height: 1;
  border: 1px solid var(--forest); background: var(--forest); color: var(--mint-100);
  position: relative; overflow: hidden;
  transition: color .5s var(--ease);
}
.btn::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background: var(--mint-100);
  transform: scaleX(0); transform-origin: right;
  transition: transform .55s var(--ease);
}
.btn > * { position: relative; z-index: 1; }
.btn:hover { color: var(--forest); }
.btn:hover::before { transform: scaleX(1); transform-origin: left; }
.btn--ghost { background: transparent; color: var(--ink); border-color: var(--rule-gilt); }
.btn--ghost::before { background: var(--forest); }
.btn--ghost:hover { color: var(--mint-100); border-color: var(--forest); }
.btn--light { background: var(--mint-100); border-color: var(--mint-100); color: var(--forest); }
.btn--light::before { background: transparent; }
.btn--light:hover { background: transparent; color: var(--mint-100); }
.btn__mark { font-size: .85em; opacity: .7; }

/* --------------------------------------------------------------------------
   MOTION — one gentle reveal, opt-in via .js so no-script never hides content
   -------------------------------------------------------------------------- */
.js .reveal { opacity: 0; transform: translateY(16px); transition: opacity .85s var(--ease), transform .85s var(--ease); }
.js .reveal.is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
  .js .reveal { opacity: 1; transform: none; }
}
