/*
 * Sections added after the design was approved, at the client side's request
 * (2026-09-26):
 *
 *   .jennifer   a section of her own, highlighting her experience
 *   .process    "How we work" as a scroll-driven window, 01 -> 06
 *   .connect    the "Let's connect" enquiry form, in a dialog
 *
 * The first two replace the approved split section (founder panel beside
 * the approach list). That split sat directly above the globe section with
 * its colours reversed, a navy/pale over photo/navy checkerboard; as two
 * full-width sections the clash is gone.
 *
 * Everything here is built from the approved vocabulary in styles.css: its
 * colour tokens, DM Sans and Playfair Display, the uppercase tracked labels,
 * the hairline rules and the 2px corners. No new colours, no new type.
 */

/* =============================================================== intro == */

/* The mission statement is the intro's heading (2026-09-30, from the
   client's review): the approved heading was removed and the statement moved
   from the right column to the left. A full sentence, so smaller than a
   section heading, with the green rule it had on the right. */
.intro h2.mission-statement {
  max-width: 560px;
  margin-bottom: 0;
  padding-left: 24px;
  border-left: 3px solid var(--green);
  color: var(--navy);
  font-size: clamp(1.8rem, 2.7vw, 2.6rem);
  line-height: 1.28;
  letter-spacing: -.015em;
}

/* ============================================================ jennifer == */

.jennifer {
  background: var(--navy);
  color: #fff;
}
.jennifer-inner {
  max-width: 1450px;
  margin: auto;
  padding: 105px clamp(24px, 7vw, 100px);
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  column-gap: 8%;
  row-gap: 72px;
  align-items: start;
}

/* 300px wide, no more. The portrait (jennifer-oswald-portrait.jpg, supplied
   2026-09-27) is 1264x1104 but holds only about half that in real detail (it
   has been upscaled, like the photo before it), and this 4:5 frame uses the
   middle 70% of its width: roughly 440px of real detail. So the page loads
   jennifer-oswald-portrait.webp, the same photo at 760px (35 KB, not 168):
   still more than the detail it holds. On a screen scaled
   to 150% (most Windows laptops) a 420px photo is drawn 630 device pixels
   wide, an upscale that reads as out of focus; at 300px it is about 450. A
   sharper photo from Jennifer is the real fix.

   Since 2026-09-30 the copy is Jennifer's full biography, far taller than
   the photo, so the photo and her name start level with the copy and stay
   in view (sticky) while the biography scrolls past, then stop together
   exactly where the text ends.

   Chrome keeps a sticky element inside its parent's box. With the grid as
   the parent that was the whole section, record included, so the photo ran
   on past the text. .jennifer-photo is the parent instead: it fills the
   text's row and no more, so that is where the photo stops. */
.jennifer-photo {
  grid-column: 1;
  grid-row: 1;
  align-self: stretch;
}
.jennifer-portrait {
  margin: 0;
  width: 100%;
  max-width: 300px;
  position: sticky;
  top: 48px;
}
.jennifer-copy {
  grid-column: 2;
  grid-row: 1;
  align-self: start;
}
.jennifer-portrait img {
  display: block;
  width: 100%;
  /* height: auto, or the img's height="1104" attribute wins over the
     aspect ratio and the portrait renders twice as tall as intended. */
  height: auto;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: 50% 26%;
  border-radius: 2px;
}
.jennifer-portrait figcaption {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 22px;
  padding-top: 20px;
  border-top: 1px solid #6c8397;
}
.jennifer-portrait strong {
  font-family: 'Playfair Display', Georgia, serif;
  font-weight: 500;
  font-size: 1.9rem;
  line-height: 1.2;
}
.jennifer-portrait figcaption span {
  color: #bed0b9;
  text-transform: uppercase;
  font-size: .75rem;
  letter-spacing: .14em;
}

.jennifer-copy h2 {
  margin-bottom: 36px;
}
.jennifer-copy h2 em {
  color: #b6caaf;
}
.jennifer-copy p:not(.eyebrow) {
  color: #e7eeee;
  max-width: 620px;
  font-size: 1.05rem;
}
.jennifer-quote {
  margin: 40px 0 0;
  padding-left: 24px;
  border-left: 3px solid #6b9060;
}
.jennifer-quote p {
  margin: 0;
  font-family: 'Playfair Display', Georgia, serif;
  font-style: italic;
  font-size: clamp(1.35rem, 2vw, 1.75rem);
  line-height: 1.4;
  color: #fff;
  max-width: 600px;
}

/* The record: three facts from her profile, set like the global points but
   at display size. */
.jennifer-record {
  grid-column: 1 / -1;
  margin: 28px 0 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  padding-top: 36px;
  border-top: 1px solid rgba(255, 255, 255, .28);
}
.jennifer-record div {
  padding: 0 30px;
  border-left: 1px solid rgba(255, 255, 255, .22);
}
.jennifer-record div:first-child {
  padding-left: 0;
  border-left: 0;
}
.jennifer-record dt {
  font-family: 'Playfair Display', Georgia, serif;
  font-weight: 500;
  font-size: clamp(1.9rem, 2.6vw, 2.6rem);
  line-height: 1.1;
  letter-spacing: -.015em;
  margin-bottom: 12px;
}
.jennifer-record dd {
  margin: 0;
  max-width: 340px;
  color: #d2dfdf;
  font-size: .95rem;
  line-height: 1.55;
}

.jennifer-focus {
  grid-column: 1 / -1;
  margin-top: -34px;
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 12px 28px;
}
.jennifer-focus .eyebrow {
  margin: 0;
}
.jennifer-focus ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  row-gap: 10px;
}
.jennifer-focus li {
  font-size: .76rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: #dfe8e8;
}
.jennifer-focus li + li::before {
  content: "•";
  margin: 0 16px;
  color: #6b9060;
}

/* ============================================================= process ==
 *
 * Two states. Without script, or when reduced motion is requested, it is a
 * plain numbered list, which is also the approved content as approved.
 * enhance.js adds .is-engaged, which turns it into a tall section with a
 * sticky stage: the steps and a line that advances stage to stage on the
 * left, and on the right a window onto a film that scrolling scrubs through.
 */

.process {
  background: #ebf1ea;
  counter-reset: step;
}

.process-head h2 {
  margin-bottom: 30px;
}

.process-steps {
  list-style: none;
  margin: 0;
  padding: 0;
}
.process-steps li {
  display: grid;
  grid-template-columns: 56px 190px 1fr;
  gap: 12px;
  align-items: baseline;
  padding: 18px 0;
  border-bottom: 1px solid #d2dece;
  color: var(--muted);
}
.process-steps li::before {
  counter-increment: step;
  content: counter(step, decimal-leading-zero);
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .16em;
  color: var(--green);
}
.process-steps b {
  color: var(--navy);
  font-size: .83rem;
  text-transform: uppercase;
  letter-spacing: .08em;
}

/* --- static ------------------------------------------------------------ */
.process:not(.is-engaged) {
  padding: 105px clamp(24px, 7vw, 100px);
}
.process:not(.is-engaged) > * {
  max-width: 1000px;
  margin-left: auto;
  margin-right: auto;
}

/* --- engaged ----------------------------------------------------------- */
.process.is-engaged {
  /* One screen for the stage, plus about 45vh of scroll for each of the
     film's eleven four-second segments (six scenes, five camera moves). */
  height: calc(100vh + 11 * 45vh);
}
.process-stage {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  max-width: 1450px;
  margin: auto;
  padding: 0 clamp(24px, 7vw, 100px);
  box-sizing: border-box;
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  column-gap: 6%;
  align-items: center;
}

/* The track holds the rail and the list, so the rail can be positioned
   against it without putting a non-<li> inside the <ol>. */
.process-track {
  position: relative;
  padding-left: 36px;
}
.is-engaged .process-steps li {
  position: relative;
  grid-template-columns: 44px 1fr;
  row-gap: 3px;
  padding: 13px 0;
  opacity: .42;
  transition: opacity .4s ease;
}
/* Label over description, so the description is not squeezed into a
   narrow third column. */
.is-engaged .process-steps li span {
  grid-column: 2;
}
.is-engaged .process-steps li.is-done   { opacity: .72; }
.is-engaged .process-steps li.is-active { opacity: 1; }

/* The line, stage to stage. enhance.js sets its span from the first dot to
   the last and --flow for how far it has filled. */
.process-rail {
  position: absolute;
  left: 7px;
  width: 2px;
  background: #d2dece;
}
.process-rail::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: calc(var(--flow, 0) * 100%);
  background: var(--green);
}
.is-engaged .process-steps li::after {
  content: "";
  position: absolute;
  left: -35px;
  top: 50%;
  width: 14px;
  height: 14px;
  margin-top: -7px;
  box-sizing: border-box;
  border-radius: 50%;
  background: #ebf1ea;
  border: 2px solid #b6caaf;
  transition: background-color .3s ease, border-color .3s ease, box-shadow .3s ease;
}
.is-engaged .process-steps li.is-done::after,
.is-engaged .process-steps li.is-active::after {
  background: var(--green);
  border-color: var(--green);
}
.is-engaged .process-steps li.is-active::after {
  box-shadow: 0 0 0 6px rgba(85, 114, 76, .2);
}

.process-window {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 10;
  max-height: 74vh;
  overflow: hidden;
  border-radius: 2px;
  background: var(--navy);
  box-shadow: 0 34px 70px -34px rgba(10, 36, 66, .45);
}
.process-film {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.process-caption {
  position: absolute;
  z-index: 10;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 44px 24px 20px;
  display: flex;
  align-items: baseline;
  gap: 14px;
  color: #fff;
  background: linear-gradient(to top, rgba(8, 30, 55, .62), rgba(8, 30, 55, 0));
  pointer-events: none;
}
.process-count {
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .18em;
}
.process-caption strong {
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
}
.process-caption .process-desc {
  display: none;
}

/* ============================================================= connect == */

.connect {
  width: min(680px, calc(100vw - 32px));
  max-height: calc(100dvh - 32px);
  padding: 0;
  border: 0;
  border-radius: 2px;
  background: #fff;
  color: var(--ink);
  box-shadow: 0 40px 90px -30px rgba(8, 30, 55, .55);
  overflow: auto;
}
.connect::backdrop {
  background: rgba(8, 30, 55, .62);
  backdrop-filter: blur(3px);
}
html:has(.connect[open]) {
  overflow: hidden;
}

.connect-inner {
  position: relative;
  padding: 52px clamp(24px, 6vw, 56px) 48px;
}
.connect h2 {
  font-size: clamp(2.1rem, 4vw, 3.1rem);
  margin-bottom: 30px;
}

.connect-fields {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px 28px;
}
.field {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.field-wide {
  grid-column: 1 / -1;
}
.field label {
  font-size: .72rem;
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--navy);
}
.field-note {
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--muted);
}

/* Underlined fields, in the site's hairline idiom. The line is --muted, not
   the pale --line used for decoration: an input's edge has to reach 3:1
   against white to be findable (WCAG 1.4.11), and --line is about 1.3:1. */
.field input,
.field textarea {
  font: inherit;
  font-size: 1rem;
  color: var(--ink);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--muted);
  border-radius: 0;
  padding: 8px 0 10px;
  transition: border-color .2s ease, box-shadow .2s ease;
}
.field textarea {
  min-height: 118px;
  resize: vertical;
  line-height: 1.55;
}
.field input:focus,
.field textarea:focus {
  outline: none;
  border-bottom-color: var(--navy);
  box-shadow: 0 1px 0 0 var(--navy);
}
.field [aria-invalid="true"] {
  border-bottom-color: #a4262c;
  box-shadow: 0 1px 0 0 #a4262c;
}
.field-error {
  color: #a4262c;
  font-size: .85rem;
  line-height: 1.4;
}
.field-error:empty {
  display: none;
}

/* Honeypot: off-screen rather than display:none, which some bots skip. */
.connect-trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.connect-status {
  margin: 24px 0 0;
  color: #a4262c;
  font-size: .95rem;
}
.connect-status:empty {
  display: none;
}

/* The approved .button is styled for links; these are real buttons. */
button.button {
  border: 0;
  cursor: pointer;
  font-family: inherit;
}
button.button[disabled] {
  cursor: progress;
  opacity: .7;
  transform: none;
}
.connect-form .button {
  margin-top: 30px;
}

.connect-done h2 {
  margin-bottom: 12px;
}
.connect-done p:not(.eyebrow) {
  color: var(--muted);
  font-size: 1.1rem;
}
.connect-done .button {
  margin-top: 18px;
}
.connect-done:focus {
  outline: none;
}

.connect-close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--navy);
  font-size: 1.9rem;
  line-height: 1;
  cursor: pointer;
  transition: background-color .2s ease;
}
.connect-close:hover {
  background: #eff4ee;
}
.connect button:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 4px;
}

@media (prefers-reduced-motion: no-preference) {
  .connect[open] {
    animation: ib-rise .45s cubic-bezier(.2, .8, .2, 1);
  }
  .connect[open]::backdrop {
    animation: ib-fade .35s ease;
  }
}

/* ========================================================== breakpoints == */

@media (max-width: 900px) {
  .jennifer-inner {
    grid-template-columns: 1fr;
    row-gap: 48px;
    padding: 70px 7vw;
  }
  .jennifer-photo {
    grid-row: auto;
  }
  .jennifer-portrait {
    position: static;
  }
  .jennifer-portrait figcaption {
    position: static;
  }
  .jennifer-record {
    margin-top: 0;
  }
  .jennifer-copy {
    grid-column: auto;
    grid-row: auto;
  }
  .jennifer-record {
    grid-template-columns: 1fr;
    gap: 26px;
  }
  .jennifer-record div,
  .jennifer-record div:first-child {
    padding: 0 0 0 16px;
    border-left: 2px solid #6b9060;
  }
  .jennifer-focus {
    margin-top: -14px;
  }

  .process:not(.is-engaged) {
    padding: 70px 7vw;
  }

  /* The stage stacks: window on top, then the heading and the six steps
     as labels only. The active step's description rides in the window's
     caption, so the list keeps one height and nothing jumps. */
  .process-stage {
    grid-template-columns: 1fr;
    align-content: center;
    row-gap: 22px;
    padding: 0 24px;
  }
  .process-window {
    order: -1;
    aspect-ratio: 16 / 10;
    max-height: 38vh;
  }
  .process-stage .process-head h2 {
    font-size: clamp(1.9rem, 7vw, 2.6rem);
    margin-bottom: 8px;
  }
  .is-engaged .process-steps li {
    grid-template-columns: 38px 1fr;
    padding: 9px 0;
  }
  .is-engaged .process-steps li span {
    display: none;
  }
  .process-caption {
    flex-wrap: wrap;
    padding: 40px 18px 14px;
    gap: 4px 12px;
  }
  .process-caption .process-desc {
    display: block;
    flex-basis: 100%;
    font-size: .92rem;
    line-height: 1.4;
  }
}

@media (max-width: 600px) {
  .jennifer-inner {
    padding: 65px 24px;
  }
  .process:not(.is-engaged) {
    padding: 70px 24px;
  }
  .process:not(.is-engaged) .process-steps li {
    grid-template-columns: 38px 1fr;
  }
  .process:not(.is-engaged) .process-steps li span {
    grid-column: 2;
  }

  .connect {
    width: 100vw;
    max-width: 100vw;
    height: 100dvh;
    max-height: 100dvh;
    margin: 0;
    border-radius: 0;
  }
  .connect-inner {
    padding: 56px 24px 36px;
  }
  .connect-fields {
    grid-template-columns: 1fr;
  }
}
