/* Team Building Co, pre-launch page.
   Page-level rules only. Every value is lifted from the design system components
   in _ref/team-building-co-design-system/project/, which ship no CSS of their own.
   Tokens come from styles.css. Nothing here redefines a token.

   Dark mode is opt-in through data-tbc-theme="dark" on <html> and nothing else.
   Never bind it to prefers-color-scheme. */

/* ---------- layout, from ui_kits/website/index.html ---------- */

.wrap {
  max-width: var(--w);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

section {
  padding: var(--section-y) 0;
  border-top: var(--border-width-hairline) solid var(--thread);
}

/* The header is sticky at 76px, so an anchored section must clear it. */
section[id] { scroll-margin-top: 76px; }

.band {
  background: var(--surface-band);
}

.skip {
  position: absolute;
  left: -9999px;
}

.skip:focus {
  position: fixed;
  left: var(--space-5);
  top: var(--space-5);
  z-index: 50;
  background: var(--sand);
  color: var(--wool);
  padding: var(--space-3) var(--space-5);
  border: var(--border-width-button) solid var(--wool);
  border-radius: var(--r-chip);
  text-decoration: none;
}

/* ---------- lockup, from assets/logo-lockup.svg ----------
   "Team" and the three figure units on the top line, "Building Co" beneath, so the
   mark fills the space above "ing" and the block reads as one shape. The middle
   figure is the only red. Never reflow the two lines into one, never separate the
   units from "Team", and never recolour the type.

   The artwork is the outlined lockup, not live type, because this page loads its
   fonts from a CDN with no self-hosted fallback. If that request fails, live type
   sets "Building" about 17% wider and it overruns "Co". The ink group inherits
   currentColor so the mark still follows the ink tokens in dark mode. */

.sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

.lockup {
  display: block;
  width: auto;
  color: var(--wool);
}

.lockup-link {
  display: inline-flex;
  text-decoration: none;
  color: var(--wool);
}

.lockup-header { height: 38px; }

/* The header mark is hidden only while the hero lockup is on screen, so the brand is
   not shown twice at the top of the page. The class is added by the script at the foot
   of index.html, so with no JavaScript the mark is simply always visible.
   visibility, not display, so the nav does not shift when it goes.
   No transition, no fade: the brand allows no scroll-triggered animation. */
.site-header.hero-mark-visible .lockup-header {
  visibility: hidden;
}

/* Matches the design system's 64px hero lockup, which stands about 123px tall. */
.lockup-hero {
  height: clamp(62px, 9vw, 123px);
  margin-bottom: 18px;
}

/* ---------- monogram, from assets/logo-monogram.svg ----------
   The lockup's three linked figures, middle one red. Same traced artwork as the
   lockup, so the figures stay distinct rather than one shape repeated. Neither
   monogram on this page is a link, so the hover moment from the design system
   does not apply here. */

.monogram {
  display: block;
  height: auto;
  color: var(--wool);
}

/* ---------- weave, from components/brand/Weave.jsx ---------- */

.weave {
  position: relative;
  overflow: hidden;
  background: var(--sand);
}

.weave > svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.tbc-thread-draw path {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: tbc-draw var(--dur-thread) var(--ease-thread) forwards;
}

@keyframes tbc-draw {
  to { stroke-dashoffset: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .tbc-thread-draw path { animation: none; stroke-dashoffset: 0; }
}

/* ---------- buttons, from components/core/Button.jsx ---------- */

.btn {
  font-family: var(--display);
  font-weight: var(--weight-heading);
  font-size: 17px;
  line-height: 1.1;
  padding: var(--space-4) 22px;
  border-radius: var(--r-chip);
  border: var(--border-width-button) solid var(--wool);
  background: var(--wool);
  color: var(--sand);
  display: inline-flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--dur-hover) linear, border-color var(--dur-hover) linear, color var(--dur-hover) linear;
}

.btn-primary {
  background: var(--action-primary);
  border-color: var(--action-primary);
  color: var(--text-on-red);
}

.btn-primary:hover,
.btn-primary:active {
  background: var(--action-primary-hover);
  border-color: var(--action-primary-hover);
  color: var(--text-on-red);
}

.btn-ghost {
  background: transparent;
  color: var(--wool);
  border-color: var(--wool);
}

.btn-ghost:hover {
  background: var(--sand-deep);
  color: var(--wool);
}

.btn-ghost-dark {
  background: transparent;
  color: var(--sand);
  border-color: var(--sand);
}

.btn-ghost-dark:hover {
  background: rgba(251, 250, 247, .14);
  color: var(--sand);
}

.btn-sm {
  font-size: var(--size-ui);
  padding: 10px var(--space-5);
}

/* Disabled, from Button.jsx. Used in the interface previews, where a button is
   part of the designed screen but must not look clickable. */
.btn-disabled {
  background: var(--sand-deep);
  border-color: var(--thread);
  color: var(--chalk);
  cursor: not-allowed;
}

@media (prefers-reduced-motion: reduce) {
  .btn { transition: none; }
}

/* ---------- header ---------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--surface-page);
  border-bottom: var(--border-width-hairline) solid var(--thread);
}

.site-header .wrap {
  min-height: 76px;
  display: flex;
  align-items: center;
  gap: var(--space-7);
}

.site-nav {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 22px;
}

.site-nav a:not(.btn) {
  font-size: var(--size-ui);
  font-weight: var(--weight-medium);
  color: var(--text-lede);
  text-decoration: none;
}

.site-nav a:not(.btn):hover {
  color: var(--wool);
  text-decoration: underline;
  text-underline-offset: 2px;
}

@media (max-width: 640px) {
  .site-nav a:not(.btn) { display: none; }
  .site-header .wrap { gap: var(--space-4); }
}

/* ---------- hero ---------- */

.hero {
  position: relative;
  overflow: hidden;
  min-height: min(78vh, 720px);
  display: flex;
  border-top: 0;
  padding: 0;
}

.hero-inner {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: var(--w);
  margin: 0 auto;
  padding: clamp(40px, 8vw, 120px) var(--gutter) clamp(28px, 4vw, 56px);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: flex-start;
}

.hero-card {
  background: var(--surface-card);
  display: inline-block;
  padding: clamp(18px, 2.5vw, 32px) clamp(20px, 3vw, 36px) clamp(20px, 2.5vw, 30px);
  max-width: min(100%, 780px);
  border-top: 6px solid var(--red);
}

.hero-card h1 {
  font-size: clamp(32px, 4.4vw, 60px);
  letter-spacing: -.025em;
  font-stretch: 110%;
}

.lede {
  font-size: var(--size-lede);
  color: var(--text-lede);
  max-width: 44ch;
  margin: var(--space-5) 0 0;
}

/* ---------- where we are ----------
   A sand-deep band directly under the hero carrying the one paragraph about timing,
   so the pitch above stays clean. The label is the red mono numeral style, the date
   beneath it in chalk. Delete the section at launch and the hero is untouched. */

.where-band {
  padding: var(--space-8) 0;
  border-top: 0;
}

/* The red rule sits on the hero card's left edge, and the text is inset by the card's
   own padding, so the paragraph lines up with the headline in the card above it. */
.note.where-note {
  margin: 0;
  max-width: none;
  background: transparent;
  padding: 4px 0 4px calc(clamp(20px, 3vw, 36px) - 3px);
}

.where-label {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-4);
  margin-bottom: var(--space-3);
}

.where-label .step-n { margin: 0; display: inline; }

.where-date {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--text-meta-deep, var(--wool-2));
}

.where-note p {
  margin: 0;
  max-width: 68ch;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-7);
}

/* ---------- section headings and grids ---------- */

.section-head {
  max-width: 62ch;
}

.section-head h2 { text-wrap: balance; }

/* pretty keeps a lone word off the last line where the browser supports it. */
.section-head p {
  font-size: var(--size-lede);
  color: var(--text-lede);
  margin: var(--space-5) 0 0;
  max-width: 56ch;
  text-wrap: pretty;
}

.grid {
  display: grid;
  gap: var(--grid-gap);
  margin-top: var(--space-8);
  grid-template-columns: 1fr;
}

/* Explicit column counts, not auto-fit. auto-fit picks whatever happens to fit, which
   put the 4 item grids on 3 columns between 820px and 1030px and left one orphan on a
   second row. Both grids only ever use counts that divide their item count evenly:
   6 items go 1, 2 or 3 across, 4 items go 1, 2 or 4. */

@media (min-width: 560px) {
  .grid-6 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 880px) {
  .grid-6 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (min-width: 520px) {
  .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 1080px) {
  .grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.item {
  border-top: var(--border-width-hairline) solid var(--thread);
  padding-top: var(--space-5);
}

.item h3 {
  margin: 0 0 var(--space-2);
}

.item p {
  font-size: var(--size-ui);
  color: var(--text-lede);
  margin: 0;
}

.step-n {
  display: block;
  font-family: var(--mono);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  color: var(--red);
  margin-bottom: var(--space-2);
}

/* ---------- the promise ----------
   One brief, one price, one team on site. A sand card with the hero's red top rule,
   the statement large on the left, the paragraph and button on the right. The label
   is chalk, because the rule and the button already spend the red allowance. */

.promise {
  background: var(--surface-card);
  border-top: 6px solid var(--red);
  padding: clamp(24px, 3vw, 40px) clamp(20px, 3vw, 36px) clamp(28px, 3vw, 40px);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  gap: var(--space-8);
  align-items: end;
}

.promise-label {
  display: flex;
  gap: var(--space-4);
  font-family: var(--mono);
  font-size: 13px;
  color: var(--text-meta);
  margin-bottom: var(--space-4);
}

.promise-big {
  font-size: clamp(32px, 4.2vw, 56px);
  line-height: 1.02;
  letter-spacing: -.025em;
  margin: 0;
}

.promise-body p {
  font-size: var(--size-lede);
  color: var(--text-lede);
  margin: 0;
  max-width: 40ch;
}

.promise-body .actions { margin-top: var(--space-6); }

@media (max-width: 860px) {
  .promise { grid-template-columns: 1fr; gap: var(--space-6); align-items: start; }
}

/* ==========================================================================
   Interface preview
   Static recreations of the designed screens, built from the design system
   components rather than screenshotted, so they stay sharp, respond to width
   and follow the ink tokens. No prices anywhere: publishing price bands is
   still an open decision, and the sample figures are invented.
   ========================================================================== */

/* Every preview section shares one structure: the screen on the left, a 300px
   column of supporting cards on the right, so the four sections read as a set. */
.preview-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-7);
  align-items: start;
  margin-top: var(--space-8);
}

@media (min-width: 900px) {
  .preview-grid { grid-template-columns: minmax(0, 1fr) 300px; }
}

.aside-stack {
  display: grid;
  gap: var(--space-5);
}

.aside-card {
  border: var(--border-width-hairline) solid var(--thread);
  border-radius: var(--r-card);
  padding: var(--space-6);
  background: var(--surface-card);
}

.aside-card h3 { margin: 0 0 10px; }

.aside-card ul,
.aside-card ol {
  font-size: var(--size-ui);
  color: var(--text-lede);
  padding-left: var(--space-6);
  margin: 0;
  display: grid;
  gap: var(--space-2);
}

.aside-card p {
  font-size: var(--size-ui);
  color: var(--text-lede);
  margin: 0;
}

.aside-quiet {
  background: transparent;
  border-color: transparent;
  padding-top: 0;
  padding-bottom: 0;
}

.aside-quiet p { color: var(--text-meta-deep, var(--wool-2)); }

/* Numbered steps in an aside: red mono numeral, bold title, one line under it. */
.steps {
  list-style: none;
  padding-left: 0 !important;
  gap: var(--space-4) !important;
}

.steps li {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: 10px;
  align-items: baseline;
}

.steps .step-n { margin: 0; grid-row: span 2; }
.steps strong { color: var(--wool); font-weight: var(--weight-semibold); }
.steps li > span:last-child { grid-column: 2; }

/* The legend repeats the agenda's 4px left edge, so the rule is shown, not told. */
.legend {
  list-style: none;
  padding-left: 0 !important;
}

.legend li {
  display: flex;
  align-items: center;
  gap: 12px;
}

.legend i {
  display: inline-block;
  width: var(--edge-width);
  height: 22px;
  background: var(--chalk);
  flex: none;
}

.legend i[data-type="activity"]    { background: var(--edge-activity); }
.legend i[data-type="hospitality"] { background: var(--edge-hospitality); }
.legend i[data-type="corporate"]   { background: var(--edge-corporate); }
.legend i[data-type="transport"]   { background: var(--edge-transport); }

/* A small tag in the corner of a recreated screen, so nobody mistakes it for
   the live product. Mono, chalk, no border. */
.preview-tag {
  position: absolute;
  top: 14px;
  right: 16px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--text-meta);
  letter-spacing: 0;
}

/* ---------- reveal ----------
   A fourth motion moment, not sanctioned by the design system, taken as a
   decision. The class is only ever added by the script, and only when the
   visitor has not asked for reduced motion, so the no-JavaScript page and the
   reduced-motion page never hide anything. */
.reveal {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 550ms var(--ease-thread), transform 550ms var(--ease-thread);
}

.reveal.is-in {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
}

/* ---------- chip, from components/core/Chip.jsx ---------- */

.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 7px 12px;
  border: var(--border-width-card) solid var(--wool);
  border-radius: var(--r-chip);
  font-family: var(--body);
  font-weight: var(--weight-medium);
  font-size: var(--size-ui);
  line-height: 1.2;
  color: var(--wool);
  background: transparent;
  user-select: none;
}

/* Hover is colour only, never scale and never shadow. */
.chip[aria-pressed="false"]:hover { background: var(--sand-deep); }

.chip[aria-pressed="true"] {
  background: var(--wool);
  color: var(--sand);
}

/* The four mode chips select in oasis, everything else in wool. */
.chip-oasis[aria-pressed="true"] {
  background: var(--oasis);
  border-color: var(--oasis);
  color: var(--text-on-oasis);
}

/* ---------- builder, from ui_kits/website/Builder.jsx ---------- */

.builder {
  position: relative;
  background: var(--surface-card);
  border: var(--border-width-card) solid var(--wool);
  border-radius: var(--r-card);
  padding: clamp(20px, 3vw, 32px);
}

.builder-rows {
  display: grid;
  gap: var(--space-6);
}

.builder-row-head {
  display: flex;
  gap: 10px;
  align-items: baseline;
  margin-bottom: 10px;
}

.builder-row-head .n {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--text-meta);
}

.builder-row-head .q {
  font-family: var(--display);
  font-weight: var(--weight-heading);
  font-size: 18px;
}

.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.builder-foot {
  margin-top: var(--space-7);
  padding-top: var(--space-6);
  border-top: var(--border-width-hairline) solid var(--thread);
  display: flex;
  gap: var(--space-6);
  align-items: center;
  flex-wrap: wrap;
}

.builder-foot .kicker {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--text-meta);
}

/* Body face, not mono. Mono carries figures, times and references, never a
   sentence. The live builder shows a number here; this preview shows none. */
.builder-foot .value {
  font-size: var(--size-lede);
  margin-top: 2px;
}

.builder-foot .btn { margin-left: auto; }

/* ---------- note, from components/core/Note.jsx ---------- */

.note {
  padding: var(--space-5) var(--space-6);
  border-left: 3px solid var(--red);
  background: var(--surface-note);
  border-radius: 0 var(--r-chip) var(--r-chip) 0;
  max-width: var(--measure);
  color: var(--text-body);
  font-size: var(--size-ui);
}

.note-oasis {
  border-left-color: var(--oasis);
  background: var(--surface-validation);
}

/* ---------- agenda, from components/agenda/AgendaBlock.jsx ---------- */

/* The note spans the board, not the 62ch measure, so their right edges line up. */
.preview-grid .note { max-width: none; }

.agenda-board {
  border: var(--border-width-card) solid var(--wool);
  border-radius: var(--r-card);
  overflow: hidden;
  background: var(--surface-card);
}

/* Grip, time, name, in that order. The price column of the real editor is
   deliberately dropped here. */
.agenda-block {
  display: grid;
  grid-template-columns: 14px 64px minmax(0, 1fr);
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  border-top: var(--border-width-hairline) solid var(--thread);
  border-left: var(--edge-width) solid var(--chalk);
  align-items: center;
  font-family: var(--body);
}

.agenda-block:first-child { border-top: 0; }

/* Left edge carries the module type, never used decoratively. */
.agenda-block[data-type="activity"]    { border-left-color: var(--edge-activity); }
.agenda-block[data-type="hospitality"] { border-left-color: var(--edge-hospitality); }
.agenda-block[data-type="corporate"]   { border-left-color: var(--edge-corporate); }
.agenda-block[data-type="transport"]   { border-left-color: var(--edge-transport); }
.agenda-block[data-type="logistics"]   { border-left-color: var(--edge-logistics); }

/* The drag grip is CSS, not an icon. The brand draws no icons. */
.agenda-block .grip {
  width: 14px;
  height: 22px;
  background: radial-gradient(circle, var(--chalk) 1.4px, transparent 1.6px) 0 0 / 7px 7px;
  justify-self: start;
}

.agenda-block .time {
  font-family: var(--mono);
  font-size: 14px;
  font-variant-numeric: tabular-nums;
  color: var(--text-meta);
}

.agenda-block .name { font-weight: var(--weight-semibold); }

.agenda-block .meta {
  font-size: 14px;
  color: var(--text-meta);
}

/* A validation note tints the row and darkens the meta ink, because chalk is
   only 3.8:1 on the oasis-soft ground. */
.agenda-block.has-note {
  background: var(--surface-validation);
}

.agenda-block.has-note .time,
.agenda-block.has-note .meta {
  color: var(--wool-2);
}

.agenda-block .block-note {
  font-size: 14px;
  color: var(--wool-2);
  margin-top: var(--space-1);
}

/* Rows respond to the pointer in colour only. A row with a note keeps its tint. */
.agenda-block:not(.has-note):hover { background: var(--sand-deep); }

/* ---------- module card, from components/agenda/ModuleCard.jsx ----------
   The media slot is never a photo here and never a grey box. Until a real
   photo exists every 4:3 slot carries the fine weave at 0.35 on sand-deep.
   The card has no type colour: that belongs to the agenda block only. */

.module-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--grid-gap);
  margin-top: var(--space-8);
}

.module-card {
  border: var(--border-width-card) solid var(--wool);
  border-radius: var(--r-card);
  overflow: hidden;
  background: var(--surface-card);
  font-family: var(--body);
  display: flex;
  flex-direction: column;
}

/* A photograph or the weave, same slot either way. object-fit keeps a photo at 4:3
   without distortion, and the sand-deep ground shows while it loads. */
.module-media {
  aspect-ratio: 4 / 3;
  background: var(--surface-band);
  display: block;
  width: 100%;
  height: auto;
  object-fit: cover;
}

/* The body grows to fill the card and pins the meta row to the bottom, so a
   title that wraps to 2 lines does not push its meta out of line with the rest. */
.module-body {
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  flex: 1;
}

.module-body h3 { margin: 0 0 6px; text-wrap: balance; }

.module-body p {
  font-size: var(--size-ui);
  margin: 0;
  color: var(--text-lede);
  max-width: none;
}

.module-meta {
  display: flex;
  gap: var(--space-4);
  flex-wrap: wrap;
  font-family: var(--mono);
  font-size: 13px;
  color: var(--text-meta);
  margin-top: auto;
  padding-top: 12px;
  font-variant-numeric: tabular-nums;
}

/* Cards sit on a sand-deep band, where chalk drops to 3.88:1. */
.band .module-meta { color: var(--text-meta-deep, var(--wool-2)); }

/* ---------- report ----------
   Invented. The design system has no report screen, only the promise copy,
   so this is assembled from approved strings and existing components. */

.report {
  position: relative;
  border: var(--border-width-card) solid var(--wool);
  border-radius: var(--r-card);
  background: var(--surface-card);
  padding: clamp(20px, 3vw, 32px);
}

.report .ref {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--text-meta);
}

.report h3 { margin: var(--space-2) 0 0; }

.report p { margin: 10px 0 0; }

/* Galleries are grids: 1.5px wool border, 12px radius, 16px gap, the same tile
   as a card's media area. No lightbox, no carousel, no arrows. */
.photo-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-5);
  margin-top: var(--space-6);
}

.photo-grid .module-media {
  border: var(--border-width-card) solid var(--wool);
  border-radius: var(--r-card);
}

.report-foot {
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: var(--border-width-hairline) solid var(--thread);
  font-family: var(--mono);
  font-size: 13px;
  color: var(--text-meta);
}

/* ---------- inverted board, from components/core/InvertedBoard.jsx ---------- */

.board {
  background: var(--surface-inverted);
  color: var(--text-inverted);
  border-radius: var(--r-card);
  padding: clamp(24px, 4vw, 40px);
  overflow: hidden;
  font-family: var(--body);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-8);
  align-items: center;
}

/* The monogram column is 220px fixed, so it only earns its place once the text column
   still has room to breathe beside it. */
@media (min-width: 860px) {
  .board { grid-template-columns: 1.3fr minmax(0, 1fr); }
}

.board h2 {
  font-size: clamp(28px, 3.4vw, 44px);
  color: var(--text-inverted);
}

.board p {
  color: var(--text-lede-inverted);
  max-width: 44ch;
  margin: var(--space-5) 0 0;
}

/* Inverted ground, so the ink group takes sand. The middle figure stays red. */
.board .monogram {
  width: 150px;
  max-width: 100%;
  justify-self: start;
  color: var(--sand);
}

@media (min-width: 860px) {
  .board .monogram { width: 220px; justify-self: end; }
}

/* ---------- footer ---------- */

.site-footer {
  background: var(--surface-inverted);
  color: var(--text-inverted);
  padding: var(--space-9) 0 var(--space-10);
  border-top: 0;
}

.footer-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-9);
}

@media (min-width: 900px) {
  .footer-grid {
    grid-template-columns: 1.4fr minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--space-8);
  }
}

.site-footer .monogram { width: 120px; color: var(--sand); }

.site-footer p {
  font-size: var(--size-ui);
  color: var(--text-lede-inverted);
  margin: var(--space-5) 0 0;
}

/* The blurb under the monogram sets as 2 lines of even length, not a line and a stub. */
.footer-grid > div:first-child > p {
  max-width: 44ch;
  text-wrap: balance;
}

.site-footer h2 {
  font-size: var(--size-h3);
  font-family: var(--display);
  font-weight: var(--weight-heading);
  color: var(--text-inverted);
  margin: 0 0 var(--space-4);
}

.footer-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-3);
}

.footer-list a,
.site-footer a {
  color: var(--text-inverted);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.site-footer a:hover {
  color: var(--text-lede-inverted);
}

.footer-meta {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--text-meta-inverted);
  font-variant-numeric: tabular-nums;
  display: grid;
  gap: var(--space-3);
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Bottom bar, aligned with Food Truck Lab: copyright left, the Project Hospitality mark
   centred, the attribution link right. Typography stays Team Building Co's own, so
   sentence case and mono, never FTL's tracked-out caps. */

.footer-bottom {
  margin-top: var(--space-9);
  padding-top: var(--space-6);
  border-top: var(--border-width-hairline) solid var(--hairline-inverted);
  font-family: var(--mono);
  font-size: 13px;
  color: var(--text-meta-inverted);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-6);
  align-items: center;
}

@media (min-width: 860px) {
  .footer-bottom { grid-template-columns: 1fr auto 1fr; }
  .footer-bottom > :last-child { justify-self: end; text-align: right; }
}

/* The mark is black artwork on transparency. The footer ground is wool, so it is
   inverted to read white. In dark mode wool becomes the light value, so the filter
   comes off and the artwork stays black. */
.phs-mark {
  display: block;
  height: 30px;
  width: auto;
  filter: invert(1);
  opacity: .82;
}

:root[data-tbc-theme="dark"] .phs-mark {
  filter: none;
}

.footer-bottom a {
  color: var(--text-meta-inverted);
  text-decoration: none;
}

.footer-bottom a:hover {
  color: var(--text-inverted);
  text-decoration: underline;
  text-underline-offset: 2px;
}


/* Focus ring needs to stay visible on the wool ground. */
.site-footer :focus-visible,
.board :focus-visible {
  outline-color: var(--sand);
}
