/* ============================================================
   NOBL — COMPONENTS
   Buttons, cards, chips, header, footer.
   ============================================================ */

/* ------------------------------------------------------------
   BUTTONS
   ------------------------------------------------------------ */

/* One radius at every size — a bigger button does not get a bigger
   corner. That part is the kit's.

   The TYPE is a deliberate departure from it. The manifest sets
   buttons in Space Mono, uppercase, +0.06em; at real size that
   reads as a terminal prompt rather than a control, and it was the
   single thing making the site feel less professional than the
   Stripe reference we're aiming at. Buttons are body copy you can
   click: Noto Sans, sentence case, no tracking. Mono stays where
   the kit is right about it — labels, chips, data, eyebrows.
   Worth reconciling back into the manifest. */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-body);
  font-size: var(--t-btn);
  font-weight: 600;
  letter-spacing: 0;
  padding: 12px 20px;
  border: 1px solid transparent;
  border-radius: var(--r-button);
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--d-btn), border-color var(--d-btn), color var(--d-btn);
}
.btn .arw { font-size: 15px; line-height: 1; }

/* PRIMARY — Fiber Blue, one per screen. Kept under the old
   `--dark` name so the markup didn't have to churn. */
.btn--dark {
  background: var(--accent);
  color: var(--accent-ink);
}
.btn--dark:hover { background: #33596F; }

/* GHOST — secondary on light */
.btn--glass {
  color: var(--text);
  border-color: var(--stroke-strong);
  background: var(--panel);
}
.btn--glass:hover { background: var(--panel-2); }
.btn--glass .arw { color: var(--accent); }

/* Primary on dark: white fill, ink text */
.btn--white {
  background: var(--bg);
  color: var(--text);
}
.btn--white:hover { background: var(--accent-fill); color: var(--text); }

/* Ghost on dark */
.btn--outline-light {
  border-color: var(--bw-25);
  color: var(--bg);
}
.btn--outline-light:hover { background: rgba(255,255,255,0.08); }

/* Small variant — same 4px corner, less padding */
.btn--sm { font-size: var(--t-btn-sm); padding: 10px 16px; }
.btn--sm .arw { font-size: 14px; }

/* Header CTA. Deliberately NOT the accent: the page's own primary
   action is the one Fiber Blue thing on screen, and a header
   button competing with it would break that. */
.btn--nav {
  font-size: var(--t-btn-sm);
  padding: 9px 16px;
  gap: 7px;
  background: var(--text);
  color: var(--bg);
}
.btn--nav .arw { font-size: 14px; }
.btn--nav:hover { background: var(--accent); }

.btn-row {
  display: flex;
  gap: var(--gap-chip);
  flex-wrap: wrap;
  align-items: center;
}
.btn-row--center { justify-content: center; }


/* ------------------------------------------------------------
   CARDS
   ------------------------------------------------------------ */

.card {
  position: relative;
  padding: var(--pad-card);
  border-radius: var(--r-card);
  background: var(--bg-deep);
  border: 1px solid var(--stroke);
  transition: transform var(--d-card), box-shadow var(--d-card);
}
/* Depth from tint, not shadow: the border firms up and the surface
   lifts to white. No drop shadow anywhere in the card system. */
.card:hover { background: var(--bg); border-color: var(--stroke-strong); }

.card--dark {
  background: var(--smoke);
  color: var(--on-dark-heading);
  border-color: var(--smoke);
  overflow: hidden;
}
.card--dark:hover { border-color: var(--bw-18); }

/* Corner glow that bleeds from top-right of a dark card */
.card__glow {
  position: absolute;
  right: -60px; top: -60px;
  width: 220px; height: 220px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(62,107,135,0.55), rgba(62,107,135,0) 70%);
  pointer-events: none;
}
.card__glow--gold {
  background: radial-gradient(circle, rgba(212,168,90,0.45), rgba(212,168,90,0) 70%);
}

.card__number {
  font-family: var(--font-display);
  text-transform: uppercase;
  font-weight: 400;
  font-size: var(--t-card-number);
  letter-spacing: var(--tr-display);
  line-height: 1;
  color: var(--text);
  margin-bottom: 56px;
}
.card--dark .card__number { color: var(--accent-fill); }

.card__title {
  font-size: var(--t-card-title);
  font-weight: 700;
  letter-spacing: -0.02em;
  margin: 0 0 10px;
}

.card__body {
  font-size: var(--t-card);
  color: var(--body);
  line-height: var(--lh-body);
  margin: 0;
}
.card--dark .card__body { color: var(--on-dark-body); }

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--gap-card);
}


/* ------------------------------------------------------------
   CHIPS & PILLS
   ------------------------------------------------------------ */

.pill-badge {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 6px 12px 6px 8px;
  border: 1px solid var(--stroke);
  border-radius: var(--r-button);
  background: rgba(255,255,255,0.75);
  backdrop-filter: blur(8px);
}
.pill-badge__dot {
  width: 18px; height: 18px;
  border-radius: 50%;
  background: var(--accent);
  display: grid; place-items: center;
  flex: 0 0 auto;
}
.pill-badge__dot i {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--bg);
  animation: noblPulse 2.4s ease-in-out infinite;
}
.pill-badge__text {
  font-family: var(--font-mono);
  font-size: var(--t-eyebrow);
  letter-spacing: var(--tr-label);
  color: var(--accent);
  font-weight: 400;
  white-space: nowrap;
}

/* Status chip inside the platform mock */
.status-chip {
  font-family: var(--font-mono);
  font-size: var(--t-chip);
  letter-spacing: var(--tr-chip);
  padding: 4px 8px;
  border-radius: var(--r-button);
  background: rgba(255,255,255,0.10);
  white-space: nowrap;
  flex: 0 0 auto;
}
.status-chip--installed { color: var(--accent-fill); }
.status-chip--scheduled { color: var(--gold); }
.status-chip--submitted { color: var(--on-dark-meta); }

/* Checklist row on dark */
.check-list { display: grid; gap: 14px; }
.check-list li { display: flex; align-items: center; gap: 14px; }
.check-list__mark {
  width: 20px; height: 20px;
  border-radius: 50%;
  background: rgba(91,157,181,0.18);
  display: grid; place-items: center;
  flex: 0 0 auto;
}
.check-list__mark i { width: 6px; height: 6px; border-radius: 50%; background: var(--accent-fill); }
.check-list__mark--gold { background: rgba(212,168,90,0.18); }
.check-list__mark--gold i { background: var(--gold); }
.check-list span { font-size: var(--t-body); color: var(--on-dark-list); }


/* ------------------------------------------------------------
   DECORATIVE LAYERS (dark sections)
   ------------------------------------------------------------ */

.glow {
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
  z-index: -1;
}
.glow--bl {
  left: -200px; bottom: -300px;
  width: 800px; height: 800px;
  background: radial-gradient(circle, rgba(62,107,135,0.35), rgba(62,107,135,0) 65%);
}
.glow--tr {
  right: -200px; top: -200px;
  width: 700px; height: 700px;
  background: radial-gradient(circle, rgba(62,107,135,0.4), rgba(62,107,135,0) 65%);
}

/* 64px grid texture, radially masked */
.grid-texture {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(255,255,255,0.035) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,0.035) 1px, transparent 1px);
  background-size: 64px 64px;
  -webkit-mask-image: radial-gradient(ellipse 60% 70% at 70% 40%, #000, transparent);
          mask-image: radial-gradient(ellipse 60% 70% at 70% 40%, #000, transparent);
  pointer-events: none;
  z-index: -1;
}


/* ============================================================
   HEADER
   ============================================================ */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(255,255,255,0.82);
  backdrop-filter: blur(14px) saturate(1.4);
  border-bottom: 1px solid var(--stroke);
}

.site-header__inner {
  max-width: var(--page-max);
  margin-inline: auto;
  padding-inline: var(--header-pad);
  display: grid;
  grid-template-columns: auto minmax(0,1fr) auto;
  align-items: center;
  gap: 16px;
  height: var(--header-h);
}

/* ------------------------------------------------------------
   THE LOCKUP — mark + NOBL, never the SALES line

   The shared lockup PNG is mark + NOBL on rows 0–310 and SALES
   alone on rows 353–434. `object-fit: cover` anchored to the top
   of a 2000/331 box cuts at row 331 — the middle of the gap, with
   ~20 source rows of slack either side, so rounding can neither
   shave the wordmark nor reveal a sliver of SALES. It's the same
   cut the brand manifest makes, and it needs no wrapper element.

   Height is set on the image and the ratio does the rest, so the
   wordmark keeps its optical size instead of shrinking into the
   shorter crop.

   One rule for every lockup on the site. When design cuts a
   wordmark-only export, this collapses to `height: X; width: auto`.
   ------------------------------------------------------------ */
.site-header__logo img,
.site-footer__brand img {
  display: block;
  width: auto;
  aspect-ratio: 2000 / 331;
  object-fit: cover;
  object-position: top;
}
.site-header__logo img { height: 20px; }

.site-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
}
.site-nav a {
  padding: 8px 10px;
  font-size: var(--t-nav);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--body);
  white-space: nowrap;
}
.site-nav a:hover { color: var(--text); }
.site-nav a[aria-current="page"] { color: var(--text); }

/* Mobile drawer toggle — hidden on desktop */
.nav-toggle {
  display: none;
  width: 40px; height: 40px;
  border-radius: 50%;
  border: 1px solid var(--stroke);
  place-items: center;
}
.nav-toggle span {
  display: block;
  width: 16px; height: 1.5px;
  background: var(--text);
  border-radius: 2px;
  transition: transform var(--d-btn), opacity var(--d-btn);
}
.nav-toggle span + span { margin-top: 4px; }
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(5.5px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-5.5px) rotate(-45deg); }

@media (max-width: 900px) {
  .site-header__inner { grid-template-columns: auto 1fr auto; }
  .nav-toggle { display: grid; }

  .site-nav {
    position: fixed;
    inset: var(--header-h) 0 auto 0;
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    gap: 2px;
    background: rgba(255,255,255,0.97);
    backdrop-filter: blur(14px) saturate(1.4);
    border-bottom: 1px solid var(--stroke);
    padding: 12px var(--page-pad) 24px;
    transform: translateY(-12px);
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--d-btn), transform var(--d-btn), visibility var(--d-btn);
  }
  .site-nav[data-open="true"] { opacity: 1; transform: none; visibility: visible; }
  .site-nav a {
    padding: 14px 4px;
    font-size: 16px;
    border-bottom: 1px solid var(--stroke);
  }
  .site-header .btn--nav { display: none; }
}


/* ============================================================
   FOOTER
   ============================================================ */

.site-footer {
  background: var(--bg);
  border-top: 1px solid var(--stroke);
}
.site-footer__inner {
  max-width: var(--page-max);
  margin-inline: auto;
  padding: 72px var(--page-pad) 36px;
}
.site-footer__cols {
  display: flex;
  gap: var(--gap-col);
  flex-wrap: wrap;
  padding-bottom: 56px;
}
.site-footer__brand { flex: 1; min-width: 260px; }
.site-footer__brand img { height: 22px; margin-bottom: 22px; }
.site-footer__disclaimer {
  font-size: var(--t-footer-link);
  color: var(--body);
  line-height: 1.65;
  max-width: 340px;
  margin: 0;
}
.site-footer__col { display: grid; gap: 12px; align-content: start; min-width: 150px; }
.site-footer__col h2 {
  font-family: var(--font-mono);
  font-size: var(--t-meta);
  font-weight: 400;
  letter-spacing: 0.16em;
  color: var(--body);
  margin: 0 0 4px;
  text-transform: uppercase;
}
.site-footer__col a,
.site-footer__col span {
  font-size: var(--t-footer-link);
  color: var(--text);
  font-weight: 500;
}
.site-footer__col a:hover { color: var(--accent); }

.site-footer__bar {
  display: flex;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
  padding-top: 24px;
  border-top: 1px solid var(--stroke);
  font-family: var(--font-mono);
  font-size: var(--t-meta);
  letter-spacing: var(--tr-meta);
  color: var(--body);
}
.site-footer__bar a { color: inherit; }
.site-footer__bar a:hover { color: var(--text); }


/* ============================================================
   SHARED SECTION PATTERNS
   Lifted out of home.css when the second page needed them.
   These are page furniture, not home-page features.
   ============================================================ */

/* ------------------------------------------------------------
   SPLIT HEADER — eyebrow + headline left, intro paragraph right
   ------------------------------------------------------------ */
.split-header {
  display: grid;
  grid-template-columns: minmax(0,1fr) minmax(0,1fr);
  gap: var(--gap-col);
  align-items: end;
  margin-bottom: 72px;
}
@media (max-width: 900px) {
  .split-header { grid-template-columns: 1fr; gap: 24px; margin-bottom: 44px; }
}


/* ------------------------------------------------------------
   5. STATS — the data rail

   Five equal slots on one line, hairline dividers, no hierarchy:
   the record, stated plainly. Five columns fill the row exactly —
   the previous `auto-fit` grid landed on four and left the fifth
   stranded alone on a second row.
   ------------------------------------------------------------ */

/* Boxes, not a hairline rail — the same card the pillars use, so a
   figure reads as its own object rather than a cell in a table. */
.rail {
  display: grid;
  grid-template-columns: repeat(var(--rail-cols, 5), minmax(0, 1fr));
  gap: var(--gap-card);
  margin: 0;
  padding: 0;
  list-style: none;
}

.rail__item {
  display: flex;
  flex-direction: column;
  padding: 26px 24px 28px;
  background: var(--s2);
  border: 1px solid var(--stroke);
  border-radius: var(--r-card);
}
/* Raised off a white ground by default. On a tinted ground the card
   has to go the other way — see the two page-level overrides. */

/* The block is reserved at the full figure height and the value sits on
   its floor, so a stepped-down word (NIGHTLY) and a full-size numeral
   (4) share a baseline — otherwise the labels beneath them land ~16px
   apart and the row reads crooked. */
.rail__value {
  min-height: clamp(28px, 3vw, 42px);
  font-family: var(--font-display);
  text-transform: uppercase;
  font-weight: 400;
  font-size: clamp(28px, 3vw, 42px);
  line-height: 1;
  letter-spacing: var(--tr-display);
  margin: 0;
  font-variant-numeric: tabular-nums;
}

/* Some rails carry words rather than figures — NIGHTLY, FRIDAY,
   MONTHLY. A seven-letter word in a wide display face overruns a box
   that a two-digit numeral sits in comfortably, so words step down.
   Used to be safe when the last cell could bleed to the container
   edge; a box has walls. */
.rail__value:not([data-count]) {
  font-size: clamp(22px, 2.2vw, 30px);
  letter-spacing: var(--tr-display);
  overflow-wrap: anywhere;
  /* Sits on the floor of the reserved block rather than the ceiling, so
     its baseline matches the full-size figures beside it. Done with
     padding, not flex — flex strips the leading space out of the
     "<span> days</span>" suffix and "7 DAYS" closes up to "7DAYS". */
  padding-top: calc(clamp(28px, 3vw, 42px) - clamp(22px, 2.2vw, 30px));
}

/* ...and when a row MIXES the two, every value takes the word size. Left
   alone, "4" and "7 DAYS" set at 42px beside "NIGHTLY" at 30px and the
   row reads as two different typographic ranks. Rails that are all
   figures (the home stats) are untouched. */
.rail:has(.rail__value:not([data-count])) .rail__value {
  font-size: clamp(22px, 2.2vw, 30px);
  min-height: clamp(22px, 2.2vw, 30px);
  padding-top: 0;
}

/* The unit, never the magnitude — so the K in 10K stays ink. */
.stat-suffix { color: var(--accent); }

.rail__label {
  font-family: var(--font-mono);
  font-size: var(--t-meta);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--body);
  line-height: 1.7;
  margin: 13px 0 0;
}

/* Five narrow boxes stop working well before the phone. Two up, then
   one — figure and label side by side so every value stays visible
   without a horizontal scroll. */
@media (max-width: 900px) {
  .rail { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .rail__item {
    flex-direction: row;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    padding: 16px 16px 17px;
  }
  .rail__value { min-height: 0; }
  .rail__value:not([data-count]) { padding-top: 0; }
  /* a figure must not break from its unit — "7 days" was wrapping */
  .rail__value { font-size: 26px; flex: none; white-space: nowrap; }
  .rail__label { margin: 0; text-align: right; }
}
@media (max-width: 560px) {
  .rail { grid-template-columns: 1fr; }
}

/* Four-slot variant — the process stats on How It Works. */
.rail--4 { --rail-cols: 4; }

/* ------------------------------------------------------------
   8. CLOSING CTA — the journey arrives

   The page's argument is a sequence: onboarded, territory, sold,
   paid. This is where that line finally reaches its end, so the
   stepper's rail runs in from off-frame and terminates on a gold
   node at the primary action — the same gold step 04 lands on.

   Replaces a dashed SVG that animated across at 50% and cut
   straight through the sub-copy. It meant nothing and belonged to
   no other section.
   ------------------------------------------------------------ */

/* Smoke, not Fiber Fade. The kit reserves the gradient for hero
   frames, and a flat dark band is the calmer close — one quiet
   period at the foot of every page instead of a second big
   gradient moment. The scrim the gradient needed is gone with it. */
.cta {
  background: var(--smoke);
  text-align: center;
}

.cta__title {
  color: var(--bg);
  max-width: 17ch;
  margin: 0 auto 22px;
}
.cta__sub {
  color: var(--on-dark-list);
  max-width: 54ch;
  margin: 0 auto 52px;
}

/* The buttons centre on their own — the node is taken OUT of the flow
   entirely and hung off their left edge, so it can't shift them. Earlier
   it was a flex item, which centred node-plus-buttons and left the
   buttons sitting right of the headline. */
.cta__arrive {
  display: flex;
  justify-content: center;
}

.cta__actions {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 22px;
}

.cta__node {
  position: absolute;
  right: 100%;
  margin-right: 22px;
  top: 50%;
  transform: translateY(-50%);
  width: 23px; height: 23px;
  border-radius: 50%;
  border: 1px solid var(--gold);
  display: grid;
  place-items: center;
  box-shadow: 0 0 18px -2px rgba(212,168,90,0.55);
}
.cta__node::after {
  content: "";
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--gold);
}

/* Runs out of the node to beyond the frame edge, fading up from nothing
   through blue and arriving gold. */
.cta__rail {
  position: absolute;
  right: 100%;
  top: 50%;
  width: 100vw;
  height: 1px;
  background: linear-gradient(90deg,
              rgba(91,157,181,0) 0%,
              rgba(91,157,181,0.55) 52%,
              var(--gold) 100%);
  transform: scaleX(0);
  transform-origin: right center;
}
.cta__arrive[data-reveal="in"] .cta__rail {
  transform: scaleX(1);
  transition: transform 1.25s var(--ease-out) .15s;
}

@media (max-width: 900px) {
  .cta__title { max-width: none; }
  .cta__sub { margin-bottom: 38px; }
  /* Off-frame travel reads as a stray line on a phone. */
  .cta__node { display: none; }
}


/* ============================================================
   SHARED PAGE PATTERNS
   Lifted out of how-it-works.css when the remaining pages
   needed them. Page furniture, not page features.
   ============================================================ */

/* ------------------------------------------------------------
   SECTION HEADER — eyebrow + headline (+ optional intro)
   ------------------------------------------------------------ */

.sec-head { max-width: 760px; margin-bottom: 64px; }
.sec-head .intro { margin-top: 22px; max-width: 58ch; }

@media (max-width: 900px) {
  .sec-head { margin-bottom: 40px; }
}


/* ------------------------------------------------------------
   TAGSET — the artifacts a step or a role actually hands you.
   Chips rather than a second sentence: a checklist, not prose.
   ------------------------------------------------------------ */
.tagset {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 24px 0 0;
  padding: 0;
}
.tagset li {
  font-family: var(--font-mono);
  font-size: var(--t-chip);
  font-weight: 500;
  letter-spacing: var(--tr-chip);
  text-transform: uppercase;
  color: var(--body);
  border: 1px solid var(--stroke);
  border-radius: var(--r-button);
  padding: 7px 12px 6px;
  white-space: nowrap;
}


/* ------------------------------------------------------------
   FAQ

   Header parks on the left while the answers scroll past it, so
   the column of questions gets a real measure instead of running
   the full 1240px.
   ------------------------------------------------------------ */
.faq {
  display: grid;
  grid-template-columns: minmax(0, 0.72fr) minmax(0, 1.6fr);
  gap: var(--gap-col-lg);
  align-items: start;
}
.faq__aside { position: sticky; top: calc(var(--header-h) + 40px); }
.faq__head { font-size: var(--t-h2-minor); }
.faq__note {
  font-size: var(--t-body);
  color: var(--body);
  margin: 22px 0 0;
}

.faq__list { list-style: none; margin: 0; padding: 0; }
.faq__item { border-top: 1px solid var(--stroke); }
.faq__item:last-child { border-bottom: 1px solid var(--stroke); }
.faq__item h3 { margin: 0; font: inherit; }

.faq__q {
  width: 100%;
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) 22px;
  align-items: start;
  gap: 12px;
  padding: 26px 0;
  text-align: left;
}
.faq__n {
  font-family: var(--font-mono);
  font-size: var(--t-meta);
  letter-spacing: var(--tr-meta);
  color: var(--muted);
  padding-top: 7px;
  transition: color var(--d-state);
}
.faq__text {
  /* Body face on purpose: eight all-caps questions is a wall, and
     this is interface copy inside a disclosure, not a display head. */
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--t-step-title);
  line-height: 1.4;
  letter-spacing: -0.01em;
  color: var(--text);
  text-wrap: pretty;
}

/* A plus that becomes a minus — one bar rotates out. */
.faq__sign {
  position: relative;
  width: 14px; height: 14px;
  margin-top: 8px;
  justify-self: end;
}
.faq__sign::before,
.faq__sign::after {
  content: "";
  position: absolute;
  inset: 50% 0 auto 0;
  height: 1px;
  background: var(--text);
  transition: transform var(--d-state), opacity var(--d-state);
}
.faq__sign::after { transform: rotate(90deg); }

.faq__q[aria-expanded="true"] .faq__n { color: var(--accent); }
.faq__q[aria-expanded="true"] .faq__sign::after { transform: rotate(0deg); opacity: 0; }
.faq__q:hover .faq__text { color: var(--accent); }

.faq__a {
  display: grid;
  grid-template-rows: 1fr;
  transition: grid-template-rows var(--d-state) var(--ease-out);
}
.faq__item[data-open="false"] .faq__a { grid-template-rows: 0fr; }
.faq__a > p {
  overflow: hidden;
  min-height: 0;
  margin: 0;
  font-size: var(--t-intro);
  line-height: var(--lh-intro);
  color: var(--body);
  max-width: 62ch;
  padding-left: 56px;
  text-wrap: pretty;
}
/* Closed panels must not leave their bottom padding behind. */
.faq__item[data-open="true"] .faq__a > p { padding-bottom: 30px; }

@media (max-width: 900px) {
  .faq { grid-template-columns: 1fr; gap: 36px; }
  .faq__aside { position: static; }
  .faq__q { grid-template-columns: 34px minmax(0, 1fr) 18px; padding: 22px 0; }
  .faq__text { font-size: 17px; }
  .faq__a > p { padding-left: 46px; font-size: var(--t-body); }
}


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


/* ============================================================
   PAGE HERO
   The opener on every page that isn't the home page. Lighter
   than the home hero by design — no canvas, no full-viewport
   height, and it hands off to the first real section quickly.
   ============================================================ */

.phero {
  position: relative;
  overflow: hidden;
  background: var(--s2);
  border-bottom: 1px solid var(--stroke);
  padding-block: clamp(64px, 8vw, 116px) clamp(56px, 7vw, 92px);
}
.phero__field {
  position: absolute;
  inset: 0;
  background-image: radial-gradient(rgba(11,13,15,0.05) 1px, transparent 1px);
  background-size: 22px 22px;
  -webkit-mask-image: radial-gradient(ellipse 58% 68% at 14% 6%, #000, transparent);
          mask-image: radial-gradient(ellipse 58% 68% at 14% 6%, #000, transparent);
  pointer-events: none;
}
.phero > .container { position: relative; }

/* 1.3/0.7 left a wide dead band between the headline and the figures —
   the copy column stops at its 17ch measure long before its track ends.
   The copy track has a hard floor: below 622px — the headline's 17ch
   measure at its 64px cap — the H1 picks up a third line. So the room
   for the figures comes out of the gutter as well as the split:
   1.18/0.82 at a 56px gutter leaves the copy at ~625px and still
   brings the figures ~70px in off the page edge. */
.phero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.18fr) minmax(0, 0.82fr);
  gap: 56px;
  align-items: end;
}

.phero__title {
  font-size: clamp(38px, 4.6vw, 64px);
  line-height: 1.0;
  max-width: 17ch;
  margin-bottom: 24px;
}
.phero__sub { max-width: 52ch; margin-bottom: 34px; }
.phero__ctas { margin: 0; }

/* Three figures stacked against the headline — the claim on the left,
   the record on the right. Boxes, not naked hairlines: the same card
   every other figure on the site now sits in.

   Gap is 14px rather than --gap-card. These are one group of three
   reading as a set, not four independent cards in a row; at 24px
   between boxes this short they drift apart. */
.phero__proof {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 12px;
}
.phero__proof li {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 18px;
  padding: 22px 24px;
  background: var(--bg);
  border: 1px solid var(--stroke);
  border-radius: var(--r-card);
}

/* The dead band between a figure and its label is the boring part of a
   stat row. A halftone fills exactly that band and fades out at both
   ends — the same density language the mark diagram and the market
   scorecard use — so the card reads as something measured rather than
   as a table row. The figure and the label punch through it on their
   own ground, so nothing sits on top of dots however long they run. */
.phero__proof li::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(var(--rule) 1px, transparent 1.2px);
  background-size: 9px 9px;
  -webkit-mask-image: linear-gradient(90deg, transparent 22%, #000 50%, transparent 86%);
          mask-image: linear-gradient(90deg, transparent 22%, #000 50%, transparent 86%);
  opacity: .5;
  pointer-events: none;
}

.phero__proof b {
  position: relative;
  z-index: 1;
  font-family: var(--font-display);
  text-transform: uppercase;
  font-weight: 400;
  font-size: 32px;
  line-height: 1;
  letter-spacing: var(--tr-display);
  font-variant-numeric: tabular-nums;
  flex: none;
  background: var(--bg);
  padding-right: 12px;
}
.phero__proof i { font-style: normal; color: var(--accent); }
/* Direct child only — the counter writes into a .stat-num span nested
   inside the <b>, which must not pick up the label's mono treatment. */
.phero__proof li > span {
  position: relative;
  z-index: 1;
  font-family: var(--font-mono);
  font-size: var(--t-meta);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--body);
  text-align: right;
  line-height: 1.6;
  background: var(--bg);
  padding-left: 12px;
}

@media (max-width: 1000px) {
  .phero__grid { grid-template-columns: 1fr; gap: 44px; align-items: start; }
  .phero__title { max-width: none; }
}


/* ============================================================
   FORMS

   NOT WIRED. js/main.js blocks submission on any form marked
   data-unwired and shows .form__note instead — see the TODO in
   the page markup.
   ============================================================ */

.formcard {
  background: var(--bg);
  border: 1px solid var(--stroke);
  border-radius: var(--r-card);
  padding: var(--pad-card-lg);
}
.formcard__title {
  font-family: var(--font-display);
  text-transform: uppercase;
  font-weight: 400;
  font-size: 26px;
  line-height: 1.1;
  letter-spacing: var(--tr-display);
  margin: 0;
  text-wrap: balance;
}

.form { display: grid; gap: 16px; margin-top: 28px; }

.field { display: grid; gap: 7px; margin: 0; }
.field label {
  font-family: var(--font-mono);
  font-size: var(--t-label);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--body);
}
.field input,
.field textarea,
.field select {
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.5;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--stroke-strong);
  border-radius: var(--r-button);
  padding: 12px 14px;
  width: 100%;
  transition: border-color var(--d-fast), box-shadow var(--d-fast);
}
.field textarea { resize: vertical; min-height: 96px; }
.field input::placeholder,
.field textarea::placeholder { color: var(--muted); }
.field input:focus-visible,
.field textarea:focus-visible,
.field select:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(62,107,135,0.14);
}

.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }

.form__submit { margin-top: 8px; justify-self: start; }

/* Shown only when an unwired form is submitted. */
.form__note {
  margin: 0;
  font-size: var(--t-card);
  line-height: 1.55;
  color: var(--text);
  background: rgba(62,107,135,0.08);
  border: 1px solid rgba(62,107,135,0.22);
  border-radius: var(--r-button);
  padding: 12px 14px;
}
.form__note:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.form__fine {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--body);
}

@media (max-width: 560px) {
  .formcard { padding: 28px 22px 26px; }
  .field-row { grid-template-columns: 1fr; }
}


/* ============================================================
   KIT MOTIFS
   Two of the six from the brand manifest, shared across pages.
   The loud ones — HUD telemetry, ghost numerals, the scanline —
   are deliberately not here: they read sci-fi dashboard, and the
   site is aiming at calm.
   ============================================================ */

/* Framed eyebrow — mono label flanked by a hairline. Opens a section. */
.eyebrow--framed { display: flex; align-items: center; gap: 12px; }
.eyebrow--framed::before {
  content: "";
  width: 30px; height: 1px;
  background: var(--accent-line);
  flex: none;
}

/* Corner ticks — Fiber Blue L-brackets. The blueprint signature.
   One frame per page, never scattered. */
.tick { position: absolute; width: 22px; height: 22px; opacity: .7; pointer-events: none; }
.tick--tl { top: 14px; left: 14px;  border-top: 1.5px solid var(--accent-line); border-left: 1.5px solid var(--accent-line); }
.tick--tr { top: 14px; right: 14px; border-top: 1.5px solid var(--accent-line); border-right: 1.5px solid var(--accent-line); }
.tick--bl { bottom: 14px; left: 14px;  border-bottom: 1.5px solid var(--accent-line); border-left: 1.5px solid var(--accent-line); }
.tick--br { bottom: 14px; right: 14px; border-bottom: 1.5px solid var(--accent-line); border-right: 1.5px solid var(--accent-line); }


/* ------------------------------------------------------------
   WHY NOBL — the spec panel

   Six reasons as one object instead of a 3x2 of text boxes: the
   list on the left selects, the stage on the right carries the
   claim and a NOBL OS artifact that backs it. Auto-cycles, holds
   on hover or focus.

   The artifacts are deliberately STRUCTURAL — they name what the
   system records and when, they never quote a volume. An invented
   install count would be a claim this page can't stand behind.
   ------------------------------------------------------------ */

.spec {
  display: grid;
  grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr);
  gap: var(--gap-col);
  align-items: start;
}

/* --- the list --- */
.spec__nav {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 4px;
}
.spec__btn {
  position: relative;
  display: grid;
  grid-template-columns: 30px minmax(0, 1fr);
  align-items: baseline;
  gap: 12px;
  width: 100%;
  text-align: left;
  cursor: pointer;
  padding: 15px 16px 16px;
  border: 1px solid transparent;
  border-radius: var(--r-card);
  transition: background var(--d-state), border-color var(--d-state);
}
.spec__item[data-on="true"] .spec__btn {
  background: var(--bg);
  border-color: var(--accent-line);
}
.spec__btn:hover { background: var(--bg); }
.spec__item[data-on="true"] .spec__btn:hover { background: var(--bg); }
.spec__btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.spec__n {
  font-family: var(--font-mono);
  font-size: var(--t-meta);
  letter-spacing: var(--tr-label);
  color: var(--faint);
  transition: color var(--d-state);
}
.spec__item[data-on="true"] .spec__n { color: var(--accent); }
.spec__t {
  font-size: 15px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--muted);
  transition: color var(--d-state);
}
.spec__item[data-on="true"] .spec__t { color: var(--text); }

/* The auto-advance, made visible: a hairline that fills over the
   dwell. Without it the panel changes for no reason the reader can
   see. Restarted per selection by re-adding the class in JS. */
.spec__meter {
  grid-column: 2;
  display: block;
  height: 1px;
  margin-top: 12px;
  background: var(--stroke);
  opacity: 0;
  transition: opacity var(--d-state);
}
.spec__item[data-on="true"] .spec__meter { opacity: 1; }
.spec__meter i {
  display: block;
  height: 100%;
  width: 0;
  background: var(--accent);
}
.spec.is-running .spec__item[data-on="true"] .spec__meter i {
  animation: specFill var(--dwell, 5s) linear forwards;
}
@keyframes specFill { from { width: 0 } to { width: 100% } }

/* --- the stage --- */
.spec__stage {
  position: relative;
  background: var(--bg);
  border: 1px solid var(--stroke);
  border-radius: var(--r-card);
  padding: 32px 34px 34px;
}
.spec__h {
  font-family: var(--font-display);
  text-transform: uppercase;
  font-weight: 400;
  font-size: var(--t-card-title);
  line-height: 1.16;
  letter-spacing: var(--tr-display);
  color: var(--text);
  margin: 0 0 12px;
}
.spec__b {
  font-size: var(--t-card);
  line-height: var(--lh-body);
  color: var(--body);
  margin: 0 0 26px;
  max-width: 54ch;
  text-wrap: pretty;
}

/* Once JS is in, all six panels stack in ONE grid cell and only the
   live one is visible. Stacking rather than display:none is what keeps
   the stage's height fixed to the tallest panel — hiding them outright
   made the box jump every time the cycle advanced. visibility:hidden
   also takes the inactive ones out of the accessibility tree.
   Without JS every panel stays in flow and the section reads as six
   stacked blocks, so nothing is ever hidden from a crawler. */
.spec.is-live .spec__stage { display: grid; }
.spec.is-live .spec__panel {
  grid-area: 1 / 1;
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
}
.spec.is-live .spec__panel[data-on="true"] {
  visibility: visible;
  opacity: 1;
  pointer-events: auto;
  animation: specIn .4s var(--ease-out) both;
}
@keyframes specIn {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
.spec:not(.is-live) .spec__panel + .spec__panel {
  margin-top: 34px;
  padding-top: 32px;
  border-top: 1px solid var(--stroke);
}

/* --- the artifact: a dark product surface on a light page --- */
.spec__art {
  color: var(--on-dark-list);
  background: var(--smoke);
  border: 1px solid rgba(255,255,255,0.09);
  border-radius: var(--r-card);
  padding: 15px 17px 17px;
  box-shadow: var(--sh-mock);
}
.spec__art-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: var(--t-meta);
  letter-spacing: var(--tr-meta);
  text-transform: uppercase;
  color: var(--on-dark-mono);
  margin: 0 0 4px;
  padding-bottom: 11px;
  border-bottom: 1px solid var(--bw-08);
}
.spec__art-bar i {
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--accent-fill);
  flex: none;
}

.spec__rows { list-style: none; margin: 0; padding: 0; }
.spec__rows li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 11px 0;
  border-bottom: 1px solid var(--bw-08);
}
.spec__rows li:last-child { border-bottom: 0; padding-bottom: 2px; }
.spec__rows span {
  font-size: 13px;
  color: var(--on-dark-list);
  min-width: 0;
}
.spec__st {
  font-family: var(--font-mono);
  font-style: normal;
  font-size: 9.5px;
  letter-spacing: var(--tr-chip);
  text-transform: uppercase;
  padding: 5px 8px 4px;
  border-radius: var(--r-button);
  white-space: nowrap;
  flex: none;
}
.spec__st--ok   { color: var(--accent-fill); background: rgba(91,157,181,0.16); }
.spec__st--live { color: var(--gold); background: rgba(212,168,90,0.14); }
.spec__st--off  { color: var(--on-dark-mono); background: rgba(255,255,255,0.06); }

/* the 7-day standup */
.spec__track {
  list-style: none;
  margin: 0;
  padding: 14px 0 2px;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px;
  counter-reset: none;
}
.spec__track li {
  position: relative;
  padding-top: 18px;
  min-width: 0;
}
/* the rail runs node-centre to node-centre, so it never overhangs */
.spec__track li::before {
  content: "";
  position: absolute;
  left: 0; top: 4px;
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--accent-fill);
  z-index: 1;
}
.spec__track li::after {
  content: "";
  position: absolute;
  left: 9px; top: 8px;
  right: -10px;
  height: 1px;
  background: var(--bw-14);
}
.spec__track li:last-child::after { display: none; }
.spec__track li:last-child::before { background: var(--gold); }
.spec__day {
  display: block;
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: var(--tr-chip);
  text-transform: uppercase;
  color: var(--on-dark-mono);
  margin-bottom: 5px;
}
.spec__step {
  display: block;
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--on-dark-heading);
  overflow-wrap: anywhere;
}

.spec__foot {
  font-family: var(--font-mono);
  font-size: var(--t-meta);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--on-dark-mono);
  margin: 14px 0 0;
}

/* On a phone the nav is ~420px of its own, so tapping the first title
   updates a stage that is already off-screen. Below this the section
   drops the nav entirely and shows all six stacked with their
   artifacts — the same shape the no-JS fallback uses. */

@media (max-width: 980px) {
  .spec { grid-template-columns: 1fr; gap: 28px; }
  .spec__nav { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* On a phone the nav is ~420px of its own, so tapping the first title
   updates a stage that is already off-screen. Below this the section
   drops the nav entirely and shows every panel stacked with its
   artifact — the same shape the no-JS fallback uses. */
@media (max-width: 720px) {
  .spec__nav { display: none; }
  .spec.is-live .spec__stage { display: block; }
  .spec.is-live .spec__panel {
    grid-area: auto;
    visibility: visible;
    opacity: 1;
    pointer-events: auto;
    animation: none;
  }
  .spec.is-live .spec__panel + .spec__panel {
    margin-top: 30px;
    padding-top: 28px;
    border-top: 1px solid var(--stroke);
  }
  .spec__stage { padding: 24px 22px 26px; }
  .spec__track { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px 10px; }
  .spec__track li:nth-child(2)::after { display: none; }
}


/* --- the system map --------------------------------------------

   Laid out once at 1180×560 in absolute pixels — the wires are an
   SVG in the same coordinates, so nothing has to be measured to
   keep a line attached to a tile — and the whole stage is scaled to
   the container by js/how-it-works.js. Text scales with it.

   Light, to match the page (Jordan's call — the reference is dark).
   Dotted ground, solid accent nodes, dashed ink wires, tiles that
   empty and refill: the format is the reference; the content is how
   NOBL actually runs. NOBL OS in the centre stays dark — it's the
   product, and the site's product surfaces are dark.
   ---------------------------------------------------------------- */

.sysmap {
  color: var(--text);
  position: relative;
  aspect-ratio: 1180 / 560;
  overflow: hidden;
  border-radius: var(--r-card);
  background:
    radial-gradient(rgba(11,13,15,0.10) 1px, transparent 1.2px) 0 0 / 22px 22px,
    var(--bg);
  border: 1px solid var(--stroke);
}
.sysmap__stage {
  position: absolute;
  left: 0; top: 0;
  width: 1180px; height: 560px;
  transform-origin: 0 0;
  transform: scale(var(--k, 1));
}
.sysmap__stage > * { position: absolute; }

.sysmap__wires {
  left: 0; top: 0;
  width: 1180px; height: 560px;
  stroke: rgba(11,13,15,0.30);
  stroke-width: 1.2;
  stroke-dasharray: 3 5;
  overflow: visible;
}
/* a slow drift along every wire — traffic, not decoration */
.sysmap__wires path { animation: sysmapDrift 9s linear infinite; }
@keyframes sysmapDrift { to { stroke-dashoffset: -64; } }

.sysmap__pulse {
  fill: var(--accent);
  stroke: none;
  opacity: 0;
  filter: drop-shadow(0 0 5px rgba(62,107,135,0.7));
}
.sysmap.is-pulsing .sysmap__pulse { opacity: 1; }

/* --- labels --- */
.sysmap__label {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: var(--tr-meta);
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}
.sysmap__label--c { text-align: center; }

/* --- trays and tiles --- */
.sysmap__tray {
  display: flex;
  gap: 10px;
  padding: 10px;
  border-radius: var(--r-tile);
  background: var(--s2);
  border: 1px solid var(--stroke);
}
.sysmap__tray--grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-template-rows: repeat(3, 1fr);
}
.sysmap__tile {
  display: grid;
  place-items: center;
  flex: 1 1 0;
  min-width: 0;
  padding: 0 12px;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 600;
  line-height: 1.15;
  text-align: center;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--stroke-strong);
  border-radius: var(--r-button);
  white-space: nowrap;
  transition: background .35s var(--ease-out), border-color .35s var(--ease-out),
              color .35s var(--ease-out);
}
.sysmap__tray--grid .sysmap__tile { white-space: normal; font-size: 12px; padding: 0 8px; overflow-wrap: anywhere; }
/* emptied: the slot stays, dashed, until the next item lands */
.sysmap__tile.is-empty {
  background: transparent;
  border: 1px dashed var(--stroke-strong);
  color: transparent;
}

/* --- the solid nodes --- */
.sysmap__node {
  height: 40px;
  display: grid;
  place-items: center;
  font-family: var(--font-body);
  font-size: 13.5px;
  font-weight: 600;
  color: var(--accent-ink);
  background: var(--accent);
  border-radius: var(--r-button);
  white-space: nowrap;
}
.sysmap__node--record {
  background: var(--text);
  color: var(--bg);
}

/* --- NOBL OS --- */
.sysmap__core {
  width: 100px; height: 100px;
  display: grid;
  align-content: center;
  justify-items: center;
  gap: 4px;
  border-radius: var(--r-tile);
  background: linear-gradient(180deg, #1D2226, #141414);
  border: 1px solid var(--bw-18);
  box-shadow: 0 0 0 6px rgba(91,157,181,0.07), 0 0 40px -6px rgba(91,157,181,0.35);
}
.sysmap__core img { width: 34px; height: auto; margin-bottom: 4px; }
.sysmap__core b {
  font-family: var(--font-display);
  text-transform: uppercase;
  font-weight: 400;
  font-size: 15px;
  line-height: 1;
  letter-spacing: var(--tr-display);
  color: var(--on-dark-heading);
}
.sysmap__core i {
  font-family: var(--font-mono);
  font-style: normal;
  font-size: 7.5px;
  letter-spacing: var(--tr-chip);
  text-transform: uppercase;
  color: var(--on-dark-mono);
}

/* --- the deal --- */
.sysmap__deal {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-rows: auto auto;
  align-content: center;
  align-items: center;
  column-gap: 10px;
  row-gap: 4px;
  padding: 0 14px;
  border-radius: var(--r-card);
  background: var(--bg);
  border: 1px solid var(--stroke-strong);
  transition: border-color .4s var(--ease-out), box-shadow .4s var(--ease-out);
}
.sysmap__deal-id {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
}
.sysmap__deal-addr {
  grid-row: 2;
  grid-column: 1 / 3;
  font-size: 11px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sysmap__chip {
  grid-column: 2;
  grid-row: 1;
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: var(--tr-chip);
  text-transform: uppercase;
  padding: 5px 8px 4px;
  border-radius: var(--r-button);
  background: var(--s3);
  color: var(--body);
  transition: color .35s, background .35s;
}
/* the deal's four states — the light-mode versions of the OS mock's */
.sysmap__deal[data-state="signed"]    .sysmap__chip { color: var(--body); }
.sysmap__deal[data-state="scheduled"] .sysmap__chip { color: var(--gold-ink); background: var(--gold-soft); }
.sysmap__deal[data-state="installed"] .sysmap__chip { color: var(--accent); background: var(--accent-soft); }
.sysmap__deal[data-state="paid"]      .sysmap__chip { color: var(--text); background: var(--gold); }
.sysmap__deal.is-hot { border-color: var(--accent); box-shadow: 0 0 0 4px var(--accent-soft); }

/* --- the four roles, reading one record --- */
.sysmap__roles { display: flex; gap: 20px; }
.sysmap__role {
  flex: 1 1 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
  background: var(--s2);
  border: 1px solid var(--stroke);
  border-radius: var(--r-button);
  transition: color .35s, border-color .35s, background .35s;
}
.sysmap__role i {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--rule);
  transition: background .35s, box-shadow .35s;
}
.sysmap__role.is-lit { color: var(--text); border-color: var(--stroke-strong); background: var(--bg); }
.sysmap__role.is-lit i { background: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.sysmap[data-state="scheduled"] .sysmap__role.is-lit i { background: var(--gold); box-shadow: 0 0 0 3px var(--gold-soft); }
.sysmap[data-state="paid"]      .sysmap__role.is-lit i { background: var(--gold); box-shadow: 0 0 0 3px var(--gold-soft); }

/* Below this the stage would scale under 0.6 and the 13px tiles turn
   to 8px. The legend carries the section on a phone. */
@media (max-width: 720px) {
  .sysmap { display: none; }
  .roles__legend { margin-top: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .sysmap__wires path { animation: none; }
  .sysmap__pulse { display: none; }
}
