/* blocks.css · one section per band kind, plus header, footer and forms.
   Every value is a token. No colour literal appears here. */

/* ================================================================ hero */
.twf-hero { position: relative; overflow: hidden; padding-block: var(--twf-space-band-mobile); }
@media (min-width: 768px) { .twf-hero { padding-block: var(--twf-space-band-tablet); } }
@media (min-width: 1024px) { .twf-hero { padding-block: var(--twf-space-band-desktop); } }

.twf-hero__inner { position: relative; }
.twf-hero__text { position: relative; z-index: 2; }
.twf-hero__sub { margin-top: var(--twf-space-5); }
.twf-hero .twf-btns { margin-top: var(--twf-space-6); }

/* The hero photograph: a radius.md frame, never full bleed, never behind text. */
.twf-hero__graphic { position: relative; margin: var(--twf-space-6) 0 0; }
.twf-hero__graphic .twf-img { aspect-ratio: 4 / 3; object-fit: cover; box-shadow: var(--twf-shadow-card); }
/* An informational graphic keeps its own proportions so its legend stays readable, rather than
   being cropped into the 4:3 photo frame. */
.twf-hero__graphic--contain .twf-img {
  aspect-ratio: auto;
  object-fit: contain;
  background: var(--twf-paper);
  max-height: 620px;
  width: auto;
  max-width: 100%;
  margin-inline: auto;
  padding: var(--twf-space-4);
}
@media (min-width: 1024px) {
  .twf-hero__inner { display: grid; grid-template-columns: repeat(12, 1fr); gap: var(--twf-space-grid-gap-desktop); align-items: center; }
  .twf-hero__text { grid-column: 1 / span 6; }
  .twf-hero__graphic { grid-column: 8 / span 5; margin-top: 0; }
  .twf-hero--text-only .twf-hero__text { grid-column: 1 / span 8; }
  .twf-hero--gradient { min-height: 72vh; display: flex; align-items: center; }
}
/* Home h1 is display-1; every inner page h1 is display-2. */
.twf-hero--display1 h1 { font-size: var(--twf-size-display-1); line-height: var(--twf-line-display-1); letter-spacing: var(--twf-track-display-1); }
.twf-hero--gradient h1 { color: var(--twf-on-dark); }
.twf-hero--gradient .twf-rule--section::after { background: var(--twf-orange); }

/* ================================================================ prose */
.twf-prose__p + .twf-prose__p { margin-top: var(--twf-space-5); }
.twf-band--prose .twf-link { margin-top: var(--twf-space-5); }

/* Two column split, shared by prose, faq and checklist. Heading in columns 1 to 4, content in
   5 to 12. A single 44rem column left 39 percent of the row empty, which read as an unfinished
   page. The body is still capped at the 68ch measure. Stacks below 1024px. */
.twf-prose__split { display: grid; gap: var(--twf-space-grid-gap-mobile); }
@media (min-width: 1024px) {
  .twf-prose__split {
    grid-template-columns: repeat(12, 1fr);
    column-gap: var(--twf-space-grid-gap-desktop);
    row-gap: 0;
    align-items: start;
  }
  .twf-prose__split > .twf-band__head { grid-column: 1 / span 4; margin-bottom: 0; }
  .twf-prose__split > .twf-prose__body,
  .twf-prose__split > .twf-faq,
  .twf-prose__split > .twf-checklist { grid-column: 5 / span 8; }

  /* With an image beside it the text needs the room, so the heading sits above its own column. */
  .twf-prose__split--media { grid-template-areas: "h h h h h h h m m m m m" "b b b b b b b m m m m m"; }
  .twf-prose__split--media > .twf-band__head { grid-area: h; margin-bottom: var(--twf-space-5); }
  .twf-prose__split--media > .twf-prose__body { grid-area: b; }
  .twf-prose__split--media > .twf-prose__media { grid-area: m; }
}
.twf-prose__media { margin: 0; }
.twf-prose__media .twf-img { aspect-ratio: 4 / 3; object-fit: cover; }

/* Contact address block: hairline above and below, DESIGN-INTENT 11. */
.twf-address {
  font-style: normal;
  display: flex;
  flex-direction: column;
  gap: var(--twf-space-2);
  border-top: var(--twf-border-hairline);
  border-bottom: var(--twf-border-hairline);
  padding-block: var(--twf-space-5);
  margin-top: var(--twf-space-5);
}
.twf-address__line { font-size: var(--twf-size-lead); color: var(--twf-ink); text-decoration: none; }
a.twf-address__line { color: var(--twf-blue); font-weight: 600; }
a.twf-address__line:hover { color: var(--twf-blue-deep); }

/* ================================================================ images */
.twf-img { width: 100%; height: auto; border-radius: var(--twf-radius-md); }
.twf-img--fallback { display: grid; place-items: center; padding: var(--twf-space-6); aspect-ratio: 16 / 11; }
.twf-img--fallback .twf-trajectory { width: 100%; }
.twf-img--svg { background: var(--twf-mist); }

.twf-monogram {
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  background: var(--twf-mist);
  border-radius: var(--twf-radius-md);
  font-family: var(--twf-font-display);
  font-weight: 700;
  font-size: var(--twf-size-stat);
  color: var(--twf-blue);
}

/* ================================================================ media band */
.twf-media { margin: 0; }
.twf-media--narrow { width: min(100%, 60%); margin-inline: auto; }
/* Left aligned with every other band (DESIGN-INTENT 2); only the centred certificate keeps
   its caption centred beneath it. */
.twf-media__caption { margin-top: var(--twf-space-4); }
.twf-media--narrow .twf-media__caption { text-align: center; }

/* Partner rows. Six marks were supplied by the client and are used exactly as given; the five
   still outstanding render as the partner's name in the display font, which is the fallback
   IMAGE-CURATION section 6 defines. Both share one tile shape so a part-supplied row still
   reads as a finished wall. */
.twf-logowall {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  /* 1fr on auto rows makes every row match the tallest, so a five line name and a one word
     name sit in identical tiles. AGENTS 6.5: partner marks at equal visual weight. */
  grid-auto-rows: 1fr;
  gap: var(--twf-space-4);
  padding: 0;
  margin: 0;
}
/* Six across put each mark in a 192px column, which left the logos looking like footnotes.
   auto-fit at a 240px floor gives four across on desktop and marks half again as large. */
@media (min-width: 768px) { .twf-logowall { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); } }
@media (min-width: 1024px) { .twf-logowall { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); } }
/* One tile shape for every member, whether it holds a supplied mark or a name. */
.twf-logowall__item {
  position: relative;
  display: grid;
  place-items: center;
  text-align: center;
  min-height: 156px;
  padding: var(--twf-space-5) var(--twf-space-4);
  border-radius: var(--twf-radius-md);
  overflow: hidden;
  transition: background-color var(--twf-duration-fast) var(--twf-ease), opacity var(--twf-duration-fast) var(--twf-ease);
}
/* The supplied marks are white ink on transparent, drawn for a dark ground, so the band they
   sit on is Ink and no mark is ever recoloured. Quiet by default, full strength on hover,
   which is DESIGN-INTENT 2's "grayscale by default, colour on hover" applied to a mono mark. */
.twf-logowall__mark {
  width: 100%;
  max-width: 260px;
  height: auto;
  opacity: 0.9;
  transition: opacity var(--twf-duration-fast) var(--twf-ease);
}
.twf-logowall__item:hover .twf-logowall__mark { opacity: 1; }

/* A name sits on the same ground as a mark, with no box around it. Boxing only the outstanding
   ones made the supplied marks look like they were missing their frame; unboxed, the row reads
   as one wall of wordmarks. */
.twf-logowall__name {
  font-family: var(--twf-font-display);
  font-weight: 700;
  font-size: var(--twf-size-body);
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--twf-on-dark-soft);
  text-wrap: balance;
  transition: color var(--twf-duration-fast) var(--twf-ease);
}
.twf-logowall__name:hover { color: var(--twf-on-dark); }

/* ================================================================ cards */
.twf-cards { display: grid; gap: var(--twf-space-grid-gap-mobile); padding: 0; margin: 0; }
@media (min-width: 768px) {
  .twf-cards { gap: var(--twf-space-grid-gap-desktop); }
  .twf-cards--2up { grid-template-columns: repeat(2, 1fr); }
  .twf-cards--3up { grid-template-columns: repeat(3, 1fr); }
}
.twf-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--twf-space-4);
  padding: var(--twf-space-6);
  border-radius: var(--twf-radius-md);
  background: var(--twf-paper);
  overflow: hidden;
}
/* shadow.card is applied to cards on Mist only; cards on Paper take a hairline instead. */
.twf-card--on-mist { box-shadow: var(--twf-shadow-card); }
.twf-card--on-paper { border: var(--twf-border-hairline); }
.twf-card--on-ink { border: var(--twf-border-hairline); }
/* 4px top rule in that program's section colour. */
.twf-card[style*="--twf-card-rule"]::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 4px;
  background: var(--twf-card-rule);
}
.twf-card__copy { color: var(--twf-ink); margin: 0; }
.twf-card__title { margin: 0; }
.twf-card .twf-link { margin-top: auto; }
.twf-card__media { width: 100%; }
.twf-cards--team .twf-card__media { max-width: 200px; }
.twf-cards--team .twf-card__title { margin-top: var(--twf-space-2); }

/* ================================================================ definitions */
.twf-defs { margin: 0; }
.twf-defs__row {
  display: grid;
  gap: var(--twf-space-2);
  padding-block: var(--twf-space-5);
  border-top: var(--twf-border-hairline);
}
.twf-defs__row:last-child { border-bottom: var(--twf-border-hairline); }
@media (min-width: 768px) {
  .twf-defs__row { grid-template-columns: repeat(12, 1fr); gap: var(--twf-space-grid-gap-desktop); }
  .twf-defs__term { grid-column: 1 / span 4; }
  .twf-defs__copy { grid-column: 5 / span 8; }
}
.twf-defs__term {
  font-family: var(--twf-font-display);
  font-size: var(--twf-size-h3);
  line-height: var(--twf-line-h3);
  font-weight: 700;
  color: var(--twf-blue);
}
.twf-defs__copy { margin: 0; max-width: var(--twf-measure-body); }
.twf-ground-ink .twf-defs__term { color: var(--twf-on-dark); }

/* ================================================================ stats */
.twf-stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0; padding: 0; margin: 0; }
@media (min-width: 768px) {
  .twf-stats--3 { grid-template-columns: repeat(3, 1fr); }
  .twf-stats--4 { grid-template-columns: repeat(4, 1fr); }
  .twf-stats--2 { grid-template-columns: repeat(2, 1fr); }
  .twf-stats--1 { grid-template-columns: 1fr; }
}
.twf-stat {
  display: flex;
  flex-direction: column;
  gap: var(--twf-space-2);
  padding: var(--twf-space-5);
  border-top: var(--twf-border-hairline);
}
@media (min-width: 768px) {
  .twf-stat { border-top: 0; border-left: var(--twf-border-hairline); }
  .twf-stat:first-child { border-left: 0; padding-left: 0; }
}
.twf-stat__value {
  font-family: var(--twf-font-display);
  font-size: var(--twf-size-stat);
  line-height: var(--twf-line-stat);
  letter-spacing: var(--twf-track-stat);
  font-weight: 700;
  color: var(--twf-blue);
}
/* A tile whose value is a phrase rather than a figure. See blocks/stats/render.php. */
.twf-stat--phrase .twf-stat__value {
  font-size: var(--twf-size-h2);
  line-height: var(--twf-line-h2);
  letter-spacing: var(--twf-track-h2);
  text-wrap: balance;
}
.twf-stat__label { font-size: var(--twf-size-small); line-height: var(--twf-line-small); color: var(--twf-ink-soft); }
.twf-ground-ink .twf-stat__value { color: var(--twf-on-dark); }
.twf-ground-ink .twf-stat__label { color: var(--twf-on-dark-soft); }
.twf-ground-ink .twf-stat { border-color: var(--twf-ink-soft); }

/* Home S02 sits on a Paper card overlapping the gradient edge on desktop only.
   On mobile it does not overlap (DESIGN-INTENT 3). */
.twf-band--overlap .twf-stats__card { background: var(--twf-paper); border-radius: var(--twf-radius-md); }
.twf-band--overlap .twf-stats__card .twf-band__head { margin-bottom: var(--twf-space-5); }
@media (min-width: 1024px) {
  .twf-band--overlap { padding-top: 0; }
  .twf-band--overlap .twf-stats__card {
    margin-top: -64px;
    box-shadow: var(--twf-shadow-card);
    padding: var(--twf-space-6) var(--twf-space-7);
    position: relative;
    z-index: 3;
  }
}

/* ================================================================ steps */
.twf-steps { list-style: none; counter-reset: none; padding: 0; margin: 0; display: grid; gap: var(--twf-space-6); }
.twf-step { display: grid; grid-template-columns: auto 1fr; gap: var(--twf-space-5); align-items: start; }
.twf-step__n {
  font-family: var(--twf-font-display);
  font-size: 40px;
  line-height: 1;
  font-weight: 700;
  color: var(--twf-blue);
  min-width: 56px;
}
.twf-ground-ink .twf-step__n { color: var(--twf-on-dark); }
.twf-step__title { margin-bottom: var(--twf-space-2); }
.twf-step__copy { margin: 0; }

/* ================================================================ faq */
.twf-faq { border-top: var(--twf-border-hairline); }
.twf-faq__item { border-bottom: var(--twf-border-hairline); }
.twf-faq__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--twf-space-4);
  padding-block: var(--twf-space-5);
  cursor: pointer;
  list-style: none;
  font-family: var(--twf-font-display);
  font-size: var(--twf-size-h3);
  line-height: var(--twf-line-h3);
  font-weight: 700;
  color: var(--twf-blue);
}
.twf-faq__q::-webkit-details-marker { display: none; }
.twf-faq__marker { position: relative; width: 16px; height: 16px; flex: none; }
.twf-faq__marker::before,
.twf-faq__marker::after {
  content: "";
  position: absolute;
  background: var(--twf-orange);
  transition: transform var(--twf-duration-fast) var(--twf-ease);
}
.twf-faq__marker::before { inset: 7px 0; height: 2px; }
.twf-faq__marker::after { inset: 0 7px; width: 2px; }
.twf-faq__item[open] .twf-faq__marker::after { transform: scaleY(0); }
.twf-faq__a { padding-bottom: var(--twf-space-5); }
.twf-faq__a p { margin: 0; }

/* ================================================================ quote */
.twf-quote { margin: 0; }
@media (min-width: 768px) { .twf-quote { width: 83.333%; margin-inline: auto 0; } }
/* A 48px orange rule above the quote instead of quotation marks. */
.twf-quote::before { content: ""; display: block; width: 48px; height: 3px; background: var(--twf-orange); margin-bottom: var(--twf-space-5); }
.twf-quote__text { margin: 0; }
.twf-quote__text p {
  font-family: var(--twf-font-display);
  font-size: var(--twf-size-quote);
  line-height: var(--twf-line-quote);
  letter-spacing: var(--twf-track-quote);
  font-weight: 500;
  color: var(--twf-on-dark);
  max-width: none;
  margin: 0;
}
.twf-quote__by { margin-top: var(--twf-space-5); font-size: var(--twf-size-small); color: var(--twf-on-dark-soft); }
.twf-ground-paper .twf-quote__text p { color: var(--twf-ink); }
.twf-ground-paper .twf-quote__by, .twf-ground-mist .twf-quote__by { color: var(--twf-ink-soft); }
.twf-ground-mist .twf-quote__text p { color: var(--twf-ink); }

/* ================================================================ credentials */
.twf-creds {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: var(--twf-space-4);
  grid-template-columns: 1fr;
}
@media (min-width: 640px) { .twf-creds { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .twf-creds { grid-template-columns: repeat(3, 1fr); } }
.twf-cred {
  display: flex;
  flex-direction: column;
  gap: var(--twf-space-2);
  padding: var(--twf-space-5);
  background: var(--twf-paper);
  border: var(--twf-border-hairline);
  border-radius: var(--twf-radius-md);
  border-top: 3px solid var(--twf-blue);
  transition: border-color var(--twf-duration-fast) var(--twf-ease), box-shadow var(--twf-duration-fast) var(--twf-ease);
}
.twf-cred:hover { border-top-color: var(--twf-orange); box-shadow: var(--twf-shadow-card); }
.twf-cred__field {
  font-size: var(--twf-size-eyebrow);
  font-weight: 600;
  color: var(--twf-ink-soft);
  margin: 0;
}
.twf-cred__name { font-size: var(--twf-size-h3); line-height: 1.2; margin: 0; }
.twf-cred__copy { font-size: var(--twf-size-small); color: var(--twf-ink); margin: 0; max-width: none; }

/* ================================================================ chips */
.twf-chips { display: flex; flex-wrap: wrap; gap: var(--twf-space-3); padding: 0; margin: 0; }
.twf-chip {
  background: var(--twf-blue-tint);
  color: var(--twf-blue);
  border-radius: var(--twf-radius-pill);
  padding: 0.5rem 1rem;
  font-weight: 600;
  font-size: var(--twf-size-button);
  line-height: 1.2;
}

/* ================================================================ checklist */
.twf-checklist { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--twf-space-4); }
.twf-checklist__item { display: grid; grid-template-columns: auto 1fr; gap: var(--twf-space-4); align-items: start; }
.twf-checklist__tick {
  width: 28px; height: 28px; flex: none;
  display: grid; place-items: center;
  background: var(--twf-green-tint);
  border-radius: var(--twf-radius-pill);
}
.twf-checklist__tick svg { width: 18px; height: 18px; }
.twf-checklist__text { max-width: var(--twf-measure-body); }

/* ================================================================ cta band */
/* The one centred band on a page (DESIGN-INTENT 2). */
.twf-cta { text-align: center; }
.twf-cta > * { margin-inline: auto; }
.twf-band__head--center { display: flex; flex-direction: column; align-items: center; }
.twf-band__head--center h2 { text-align: center; }
.twf-band__head--center .twf-rule::after { left: 50%; transform: translateX(-50%); }
.twf-cta__body { margin-inline: auto; margin-bottom: var(--twf-space-6); }
.twf-cta .twf-btns { justify-content: center; }

/* ================================================================ table */
.twf-table__scroll { overflow-x: auto; }
.twf-table { border-collapse: collapse; width: 100%; font-size: var(--twf-size-small); }
.twf-table th, .twf-table td { text-align: left; padding: var(--twf-space-4); border-bottom: var(--twf-border-hairline); }
.twf-table th { font-family: var(--twf-font-display); color: var(--twf-blue); }

/* ================================================================ header */
.twf-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--twf-paper);
  border-bottom: var(--twf-border-hairline);
  height: var(--twf-header-expanded);
  transition: height var(--twf-duration-fast) var(--twf-ease);
}
.twf-header.is-shrunk { height: var(--twf-header-shrunk); }
.twf-header__inner { display: flex; align-items: center; justify-content: space-between; gap: var(--twf-space-5); height: 100%; }
.twf-header__logo { display: flex; align-items: center; flex: none; }
/* 150% of the original 44px. At 44px the tagline under the wordmark was effectively
   unreadable; at 66px it resolves, and the mark still clears the nav by 480px and fits the
   88px header with 11px above and below. 200% was tested too but needs the header grown to
   104px and starts to compete with the page's own headings. Logged in DECISIONS.md. */
.twf-header__logo img { height: 86px; width: auto; transition: height var(--twf-duration-fast) var(--twf-ease); }
.twf-header.is-shrunk .twf-header__logo img { height: 60px; }

.twf-nav { display: none; }
@media (min-width: 1024px) { .twf-nav { display: flex; align-items: center; gap: var(--twf-space-6); } }
.twf-nav__list { display: flex; align-items: center; gap: var(--twf-space-6); list-style: none; margin: 0; padding: 0; }
.twf-nav__link {
  font-family: var(--twf-font-display);
  font-weight: 500;
  color: var(--twf-blue);
  text-decoration: none;
  padding-block: var(--twf-space-2);
  border-bottom: 2px solid transparent;
}
.twf-nav__link:hover { border-bottom-color: var(--twf-orange); }
.twf-nav__item.is-current > .twf-nav__link { border-bottom-color: var(--twf-green); }

.twf-nav__group { position: relative; }
.twf-nav__toggle {
  display: inline-flex; align-items: center; gap: var(--twf-space-2);
  font-family: var(--twf-font-display); font-weight: 500; color: var(--twf-blue);
  padding-block: var(--twf-space-2); border-bottom: 2px solid transparent;
}
.twf-nav__toggle:hover { border-bottom-color: var(--twf-orange); }
.twf-nav__caret { width: 10px; height: 10px; transition: transform var(--twf-duration-fast) var(--twf-ease); }
.twf-nav__toggle[aria-expanded="true"] .twf-nav__caret { transform: rotate(180deg); }
/* The dropdown sat 12px below the toggle, and that gap was dead space: moving the pointer
   toward the menu left the group, the mouseleave fired, and the menu closed before it could be
   clicked. The panel now starts flush against the toggle and carries the gap as its own top
   padding, so the pointer never crosses a hole. */
.twf-nav__sub {
  position: absolute; top: 100%; left: 0; min-width: 320px;
  padding-top: 12px;
  list-style: none; margin: 0;
  display: none;
}
.twf-nav__sub::before {
  content: "";
  position: absolute;
  inset: 12px 0 0 0;
  background: var(--twf-paper);
  border: var(--twf-border-hairline);
  border-radius: var(--twf-radius-md);
  box-shadow: var(--twf-shadow-card);
}
.twf-nav__sub > li { position: relative; }
.twf-nav__sub > li:first-child { padding-top: var(--twf-space-3); }
.twf-nav__sub > li:last-child { padding-bottom: var(--twf-space-3); }
.twf-nav__group.is-open .twf-nav__sub { display: block; }
.twf-nav__sub a {
  position: relative;
  display: block;
  margin-inline: var(--twf-space-3);
  padding: var(--twf-space-3) var(--twf-space-4);
  border-radius: var(--twf-radius-sm);
  color: var(--twf-blue);
  text-decoration: none;
  font-weight: 500;
}
.twf-nav__sub a:hover { background: var(--twf-blue-tint); }

.twf-burger { display: inline-flex; flex-direction: column; justify-content: center; gap: 5px; width: 44px; height: 44px; align-items: center; }
@media (min-width: 1024px) { .twf-burger { display: none; } }
.twf-burger span { display: block; width: 24px; height: 2px; background: var(--twf-blue); transition: transform var(--twf-duration-fast) var(--twf-ease), opacity var(--twf-duration-fast) var(--twf-ease); }
.twf-burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.twf-burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.twf-burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* Mobile overlay nav, full screen. */
.twf-mobilenav {
  position: fixed; inset: 0; z-index: 60;
  background: var(--twf-paper);
  padding: var(--twf-space-8) var(--twf-space-gutter-mobile) var(--twf-space-6);
  overflow-y: auto;
  display: none;
}
.twf-mobilenav.is-open { display: block; }
@media (min-width: 1024px) { .twf-mobilenav, .twf-mobilenav.is-open { display: none; } }
.twf-mobilenav__list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--twf-space-2); }
.twf-mobilenav__list a {
  display: block; padding: var(--twf-space-4) 0;
  font-family: var(--twf-font-display); font-size: var(--twf-size-h3); font-weight: 700;
  color: var(--twf-blue); text-decoration: none; border-bottom: var(--twf-border-hairline);
}
.twf-mobilenav__label { font-size: var(--twf-size-eyebrow); font-weight: 600; color: var(--twf-ink-soft); padding-top: var(--twf-space-5); }
.twf-mobilenav__sub { list-style: none; margin: 0; padding-left: var(--twf-space-5); }
.twf-mobilenav__sub a { font-size: var(--twf-size-body); font-weight: 500; }
.twf-mobilenav .twf-btn { margin-top: var(--twf-space-6); width: 100%; }
.twf-mobilenav__close { position: absolute; top: var(--twf-space-5); right: var(--twf-space-gutter-mobile); }

/* ================================================================ footer */
.twf-footer { background: var(--twf-paper); border-top: var(--twf-border-hairline); }
.twf-footer__cols { display: grid; gap: var(--twf-space-7); padding-block: var(--twf-space-8); }
@media (min-width: 768px) { .twf-footer__cols { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .twf-footer__cols { grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: var(--twf-space-6); } }
.twf-footer__brand img { width: 140px; height: auto; }
.twf-footer__tagline { font-family: var(--twf-font-display); font-weight: 500; color: var(--twf-blue); margin-top: var(--twf-space-4); }
.twf-footer__about { font-size: var(--twf-size-small); color: var(--twf-ink-soft); margin-top: var(--twf-space-3); }
.twf-footer__title { font-family: var(--twf-font-display); font-size: var(--twf-size-h3); font-weight: 700; color: var(--twf-blue); margin-bottom: var(--twf-space-4); }
.twf-footer__list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--twf-space-3); }
.twf-footer__list a, .twf-footer__list span { font-size: var(--twf-size-small); color: var(--twf-ink-soft); text-decoration: none; }
.twf-footer__list a:hover { color: var(--twf-blue); }
.twf-social { display: flex; gap: var(--twf-space-3); margin-top: var(--twf-space-5); }
.twf-social a { display: grid; place-items: center; width: 40px; height: 40px; border: var(--twf-border-hairline); border-radius: var(--twf-radius-pill); color: var(--twf-blue); }
.twf-social a:hover { background: var(--twf-blue-tint); }
.twf-social svg { width: 18px; height: 18px; }

.twf-footer__bar { background: var(--twf-ink); color: var(--twf-on-dark-soft); }
.twf-footer__bar-inner { display: flex; flex-direction: column; gap: var(--twf-space-2); padding-block: var(--twf-space-5); font-size: var(--twf-size-small); }
@media (min-width: 768px) { .twf-footer__bar-inner { flex-direction: row; justify-content: space-between; align-items: center; } }

/* ================================================================ article body */
/* Long form editorial. Measure is capped at the body measure AGENTS 5 requires, and the column
   sits at the left of the content container so it lines up with every other band. */
.twf-article { max-width: var(--twf-measure-body); }
.twf-article > * + * { margin-top: var(--twf-space-5); }
.twf-article p { max-width: none; }
/* Band headings are capped at 22ch so a marketing headline breaks in a controlled place.
   An article subhead is a sentence, not a headline, and that cap made it wrap mid-phrase. */
.twf-article h2, .twf-article h3, .twf-article h4 { max-width: none; }
.twf-article h2 {
  font-size: var(--twf-size-h2);
  line-height: var(--twf-line-h2);
  letter-spacing: var(--twf-track-h2);
  margin-top: var(--twf-space-7);
  position: relative;
  padding-bottom: 15px;
}
.twf-article h2::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 48px;
  height: 3px;
  background: var(--twf-orange);
}
.twf-article h3 { font-size: var(--twf-size-h3); margin-top: var(--twf-space-6); }
.twf-article__list { list-style: none; padding: 0; display: grid; gap: var(--twf-space-4); }
.twf-article__list li { position: relative; padding-left: var(--twf-space-6); }
.twf-article__list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.6em;
  width: 10px;
  height: 3px;
  background: var(--twf-orange);
}
/* A policy table is wider than a phone. It scrolls inside its own box rather than pushing the
   page sideways. */
.twf-article__tablewrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.twf-article__tablewrap table { min-width: 34rem; }
.twf-article__olist { padding-left: var(--twf-space-6); display: grid; gap: var(--twf-space-3); }
.twf-article strong { font-weight: 600; color: var(--twf-ink); }
.twf-article a { color: var(--twf-blue); font-weight: 600; }
.twf-article blockquote {
  margin: 0;
  padding-left: var(--twf-space-5);
  border-left: 3px solid var(--twf-orange);
}
.twf-article blockquote p { font-size: var(--twf-size-lead); color: var(--twf-ink-soft); }

/* Post meta: date and byline. */
.twf-postmeta__author { font-weight: 600; color: var(--twf-blue); }
.twf-postlist__meta { font-size: var(--twf-size-small); color: var(--twf-ink-soft); }

/* ================================================================ 404 and news */
.twf-404 { text-align: left; }
/* The post list uses the same two column rhythm as the definitions and prose bands: date and
   byline on columns 1 to 3, the title and opening line on 4 to 12. A single narrow column left
   the right half of the row empty. */
.twf-postlist { list-style: none; margin: 0; padding: 0; border-top: var(--twf-border-hairline); }
.twf-postlist__item {
  display: grid;
  gap: var(--twf-space-3);
  padding-block: var(--twf-space-6);
  border-bottom: var(--twf-border-hairline);
}
@media (min-width: 768px) {
  .twf-postlist__item {
    grid-template-columns: repeat(12, 1fr);
    column-gap: var(--twf-space-grid-gap-desktop);
    align-items: start;
  }
  .twf-postlist__meta { grid-column: 1 / span 3; }
  .twf-postlist__body { grid-column: 4 / span 9; }
}
.twf-postlist__date { font-size: var(--twf-size-small); color: var(--twf-ink-soft); }
.twf-postlist__byline { font-size: var(--twf-size-small); color: var(--twf-blue); font-weight: 600; margin-top: var(--twf-space-1); }
/* A list title is a full headline, not a band heading, so it is not capped at 22ch. */
.twf-postlist__title { margin-bottom: var(--twf-space-3); max-width: none; }
.twf-postlist__title a { color: var(--twf-blue); text-decoration: none; }
.twf-postlist__title a:hover { color: var(--twf-blue-deep); }
.twf-postmeta { font-size: var(--twf-size-small); color: var(--twf-ink-soft); margin-top: var(--twf-space-4); }

/* ================================================================ forms */
.twf-forms { display: grid; gap: var(--twf-space-5); }
.twf-formtabs { display: flex; flex-wrap: wrap; gap: var(--twf-space-3); border-bottom: var(--twf-border-hairline); padding-bottom: var(--twf-space-4); }
.twf-formtab {
  font-family: var(--twf-font-body); font-weight: 600; font-size: var(--twf-size-small);
  padding: var(--twf-space-3) var(--twf-space-4); border-radius: var(--twf-radius-pill);
  color: var(--twf-blue); background: var(--twf-blue-tint);
}
.twf-formtab[aria-selected="true"] { background: var(--twf-blue); color: var(--twf-on-dark); }
.twf-formpanel[hidden] { display: none; }

/* Ninja Forms restyled with tokens. DESIGN-INTENT 11. */
.nf-form-cont .nf-field-label label { font-weight: 600; font-size: var(--twf-size-small); color: var(--twf-ink); }
.nf-form-cont input[type="text"], .nf-form-cont input[type="email"], .nf-form-cont input[type="tel"],
.nf-form-cont textarea, .nf-form-cont select {
  width: 100%;
  min-height: 48px;
  padding: var(--twf-space-3) var(--twf-space-4);
  border: var(--twf-border-hairline);
  border-radius: var(--twf-radius-sm);
  background: var(--twf-paper);
  color: var(--twf-ink);
  font-size: var(--twf-size-body);
}
.nf-form-cont textarea { min-height: 140px; }
.nf-form-cont input:focus, .nf-form-cont textarea:focus, .nf-form-cont select:focus { border-color: var(--twf-blue); }
.nf-form-cont .nf-error-msg, .nf-error-msg, .nf-form-cont .nf-error .nf-error-msg {
  color: var(--twf-ink);
  background: var(--twf-orange-tint);
  border-left: var(--twf-border-rule-accent);
  padding: var(--twf-space-3) var(--twf-space-4);
  font-size: var(--twf-size-small);
  border-radius: 0;
}
.nf-form-cont .nf-error input, .nf-form-cont .nf-error textarea, .nf-form-cont .nf-error select { border-color: var(--twf-orange); }
.nf-form-cont input[type="button"], .nf-form-cont input[type="submit"], .nf-form-cont button[type="submit"] {
  background: var(--twf-blue);
  color: var(--twf-on-dark);
  border: 0;
  border-radius: var(--twf-radius-pill);
  padding: 0.875rem 1.5rem;
  font-weight: 600;
  cursor: pointer;
}
.nf-form-cont input[type="button"]:hover { background: var(--twf-blue-deep); }
.nf-response-msg, .nf-form-cont .nf-response-msg {
  background: var(--twf-green-tint);
  border-left: 3px solid var(--twf-green-deep);
  padding: var(--twf-space-4);
  color: var(--twf-ink);
}
/* Ninja Forms paints the required asterisk #E80000, which is both outside the token palette and
   a red. AGENTS 4: red appears only in the logo, never as a text, alert or validation colour.
   TWF Blue is used instead: it is a token, it measures 9.34:1 on Paper, and requirement is also
   carried by the `required` attribute and by the sentence above the fields, so colour is never
   the only signal. */
.nf-form-cont .ninja-forms-req-symbol,
.nf-form-cont .ninja-forms-req-symbol * {
  color: var(--twf-blue);
}
.nf-form-cont .nf-form-fields-required { color: var(--twf-ink-soft); font-size: var(--twf-size-small); }

/* Honeypot. Never shown, never announced. */
.twf-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* ================================================================ contact layout */
/* The details block and the three forms share one band: details on columns 1 to 4, forms on
   6 to 12. Ninja Forms renders its own full width wrapper, which previously ran the fields the
   whole width of the viewport; the grid column is what contains it. DESIGN-INTENT 11. */
.twf-prose__split--address { display: grid; gap: var(--twf-space-7); }
@media (min-width: 1024px) {
  .twf-prose__split--address {
    grid-template-columns: repeat(12, 1fr);
    column-gap: var(--twf-space-grid-gap-desktop);
    /* The 3rem stack gap is for the mobile layout, where the forms sit under the details.
       On desktop they are side by side, so the heading should sit close to its own address. */
    row-gap: 0;
    align-items: start;
  }
  .twf-prose__split--address > .twf-contact__mark,
  .twf-prose__split--address > .twf-band__head,
  .twf-prose__split--address > .twf-prose__body { grid-column: 1 / span 4; }
  .twf-prose__split--address > .twf-band__head { margin-bottom: var(--twf-space-4); }
  .twf-contact__forms { grid-column: 6 / span 7; grid-row: 1 / span 4; }
}
.twf-contact__mark { width: 132px; height: auto; margin-bottom: var(--twf-space-5); }

.twf-contact__forms {
  background: var(--twf-mist);
  border-radius: var(--twf-radius-md);
  padding: var(--twf-space-6);
}
@media (min-width: 768px) { .twf-contact__forms { padding: var(--twf-space-7); } }
/* Ninja Forms lays its own grid out at 100vw unless the container holds it. */
.twf-contact__forms .nf-form-cont,
.twf-contact__forms .nf-form-layout,
.twf-contact__forms .nf-form-content { max-width: 100%; padding: 0; }
.twf-contact__forms .nf-field-container { margin-bottom: var(--twf-space-5); }

/* ================================================================ map */
.twf-map { line-height: 0; }
.twf-map__frame { display: block; width: 100%; height: 500px; border: 0; }
@media (max-width: 767px) { .twf-map__frame { height: 340px; } }


/* ---------------------------------------------------------------------------------------------
 * A post written in the block editor
 *
 * The eleven generated posts carry their own band, container and .twf-article inside the post
 * content. A post the client writes from scratch has none of those, so functions.php adds
 * .twf-article to it — and this supplies what the missing band and container would have given it:
 * the page gutter and the vertical breathing room. Scoped to --bare so the generated posts, whose
 * wrappers already do this, are untouched.
 * ------------------------------------------------------------------------------------------ */
.twf-article--bare {
  margin-inline: auto;
  padding-block: var(--twf-space-8);
  padding-inline: var(--twf-gutter);
}
