/* Hub page (/hub until cutover, D53). Lifted from the Sep 26 design
   handoff, design/handoff/2026-09-26-hub/, revised from the Sep 28
   handoff, design/handoff/2026-09-28-hub-revision/ (hero copy widths,
   the context header bar, the recomposed open cards, D68 to D72). The
   boards' inline pixel literals, clamps and radii are the design and are
   kept as exported; every board style became a hub- class here. Colors
   are tokens only. The few alpha literals below have no token form and
   each names its derivation.

   The hero is the canonical hero water surface (design system section 06).
   .hero-panel.hero-panel--water in global.css owns the panel's background,
   position and overflow; this sheet supplies radius, padding, color and
   type through the one-class selector .hub-hero and never overrides the
   background. Never write a compound selector for the hero: at equal or
   higher specificity a later sheet beats the canonical block and nothing
   warns (GOTCHAS, the modifier-versus-base entry). site-plan.css, which
   carries the .hero-panel base rule, is not loaded on this page.

   Container queries: the boards size the hero padding, the hero heading and
   the address input with cqw units. Every cqw declaration has a plain
   fallback on the line before it, which a browser without container units
   keeps. */

/* ── Page column ─────────────────────────────────────────────── */

.hub-main {
  max-width: 992px;
  margin: 0 auto;
  padding: 24px 16px 0;
  display: flex;
  flex-direction: column;
  gap: 24px;
}

/* Retired share-link notice (D54). Unboarded: a quiet full-width line.
   No display value here, so the hidden attribute keeps it out of the
   column until the fragment handler removes it. */
.hub-checklist-notice {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r);
  padding: 12px 16px;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--text-2);
}

/* ── Hero ────────────────────────────────────────────────────── */

.hub-hero-wrap {
  container-type: inline-size;
  width: 100%;
}

.hub-hero {
  margin: 0;
  border-radius: var(--r-lg);
  padding: clamp(26px, 4.2vw, 44px) clamp(20px, 3.8vw, 36px) clamp(22px, 3.4vw, 32px);
  padding: clamp(26px, 4.2cqw, 44px) clamp(20px, 3.8cqw, 36px) clamp(22px, 3.4cqw, 32px);
  display: flex;
  flex-direction: column;
  gap: 20px;
  color: var(--white);
}

.hub-hero-head {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* Italic Fraunces comes from the h1 base rule in global.css. */
.hub-hero-title {
  color: var(--white);
  font-size: clamp(24px, 3.4vw, 30px);
  font-size: clamp(24px, 3.4cqw, 30px);
  line-height: 1.25;
  letter-spacing: -.4px;
  max-width: 640px;
  margin: 0;
  text-wrap: balance;
}

/* One sentence (hub spec section 1, Oct 6 2026); no max-width. */
.hub-hero-sub {
  font-size: 14.5px;
  line-height: 1.6;
  /* White at .88 on the pool-deep hero. */
  color: rgba(255,255,255,.88);
}

/* No max-width: the line sets on one line at desktop widths. */
.hub-hero-note {
  /* White at .18: the hairline over the independence line. */
  border-top: 1px solid rgba(255,255,255,.18);
  padding-top: 16px;
  font-size: 13.5px;
  line-height: 1.6;
  /* White at .88 on the pool-deep hero. */
  color: rgba(255,255,255,.88);
}

/* Phone hero (Oct 6 2026, hub spec section 1). Under 632px (the hero
   at 599px under the column's 16px sides, the breakpoint the context
   bar uses) the headline holds one line, sized from the hero's width
   (the line measures 14.2 em in Fraunces italic; 15 leaves room for the
   browser's optical size), and the gaps tighten, so the hero takes
   under a third of the screen. The wording is the same at every
   width. */
@media (max-width: 631px) {
  .hub-hero {
    padding: 20px 20px 16px;
    gap: 12px;
  }
  .hub-hero-head { gap: 10px; }
  .hub-hero-title {
    white-space: nowrap;
    font-size: calc((100vw - 72px) / 15);
    font-size: min(24px, calc((100cqw - 40px) / 15));
    text-wrap: nowrap;
  }
  .hub-hero-sub {
    font-size: 14px;
    line-height: 1.5;
  }
  /* One line from 360px up: the line runs 23.6 em in DM Sans, so it
     scales between 11px and 12.5px with the hero's width (24.5 leaves
     room); below about 340px it wraps rather than shrink further. */
  .hub-hero-note {
    padding-top: 10px;
    font-size: 12.5px;
    font-size: clamp(11px, calc((100cqw - 40px) / 24.5), 12.5px);
    line-height: 1.45;
  }
}

/* ── Context header: the project bar (D72) ───────────────────── */

.hub-context {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
  position: relative;
}

/* The bar: a surface in the card family, 66px tall at every state at
   the content width. The min-height holds through the neutral state,
   so resolving changes no geometry. */
.hub-context-bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px 16px;
  padding: 12px 24px;
  min-height: 66px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
}

.hub-context-eyebrow {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--pool-dark);
}

.hub-project-line {
  font-size: 13px;
  color: var(--text-2);
}

/* Neutral holding state: the line keeps its space and stays unseen until
   hub.js resolves the visitor's state. A no-script visitor gets it back
   through the <noscript> style in hub.njk. */
[data-hub-state="neutral"] .hub-project-line {
  visibility: hidden;
}

.hub-header-actions {
  margin-left: auto;
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
}

/* Below 600px of header width the row's content drops under the eyebrow
   and actions row and takes the full width. The component uses
   @container (max-width: 599px); the build uses a media query at the
   viewport width where the header reaches 599px under the column's
   16px side padding. */
@media (max-width: 631px) {
  .hub-context-bar .hub-project-line {
    order: 3;
    flex-basis: 100%;
  }
}

/* A paused property check (Oct 7 2026, option B). The bar carries it:
   the status pill in the actions slot, then the address, what happened
   and the way on across the full width. Photos back: an amber edge and
   the amber Confirm my property; still out: a grey edge, the grey
   pill, and Start on Step 2 meanwhile. */
.hub-pause {
  order: 3;
  flex-basis: 100%;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.hub-pause[hidden] { display: none; }
.hub-pause-address {
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
}
.hub-pause-text {
  font-size: 13px;
  line-height: 1.45;
  color: var(--text-2);
}
.hub-pause-action,
.hub-pause-onward {
  margin-top: 8px;
  align-self: flex-start;
}
.hub-pause-action[hidden],
.hub-pause-onward[hidden] { display: none; }
.hub-pause-onward {
  font-size: 14px;
  font-weight: 600;
  color: var(--pool-dark);
  border: 1px solid var(--pool-deep);
  border-radius: var(--r);
  padding: 10px 16px;
  text-decoration: none;
}
.hub-pause-pill {
  font-size: 11.5px;
  font-weight: 600;
  border-radius: var(--r-pill);
  padding: 3px 10px;
  color: var(--text-2);
  background: var(--surface-2);
  white-space: nowrap;
}
[data-imagery-pause] .hub-context-bar { padding-top: 14px; padding-bottom: 16px; }
[data-imagery-pause="back"] .hub-context-bar {
  border: 1.5px solid var(--sun);
  box-shadow: 0 2px 10px rgba(212, 137, 42, .18);
}
[data-imagery-pause="back"] .hub-pause-pill {
  color: var(--priority-text);
  background: var(--priority-bg);
}
[data-imagery-pause="still"] .hub-context-bar { border: 1.5px solid var(--border-2); }
@media (max-width: 631px) {
  .hub-pause-action,
  .hub-pause-onward { align-self: stretch; text-align: center; }
}

/* The bar's local-work line and Start over (D93, D99, D103). In the
   anonymous local-work states the line is the address as typed with its
   place, 15/600 in --text as the paused bar sets it; Start over is a
   quiet text control at the far right of the actions slot. Its
   confirmation swaps the bar's content in place: the ruled line, then
   Delete it in the urgent ink and Keep it where Start over was. Never
   the amber fill (D45). At 960 the bar stays 66px. */
.hub-project-line--local {
  font-size: 15px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--text);
}
/* Focus lands on the cleared line when the control that held it goes;
   the line is no control, so it draws no ring. */
.hub-project-line:focus {
  outline: none;
}
.hub-start-over,
.hub-clear-keep,
.hub-clear-yes {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  box-sizing: border-box;
  margin: 0;
  font-family: inherit;
  font-size: 12.5px;
  white-space: nowrap;
  cursor: pointer;
}
.hub-start-over,
.hub-clear-keep {
  padding: 0 6px;
  border: 0;
  background: none;
  font-weight: 500;
  color: var(--text-2);
}
.hub-start-over:hover {
  color: var(--text);
}
.hub-clear-keep {
  padding: 0 8px;
  font-weight: 600;
  color: var(--pool-dark);
}
.hub-clear-yes {
  padding: 0 14px;
  border: 1px solid var(--urgent-text);
  border-radius: var(--r);
  background: var(--surface);
  font-weight: 600;
  color: var(--urgent-text);
}
.hub-start-over:focus-visible,
.hub-clear-keep:focus-visible,
.hub-clear-yes:focus-visible {
  outline: 2px solid var(--teal-border);
  outline-offset: 2px;
}
.hub-start-over[hidden],
.hub-clear-keep[hidden],
.hub-clear-yes[hidden],
.hub-clear-text[hidden] {
  display: none;
}
.hub-clear-yes[disabled],
.hub-clear-keep[disabled] {
  opacity: .6;
  cursor: default;
}

/* Save project (D44, D81, D109), signed out, before Start over: the
   Oct 18 board's quiet underlined control (hub-bar-address-1280). */
.hub-save-project {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  box-sizing: border-box;
  margin: 0;
  padding: 0 6px;
  border: 0;
  background: none;
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
  white-space: nowrap;
  color: var(--pool-dark);
  text-decoration: underline;
  text-decoration-color: var(--teal-border);
  text-underline-offset: 3px;
  cursor: pointer;
}
.hub-save-project:hover {
  text-decoration-color: var(--pool);
}
.hub-save-project:focus-visible,
.hub-bar-signin:focus-visible {
  outline: 2px solid var(--teal-border);
  outline-offset: 2px;
}
.hub-save-project[hidden],
.hub-bar-signin[hidden] {
  display: none;
}

/* Signed in, the saved state beside Account (the Sep 26 board's chip
   label); a failed save says so in the quieter ink. */
.hub-saved {
  padding: 0 4px;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: .04em;
  white-space: nowrap;
  color: var(--pool-dark);
}
.hub-saved--failed {
  letter-spacing: 0;
  font-size: 12px;
  font-weight: 500;
  color: var(--text-2);
}

/* Sign in in the bar (the Sep 26 board's known-device and signed-out
   states): the teal button, in for the nav's (D45). */
.hub-bar-signin {
  padding: 8px 16px;
  min-height: 40px;
  font-size: 12.5px;
}

/* Signed in (the Apple slice, D108): Account at the far right of the
   actions slot, a pill in the project chip's construction, and the
   account popover of the Sep 26 board (header-account-popover-*-928),
   right-aligned under it. */
.hub-account {
  position: relative;
}
.hub-account-button {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  box-sizing: border-box;
  margin: 0;
  padding: 0 14px;
  background: var(--surface);
  border: 1px solid var(--teal-border);
  border-radius: var(--r-pill);
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--text);
  white-space: nowrap;
  cursor: pointer;
}
.hub-account-button:hover,
.hub-account-button[aria-expanded="true"] {
  border-color: var(--pool);
}
.hub-account-panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: 280px;
  max-width: calc(100vw - 32px);
  box-sizing: border-box;
  padding: 14px 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r);
  box-shadow: 0 8px 24px rgba(4, 62, 72, .14);
  text-align: left;
}
.hub-account-panel[hidden] {
  display: none;
}
.hub-account-who {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.hub-account-eyebrow {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--pool-dark);
}
.hub-account-email {
  font-size: 13px;
  color: var(--text);
  overflow-wrap: anywhere;
}
.hub-account-via {
  font-size: 11.5px;
  color: var(--text-2);
}
.hub-account-signout {
  width: 100%;
  min-height: 40px;
  margin: 0;
  padding: 9px 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  font-family: inherit;
  font-size: 12.5px;
  color: var(--text-2);
  text-align: left;
  cursor: pointer;
}
.hub-account-signout:hover {
  color: var(--text);
  border-color: var(--border-2);
}
.hub-account-signout[disabled] {
  opacity: .6;
  cursor: default;
}
.hub-account-error {
  font-size: 12px;
  line-height: 1.5;
  color: var(--priority-text);
}
.hub-account-error[hidden] {
  display: none;
}
.hub-account-danger {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}
.hub-account-delete {
  min-height: 40px;
  margin: 0;
  padding: 0;
  background: none;
  border: none;
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--urgent-text);
  text-align: left;
  cursor: pointer;
}
.hub-account-note {
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-2);
}
.hub-account-button:focus-visible,
.hub-account-signout:focus-visible,
.hub-account-delete:focus-visible {
  outline: 2px solid var(--teal-border);
  outline-offset: 2px;
}
.hub-clear-text {
  flex: 1 1 0;
  min-width: 0;
  font-size: 13px;
  line-height: 1.45;
  color: var(--text);
  text-wrap: pretty;
}
[data-start-over="confirm"] .hub-header-actions {
  justify-content: flex-end;
}
/* On a phone (D103) the eyebrow and the address read as one block with
   Start over beside it, so the bar is as tall as the first visit's; the
   confirmation puts its line under the eyebrow and its buttons on a row
   of their own, right-aligned. */
@media (max-width: 631px) {
  [data-local-work] .hub-context-bar {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "eyebrow actions" "line actions";
    column-gap: 12px;
    row-gap: 2px;
    align-items: center;
  }
  /* Set line heights keep the block under Start over's 40px, so the bar
     stays 66px. */
  [data-local-work] .hub-context-eyebrow {
    grid-area: eyebrow;
    align-self: end;
    line-height: 1.4;
  }
  [data-local-work] .hub-context-bar .hub-project-line {
    grid-area: line;
    align-self: start;
  }
  [data-local-work] .hub-header-actions {
    grid-area: actions;
    margin-left: 0;
  }
  /* More than one thing in the slot (Save project and Start over; signed
     in, the saved state, Start over and Account): beside them the address
     would wrap, so the eyebrow and the slot share the first row and the
     address takes the second, across the width, as the Oct 18 board drew
     it with Save project (D109; D103's one row holds Start over alone). */
  [data-local-work][data-bar-many]:not([data-start-over="confirm"]) .hub-context-bar {
    grid-template-areas: "eyebrow actions" "line line";
    row-gap: 0;
  }
  [data-local-work][data-bar-many]:not([data-start-over="confirm"]) .hub-context-eyebrow {
    align-self: center;
  }
  [data-start-over="confirm"] .hub-context-bar {
    grid-template-areas: "eyebrow eyebrow" "text text" "actions actions";
    row-gap: 4px;
  }
  [data-start-over="confirm"] .hub-clear-text {
    grid-area: text;
  }
  [data-start-over="confirm"] .hub-header-actions {
    margin-top: 6px;
  }
}

/* ── Cards, shared by all seven ──────────────────────────────── */

.hub-open-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 16px;
}

.hub-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
  width: 100%;
}

/* Amber edges are exclusive to the open cards (D49). */
.hub-card--open {
  border-top: 3px solid var(--sun);
  /* --pool-deep at 10%. */
  box-shadow: 0 8px 24px rgba(4,62,72,.10);
}

.hub-card-head--open {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}

.hub-card-head--wrap {
  flex-wrap: wrap;
}

.hub-card-head-main {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}

.hub-card-head--coming {
  display: grid;
  grid-template-columns: 38px minmax(0,1fr) auto;
  column-gap: 12px;
  align-items: start;
}

/* Badge geometry is uniform across all seven cards (hub spec section 2). */
.hub-badge {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  font-size: 15px;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.hub-badge--open {
  background: var(--pool);
  color: var(--white);
}

.hub-badge--coming {
  border: 1px solid var(--border-2);
  background: var(--surface);
  color: var(--text-2);
}

.hub-card-title {
  font-size: 21px;
  line-height: 1.25;
  margin-top: 6px;
  min-width: 0;
}

.hub-card-lede {
  font-size: 14px;
  line-height: 1.6;
  color: var(--text-2);
}

/* ── Step 1 card ─────────────────────────────────────────────── */

/* The card's flexible element (D69): beside the taller Step 2 card in
   the open-cards row it grows to the row height, so the two cards end
   level; at one-column widths the card is content height and the slot
   returns to its 150px basis. */
.hub-art {
  position: relative;
  box-sizing: border-box;
  min-height: 150px;
  margin-top: 2px;
  flex: 1 0 150px;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  overflow: hidden;
}

/* The drawing stays 150px tall and centers in whatever height the slot
   has; the slice preserveAspectRatio crops its width. */
.hub-art-svg {
  position: absolute;
  left: 0;
  top: 50%;
  width: 100%;
  height: 150px;
  margin-top: -75px;
}

.hub-art-north {
  position: absolute;
  right: 10px;
  top: 10px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  font-family: 'DM Mono', monospace;
  font-size: 9px;
  line-height: 1;
  color: var(--text-2);
  /* White at .88 over the art. */
  background: rgba(255,255,255,.88);
  padding: 3px 5px 2px;
  border-radius: 3px;
}

.hub-art-strip {
  position: absolute;
  left: 10px;
  bottom: 10px;
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: 'DM Mono', monospace;
  font-size: 10px;
  letter-spacing: .04em;
  color: var(--text-2);
  /* White at .88 over the art. */
  background: rgba(255,255,255,.88);
  padding: 2px 6px;
  border-radius: 3px;
}

.hub-art-tag {
  font-size: 8.5px;
  font-weight: 600;
  letter-spacing: .06em;
  padding: 1px 5px;
  border-radius: 3px;
  background: var(--surface-2);
  color: var(--text-2);
  border: 1px solid var(--border);
}

/* A finished plan in the slot (D95, D96, D97): the view composed for
   the card at Finish fills it; cover keeps the view's center, where the
   pool sits, in the middle of the slot at every height. The north arrow
   stays above it; the example's drawing and strip leave. */
.hub-art-plan {
  display: none;
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

.hub-art--plan .hub-art-plan {
  display: block;
}

.hub-art--plan .hub-art-svg,
.hub-art--plan .hub-art-strip {
  display: none;
}

/* "Finished Oct 16" on the plan, the Oct 16 board's label. */
.hub-art-finished {
  position: absolute;
  left: 10px;
  top: 10px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .02em;
  padding: 3px 8px;
  border-radius: var(--r-pill);
  background: var(--pool-light);
  color: var(--pool-dark);
  white-space: nowrap;
}

.hub-art-finished[hidden] {
  display: none;
}

/* The lede and the labelled lines as one group. */
.hub-card-body {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
}

/* Labelled lines (D69, D70): one construction on both open cards. The
   label is visible text, uppercased here, never a pseudo-element. */
.hub-lines {
  display: grid;
  grid-template-columns: 84px minmax(0, 1fr);
  column-gap: 10px;
  row-gap: 7px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-2);
}

.hub-line-label {
  font-family: 'DM Mono', monospace;
  font-size: 10px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--pool-dark);
  padding-top: 3px;
}

.hub-line-text {
  text-wrap: pretty;
}

.hub-card-foot {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: auto;
  padding-top: 6px;
}

/* The CTA's lead-in line: Step 1's merged time line above the address
   entry, Step 2's payoff above the (future) button. */
.hub-card-lead-in {
  font-size: 12.5px;
  font-weight: 500;
  color: var(--text-2);
}

.hub-address-wrap {
  container-type: inline-size;
  width: 100%;
}

.hub-address {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
}

.hub-address-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.hub-input {
  min-width: 0;
  min-height: 44px;
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  font-family: 'DM Sans', sans-serif;
  font-size: 14.5px;
  color: var(--text);
  background: var(--surface);
}

.hub-input:focus-visible {
  outline: none;
  border-color: var(--teal-border);
  /* --teal-border at 35%: the focus ring. */
  box-shadow: 0 0 0 3px rgba(168,221,228,.35);
}

/* The address basis grows as the card narrows, so the ZIP and the button
   drop to a second row before the address field gets cramped. */
.hub-input--address {
  flex: 999 1 170px;
  flex: 999 1 clamp(170px, 900px - 200cqw, 320px);
}

.hub-input--zip {
  flex: 0 0 96px;
  width: 96px;
}

/* Unboarded: the field a validation error points at. */
.hub-input.invalid {
  border-color: var(--urgent-text);
}

.hub-find {
  flex: 1 0 auto;
  min-height: 44px;
  padding: 10px 18px;
  font-size: 13.5px;
  white-space: nowrap;
}

.hub-find:focus-visible {
  outline: 2px solid var(--teal-border);
  outline-offset: 2px;
}

/* Unboarded: one inline line under the row. */
.hub-address-error {
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--urgent-text);
}

.hub-address-note {
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text-2);
}

/* Progress block (D78), lifted from step1-card-address-confirmed-472
   and step1-card-drawn-472 without the "Open the site plan" button. It
   renders from the project object once an address is confirmed; the
   address entry stays beneath it until the Step 1 revision. Spacing and
   radius in tokens; type sizes and the 26px icon disc are the board's
   own, as elsewhere in this file (no type tokens exist). */
.hub-progress {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) calc(var(--sp-3) + var(--sp-1) / 2);
  margin-top: var(--sp-1);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
}

.hub-progress[hidden] {
  display: none;
}

.hub-progress-icon {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--pool-light);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.hub-progress-icon path {
  fill: var(--teal-border);
}

[data-project-step1="finished"] .hub-progress-icon path {
  fill: var(--pool);
}

.hub-progress-text {
  min-width: 0;
  flex: 1;
}

.hub-progress-title {
  font-size: 13px;
  font-weight: 600;
  line-height: 1.4;
  color: var(--pool-dark);
}

.hub-progress-sub {
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--text-2);
  overflow-wrap: anywhere;
}

/* A finished plan (D97): "Open the site plan" takes the address entry's
   place, so Find your lot, which starts the drawing over, never sits one
   tap from the plan. The row's class pair outranks .hub-cta-row's flex,
   which comes later in this file. */
.hub-cta-row.hub-open-row {
  display: none;
}

[data-project-step1="drawn"] .hub-cta-row.hub-open-row,
[data-project-step1="finished"] .hub-cta-row.hub-open-row {
  display: flex;
}

/* A drawn plan comes back too (D109): the same control, onto the drawing. */
[data-project-step1="drawn"] .hub-address-wrap,
[data-project-step1="finished"] .hub-address-wrap {
  display: none;
}

/* The merged time line shows on a first visit only, as boarded; the
   progress states carry no time line (handoff open item 7). */
[data-project-step1="address"] .hub-card-lead-in--time,
[data-project-step1="drawn"] .hub-card-lead-in--time,
[data-project-step1="finished"] .hub-card-lead-in--time {
  display: none;
}

/* ── Step 2 card ─────────────────────────────────────────────── */

/* Two stacked halves at reading size (D70). */
.hub-halves {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding-top: 2px;
}

.hub-half {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
}

/* The half headings are the card's only rules. */
.hub-half-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--border);
}

.hub-half-num {
  font-family: 'DM Mono', monospace;
  font-size: 11px;
  color: var(--pool);
}

.hub-half-label {
  font-family: 'Fraunces', serif;
  font-size: 16px;
  line-height: 1.3;
  letter-spacing: -.3px;
  color: var(--forest);
}

.hub-half-value {
  font-size: 14px;
  line-height: 1.55;
  color: var(--text);
  text-wrap: pretty;
}

.hub-half-promise {
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text-2);
  padding-top: 4px;
  text-wrap: pretty;
}

.hub-half-text {
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-2);
  text-wrap: pretty;
}

/* The CTA row (D70), as boarded: the button block under the payoff
   line, nothing beneath it. The button is an <a> carrying .btn-primary
   (global.css) for the amber fill; .hub-cta adds the board's sizes and
   undoes the base anchor styling, hover included, which outranks
   .btn-primary's color on :hover. It points at the /contractors
   holding page until the Step 2 build replaces that page in place
   (D73). */
.hub-cta-row {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}

.hub-cta,
.hub-cta:hover {
  color: var(--white);
  text-decoration: none;
}

.hub-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  min-height: 44px;
  padding: 11px 18px;
  font-size: 13.5px;
}

.hub-cta:focus-visible {
  outline: 2px solid var(--teal-border);
  outline-offset: 2px;
}

/* ── Coming section ──────────────────────────────────────────── */

.hub-coming {
  display: flex;
  flex-direction: column;
  gap: 20px;
  width: 100%;
  min-width: 0;
  margin-top: 8px;
}

.hub-divider {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding-top: 8px;
}

.hub-divider-row {
  display: flex;
  align-items: center;
  gap: 16px;
}

.hub-divider-title {
  font-size: 24px;
  line-height: 1.2;
  flex: none;
}

.hub-divider-rule {
  flex: 1;
  height: 2px;
  background: var(--forest);
}

.hub-divider-sub {
  font-size: 14px;
  line-height: 1.6;
  color: var(--text-2);
  max-width: 640px;
}

/* Pairs at the 960px content width (3/4, 5/6, 7 alone in the left cell);
   one column at phone widths. */
.hub-coming-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 400px), 1fr));
  gap: 16px;
  align-items: stretch;
}

/* Status token (D52): text, not a control. */
.hub-pill {
  margin-top: 8px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .02em;
  padding: 3px 9px;
  border-radius: var(--r-pill);
  background: var(--pool-light);
  color: var(--pool-dark);
  line-height: 1.5;
  white-space: nowrap;
}

/* ── Teasers ─────────────────────────────────────────────────── */

.hub-teaser {
  position: relative;
  display: flex;
  gap: 12px;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  flex: 1;
  margin-top: 2px;
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
  border-radius: var(--r);
}

.hub-teaser::-webkit-scrollbar {
  display: none;
}

.hub-teaser:focus-visible {
  outline: 2px solid var(--teal-border);
  outline-offset: 2px;
}

/* Set by hub.js during a mouse drag: the slides follow the pointer, and
   snapping is off until the drag settles on a slide. */
.hub-teaser.is-dragging {
  cursor: grabbing;
  scroll-snap-type: none;
}

/* The next slide peeks 28px at the right edge. */
.hub-slide {
  flex: 0 0 calc(100% - 40px);
  scroll-snap-align: start;
  box-sizing: border-box;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r);
  padding: 16px;
  min-height: 236px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
}

.hub-slide-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  flex-wrap: wrap;
}

.hub-slide-title {
  font-family: 'Fraunces', serif;
  font-size: 16px;
  line-height: 1.3;
  letter-spacing: -.3px;
  color: var(--forest);
}

.hub-slide-caption {
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-2);
  margin-top: auto;
  padding-top: 4px;
}

.hub-dots {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 44px;
  margin: -18px 0 -18px;
}

.hub-dot {
  width: 30px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
}

.hub-dot:focus-visible {
  outline: 2px solid var(--teal-border);
  outline-offset: 2px;
}

.hub-dot-mark {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--border-2);
  transition: background .2s ease;
}

.hub-dot[aria-current="true"] .hub-dot-mark {
  width: 7px;
  height: 7px;
  background: var(--pool);
}

/* Step 4 pointer to the live calculator (D56, rulings.md 9). A pointer,
   not an ask: no button, no amber, no pill. */
.hub-pointer {
  border-top: 1px solid var(--border);
  padding-top: 12px;
  margin-top: 6px;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--text-2);
}

.hub-pointer-link {
  position: relative;
  color: var(--pool-dark);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* Enlarged hit area, as boarded. */
.hub-pointer-link::before {
  content: '';
  position: absolute;
  inset: -14px -6px;
}

.hub-pointer-link:hover {
  color: var(--pool);
}

.hub-pointer-link:focus-visible {
  outline: 2px solid var(--teal-border);
  outline-offset: 2px;
}

/* ── Teaser slide contents, shared ───────────────────────────── */

.hub-stack {
  display: flex;
  flex-direction: column;
}

.hub-min0 {
  min-width: 0;
}

.hub-strong {
  font-weight: 600;
  color: var(--text);
}

.hub-muted {
  color: var(--text-2);
}

.hub-tag-mono {
  font-family: 'DM Mono', monospace;
  font-size: 10px;
  letter-spacing: .04em;
  color: var(--text-2);
  white-space: nowrap;
}

.hub-fine {
  font-size: 11.5px;
  line-height: 1.4;
  color: var(--text-2);
}

/* A bulleted line: the questions each quote raises, what each flag means. */
.hub-point {
  display: flex;
  gap: 9px;
  padding: 7px 0;
  border-top: 1px solid var(--border);
  font-size: 12.5px;
  line-height: 1.45;
}

.hub-point-mark {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--pool);
  margin-top: 7px;
  flex-shrink: 0;
}

.hub-statement {
  font-family: 'Fraunces', serif;
  font-size: 18px;
  line-height: 1.3;
  letter-spacing: -.3px;
  color: var(--forest);
}

.hub-statement-note {
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--text-2);
}

.hub-eyebrow {
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--pool-dark);
}

/* ── Step 3 teaser: quote comparison ─────────────────────────── */

.hub-doc {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 6px 0;
  border-top: 1px solid var(--border);
}

.hub-doc-icon {
  width: 28px;
  height: 34px;
  flex-shrink: 0;
  border: 1px solid var(--border-2);
  border-radius: 3px;
  background: var(--surface);
  padding: 6px 5px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.hub-doc-line {
  height: 2px;
  background: var(--border);
  border-radius: 1px;
}

.hub-doc-line--w100 {
  width: 100%;
  background: var(--border-2);
}

.hub-doc-line--w70 {
  width: 70%;
}

.hub-doc-line--w85 {
  width: 85%;
}

.hub-doc-line--w55 {
  width: 55%;
}

.hub-doc-text {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.hub-doc-name {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text);
  line-height: 1.35;
}

.hub-doc-meta {
  font-family: 'DM Mono', monospace;
  font-size: 10px;
  letter-spacing: .04em;
  color: var(--pool-dark);
}

.hub-table {
  font-size: 10.5px;
  line-height: 1.35;
}

.hub-table-row {
  display: grid;
  grid-template-columns: minmax(0,1.4fr) repeat(3, minmax(0,1fr));
  column-gap: 6px;
  border-top: 1px solid var(--border);
  padding: 5px 0;
  font-weight: 400;
}

.hub-table-row--head {
  border-top: none;
  padding: 0 0 5px;
  color: var(--text-2);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .02em;
  align-items: end;
}

.hub-table-row--total {
  font-weight: 600;
}

.hub-cell-label {
  color: var(--text);
}

.hub-num {
  color: var(--text);
  font-style: normal;
  font-variant-numeric: tabular-nums;
}

/* A line the quote does not mention: gray, never a zero. */
.hub-num--missing {
  color: var(--text-3);
  font-style: italic;
}

/* ── Step 4 teaser: financing ────────────────────────────────── */

.hub-options {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.hub-option {
  flex: 1 1 150px;
  min-width: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.hub-option-name {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text);
}

.hub-option-amount {
  font-family: 'Fraunces', serif;
  font-size: 20px;
  line-height: 1.2;
  letter-spacing: -.3px;
  color: var(--forest);
  margin-top: 4px;
}

.hub-rates {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-top: 4px;
}

.hub-rate-row {
  display: grid;
  grid-template-columns: 38px minmax(0,1fr) 42px;
  align-items: center;
  gap: 10px;
  font-size: 12px;
}

.hub-rate {
  font-family: 'DM Mono', monospace;
  font-size: 11px;
  color: var(--text-2);
}

.hub-bar {
  height: 9px;
  background: var(--pool-light);
  border-radius: var(--r-pill);
  overflow: hidden;
}

.hub-bar-fill {
  height: 100%;
  background: var(--pool);
  border-radius: var(--r-pill);
}

.hub-bar-fill--85 {
  width: 85%;
}

.hub-bar-fill--90 {
  width: 90%;
}

.hub-bar-fill--96 {
  width: 96%;
}

.hub-rate-pay {
  font-variant-numeric: tabular-nums;
  color: var(--text);
  text-align: right;
  font-weight: 500;
}

.hub-from-tag {
  align-self: flex-start;
  font-family: 'DM Mono', monospace;
  font-size: 10px;
  letter-spacing: .04em;
  color: var(--pool-dark);
}

/* ── Step 5 teaser: contract review ──────────────────────────── */

.hub-clauses {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  overflow: hidden;
}

.hub-clause {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 10px 7px 9px;
  border-top: 1px solid var(--border);
  border-left: 3px solid transparent;
  font-size: 12px;
  line-height: 1.4;
}

.hub-clause--first {
  border-top: none;
}

.hub-clause--flagged {
  border-left-color: var(--pool);
}

.hub-clause-num {
  font-family: 'DM Mono', monospace;
  font-size: 10.5px;
  color: var(--text-2);
  width: 30px;
  flex-shrink: 0;
}

.hub-clause-text {
  flex: 1;
  min-width: 0;
  color: var(--text);
}

.hub-flag {
  font-size: 10px;
  font-weight: 600;
  padding: 2px 7px;
  border-radius: var(--r-pill);
  background: var(--pool-light);
  color: var(--pool-dark);
  white-space: nowrap;
}

/* ── Step 6 teaser: build support ────────────────────────────── */

.hub-stage {
  display: grid;
  grid-template-columns: 14px minmax(0,1fr) auto;
  column-gap: 10px;
  align-items: center;
}

.hub-stage-rail {
  display: flex;
  flex-direction: column;
  align-items: center;
  align-self: stretch;
}

.hub-rail-seg {
  width: 1.5px;
  flex: 1;
  background: var(--border-2);
}

.hub-rail-seg--done {
  background: var(--pool);
}

.hub-rail-seg--none {
  background: transparent;
}

.hub-stage-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--surface);
  border: 2px solid var(--border-2);
  flex-shrink: 0;
}

.hub-stage-dot--paid {
  background: var(--pool);
  border-color: var(--pool);
}

.hub-stage-dot--now {
  border-color: var(--pool);
}

.hub-stage-name {
  font-size: 12.5px;
  color: var(--text);
  font-weight: 400;
  padding: 6px 0;
  line-height: 1.35;
}

.hub-stage-name--now {
  font-weight: 600;
}

.hub-stage-pay {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 12px;
  padding: 6px 0;
}

.hub-stage-amount {
  font-weight: 600;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.hub-stage-share {
  font-family: 'DM Mono', monospace;
  font-size: 10px;
  color: var(--text-2);
}

.hub-progress {
  display: flex;
  gap: 3px;
  padding-bottom: 4px;
}

.hub-progress-seg {
  flex: 1;
  height: 5px;
  border-radius: 3px;
  background: var(--border-2);
}

.hub-progress-seg--done {
  background: var(--pool);
}

.hub-progress-seg--now {
  background: var(--pool-mid);
}

.hub-week-row {
  display: grid;
  grid-template-columns: 88px minmax(0,1fr);
  column-gap: 12px;
  padding: 8px 0;
  border-top: 1px solid var(--border);
  align-items: start;
}

.hub-week-label {
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--pool-dark);
  line-height: 1.4;
  padding-top: 3px;
}

.hub-week-body {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.hub-week-value {
  font-family: 'Fraunces', serif;
  font-size: 15px;
  line-height: 1.3;
  letter-spacing: -.2px;
  color: var(--forest);
}

.hub-week-note {
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--text-2);
}

/* ── Step 7 teaser: pool maintenance ─────────────────────────── */

.hub-chips {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

.hub-chip {
  font-size: 10.5px;
  font-weight: 500;
  padding: 2px 8px;
  border-radius: var(--r-pill);
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  white-space: nowrap;
}

.hub-wheel-row {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  align-items: center;
}

.hub-wheel {
  flex-shrink: 0;
}

.hub-seasons {
  flex: 1 1 150px;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.hub-season {
  display: grid;
  grid-template-columns: 8px minmax(0,1fr);
  column-gap: 8px;
  padding: 4px 0;
  border-top: 1px solid var(--border);
  font-size: 11.5px;
  line-height: 1.4;
}

.hub-season-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-top: 4px;
}

.hub-season-dot--1 {
  background: var(--teal-border);
}

.hub-season-dot--2 {
  background: var(--pool-mid);
}

.hub-season-dot--3 {
  background: var(--pool);
}

.hub-season-dot--4 {
  background: var(--pool-dark);
}

.hub-season-dot--5 {
  background: var(--pool-deep);
}

.hub-task {
  padding: 7px 0;
  border-top: 1px solid var(--border);
  font-size: 12.5px;
  line-height: 1.45;
}

.hub-because {
  display: inline-block;
  vertical-align: 1px;
  font-size: 9.5px;
  font-weight: 600;
  padding: 1px 7px;
  border-radius: var(--r-pill);
  background: var(--pool-light);
  color: var(--pool-dark);
  white-space: nowrap;
}

/* ── /contractors holding page (D73) ─────────────────────────── */

/* The Step 2 holding page loads this sheet (pageCss in
   contractors.njk) so its two halves are the hub card's own
   construction (.hub-halves, .hub-lines) and the page and the card
   cannot drift. Only the rules below are page-only; the Step 2 build
   replaces the page in place and retires them with it. One column at
   reading width; no capture of any kind (D50). */

.hub-holding-main {
  max-width: 640px;
  margin: 0 auto;
  padding: 28px 16px 48px;
  display: flex;
  flex-direction: column;
  gap: 24px;
}

/* The quiet secondary style: text-2 resting, pool-dark on hover, no
   underline shift. */
.hub-holding-home {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-2);
  text-decoration: none;
}

.hub-holding-home:hover {
  color: var(--pool-dark);
  text-decoration: none;
}

.hub-holding-home:focus-visible {
  outline: 2px solid var(--teal-border);
  outline-offset: 2px;
}

.hub-holding-chevron {
  font-size: 16px;
  line-height: 1;
}

.hub-holding-head {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.hub-holding-eyebrow {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--pool-dark);
}

.hub-holding-title {
  font-size: 28px;
  line-height: 1.25;
  margin: 0;
}

.hub-holding-lede {
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--text-2);
  margin: 0;
}

.hub-holding-close {
  border-top: 1px solid var(--border);
  padding-top: 16px;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text-2);
  margin: 0;
}

.hub-holding-close a {
  color: var(--pool-dark);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.hub-holding-close a:hover {
  color: var(--pool);
}
