*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  --bg:      #141311;
  --surface: #1e1c19;
  --border:  #2c2925;
  --border2: #3a3631;
  --text:    #ededed;
  --dim:     #555555;
  --dim2:    #333333;
  --accent:  #8a6d3b;
  --sans:    'Inter', system-ui, sans-serif;
  --mono:    'JetBrains Mono', 'Fira Mono', monospace;
}

html, body {
  height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: var(--mono);
  font-size: 15px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/* ── SHELL ── */
.shell {
  min-height: 100vh;
  display: grid;
  grid-template-rows: auto 1fr auto;
  /* one column that may shrink below its content's natural width; without
     this a long <select> option or a wide table widens the whole page on a
     phone instead of wrapping or scrolling inside its own box */
  grid-template-columns: minmax(0, 1fr);
}

/* ── HEADER ── */
.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1.25rem 2rem;
  border-bottom: 1px solid var(--border);
}

.logo {
  font-family: var(--mono);
  font-size: 0.9rem;
  font-weight: 400;
  letter-spacing: 0.28em;
  color: var(--text);
  text-decoration: none;
}

.login-link, .logout-link,
.login-link:visited, .logout-link:visited {
  font-family: var(--mono);
  font-size: 1rem;
  letter-spacing: 0.1em;
  color: var(--dim);
  text-decoration: none;
  transition: color 0.15s;
}
.login-link:hover, .logout-link:hover { color: var(--text); }

/* ── FOOTER ── */
.site-footer {
  padding: 1rem 2rem;
  border-top: 1px solid var(--border);
  display: flex;
  justify-content: space-between;
  font-size: 0.62rem;
  color: var(--dim2);
  letter-spacing: 0.08em;
}

/* ══════════════════════════════
   LANDING — CAROUSEL
══════════════════════════════ */

.landing-header {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding: 2rem 2.5rem 0;
}

.landing-enter {
  font-family: var(--mono);
  font-size: 0.85rem;
  letter-spacing: 0.1em;
  color: var(--dim);
  text-decoration: none;
  display: inline-block;
  transition: color 0.2s;
}
.landing-enter:hover {
  color: var(--text);
}

/* the way through to the workshop (partials/header.html): a control, not a hint.
   The old rule was --dim on --bg (about 2.4:1), so the icon was there but
   effectively invisible; this gives it a surface, an edge and a 44px target. */
.landing-spanner {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border2);
  border-radius: 8px;
  text-decoration: none;
  transition: color 0.2s, border-color 0.2s, background 0.2s;
}
.landing-spanner:hover {
  color: var(--accent);
  border-color: var(--accent);
  background: #26231f;
}
.landing-spanner:focus-visible { outline: 2px solid var(--text); outline-offset: 3px; }
.landing-spanner svg { display: block; width: 22px; height: 22px; }

.wip-title {
  font-family: var(--mono);
  font-size: 0.95rem;
  font-weight: 400;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--text);
}

.landing-main {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 2rem 0 3rem;
  gap: 0;
  overflow: hidden;
}

/* focused video */
.carousel-stage {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  padding: 0 2rem;
}

.carousel-track {
  display: flex;
  align-items: center;
  gap: 1rem;
  width: 100%;
  max-width: 1100px;
  transition: none;
}

.carousel-item {
  flex-shrink: 0;
  cursor: pointer;
  position: relative;
  transition: width 0.45s cubic-bezier(0.4,0,0.2,1),
              opacity 0.45s cubic-bezier(0.4,0,0.2,1),
              transform 0.3s cubic-bezier(0.4,0,0.2,1);
}

.carousel-item.active {
  width: 60%;
  opacity: 1;
}

.carousel-item.side {
  width: 12%;
  opacity: 0.85;
}

.carousel-item.side:hover {
  opacity: 1;
  transform: scale(1.02);
}

.carousel-item video,
.carousel-item .carousel-placeholder {
  width: 100%;
  aspect-ratio: 16/9;
  display: block;
  object-fit: cover;
  background: var(--surface);
  border-radius: 8px;
}

.carousel-item .carousel-still {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 8px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
}

.carousel-item.side .carousel-still {
  opacity: 1;
}

.carousel-item.active .carousel-still {
  opacity: 0;
}

.carousel-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 16/9;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
}

.carousel-placeholder span {
  font-size: 0.6rem;
  letter-spacing: 0.12em;
  color: var(--dim2);
  text-transform: uppercase;
}

/* ══════════════════════════════
   LOGIN
══════════════════════════════ */

.login-main {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
}

.gate-form {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  width: 200px;
}

.gate-form input {
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--border2);
  color: var(--text);
  font-family: var(--mono);
  font-size: 0.75rem;
  padding: 0.5rem 0;
  outline: none;
  letter-spacing: 0.05em;
  transition: border-color 0.2s;
  -webkit-appearance: none;
  border-radius: 0;
}
.gate-form input:focus { border-bottom-color: var(--text); }
.gate-form input::placeholder { color: var(--dim2); }

.gate-form button {
  background: transparent;
  border: none;
  color: var(--dim);
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.15em;
  padding: 0.6rem 0 0;
  cursor: pointer;
  text-align: right;
  transition: color 0.15s;
}
.gate-form button:hover { color: var(--text); }

.gate-error {
  font-size: 0.62rem;
  color: var(--dim);
  letter-spacing: 0.08em;
  text-align: right;
  padding-top: 0.25rem;
}

/* ══════════════════════════════
   HOME
══════════════════════════════ */

.home-main {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 3rem 2rem;
  gap: 1rem;
  min-height: calc(100vh - 120px);
}

.card-grid {
  display: flex;
  gap: 2px;
  width: 100%;
  max-width: 860px;
}

.access-card {
  flex: 1;
  padding: 2rem 1.5rem;
  text-decoration: none;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  border-right: 1px solid var(--border);
  transition: background 0.2s;
}

.access-card:last-child { border-right: none; }

.access-card:hover {
  background: var(--surface);
}

.access-card.locked {
  opacity: 0.2;
  pointer-events: none;
}

.card-label {
  font-size: 0.58rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--dim);
}

.card-title {
  font-family: var(--sans);
  font-size: 1.4rem;
  font-weight: 400;
  color: var(--text);
  line-height: 1.2;
  letter-spacing: -0.01em;
}

.card-desc {
  font-size: 1rem;
  color: var(--dim);
  line-height: 1.65;
  flex: 1;
}

.card-arrow {
  font-size: 1rem;
  color: var(--dim2);
  align-self: flex-end;
}

/* ══════════════════════════════
   DEVELOPER AREA
══════════════════════════════ */

.dev-main {
  padding: 2.5rem 2rem 4rem;
  /* full width up to the cap: centred with auto margins alone, it would
     size itself to its widest child and push past a phone's screen */
  width: 100%;
  max-width: 1040px;
  margin: 0 auto;
}

.dev-eyebrow {
  font-size: 0.58rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--dim);
  margin-bottom: 0.4rem;
}

.dev-heading {
  font-family: var(--sans);
  font-size: 1.4rem;
  font-weight: 400;
  color: var(--text);
  letter-spacing: -0.02em;
  margin-bottom: 2rem;
}

/* tabs */
.tab-bar {
  display: flex;
  border-bottom: 1px solid var(--border);
  margin-bottom: 2.5rem;
}

.tab-btn {
  background: none;
  border: none;
  border-bottom: 1px solid transparent;
  margin-bottom: -1px;
  padding: 0.5rem 1rem;
  font-family: var(--mono);
  font-size: 0.78rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dim);
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s;
}
.tab-btn:hover { color: var(--text); }
.tab-btn.active { color: var(--text); border-bottom-color: var(--text); }

.tab-panel { display: none; }
.tab-panel.active { display: block; }

/* principle cards */
.principles-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 0;
  border-top: 1px solid var(--border);
  border-left: 1px solid var(--border);
}

.principle-card {
  padding: 1.75rem 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  border-right: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}

.principle-label {
  font-size: 0.78rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--dim);
}

.principle-title {
  font-family: var(--sans);
  font-size: 1.15rem;
  font-weight: 400;
  color: var(--text);
  letter-spacing: -0.01em;
  line-height: 1.25;
}

.principle-body {
  font-size: 0.95rem;
  color: var(--dim);
  line-height: 1.75;
  flex: 1;
}

.principle-lineage {
  font-size: 0.82rem;
  color: var(--dim2);
  line-height: 1.6;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border);
}

/* protocols */
.protocols-intro {
  font-size: 0.72rem;
  color: var(--dim);
  line-height: 1.75;
  max-width: 640px;
  margin-bottom: 2rem;
}

.proto-section { margin-bottom: 2rem; }

.proto-section-heading {
  font-size: 1rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--dim);
  margin-bottom: 0.75rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--border);
}

.proto-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 0;
  border-top: 1px solid var(--border);
  border-left: 1px solid var(--border);
}

.proto-item {
  padding: 1rem 1.25rem;
  border-right: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}

.proto-item-name {
  font-size: 0.95rem;
  color: var(--text);
  margin-bottom: 0.2rem;
}

.proto-item-kind {
  font-size: 0.78rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dim);
  margin-bottom: 0.35rem;
}

.proto-item-desc {
  font-size: 0.9rem;
  color: var(--dim);
  line-height: 1.6;
}

.proto-item-caveat {
  display: inline-block;
  font-family: var(--mono);
  font-size: 0.68rem;
  color: var(--accent);
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0.04em;
  border: 1px solid var(--accent);
  border-radius: 2px;
  padding: 0.05rem 0.4rem;
  margin-left: 0.3rem;
}

.proto-item-link,
.proto-item-link:visited {
  display: inline-block;
  margin-top: 0.6rem;
  font-size: 0.72rem;
  color: var(--dim2);
  text-decoration: none;
  letter-spacing: 0.08em;
  transition: color 0.15s;
}
.proto-item-link:hover { color: var(--text); }

/* repos */
.repo-grid { display: grid; gap: 0; border-top: 1px solid var(--border); }

.repo-card {
  padding: 1.5rem 0;
  display: grid;
  grid-template-columns: 140px 1fr auto;
  grid-template-rows: auto auto;
  gap: 0.3rem 2rem;
  align-items: start;
  border-bottom: 1px solid var(--border);
}

.repo-card.primary .repo-name { color: var(--text); }

.repo-name {
  font-size: 0.9rem;
  color: var(--dim);
  letter-spacing: 0.06em;
  grid-column: 1;
  grid-row: 1;
  align-self: start;
  padding-top: 0.1rem;
}

.repo-implements {
  font-size: 1rem;
  letter-spacing: 0.1em;
  color: var(--dim2);
  text-transform: uppercase;
  grid-column: 1;
  grid-row: 2;
}

.repo-desc {
  font-size: 0.95rem;
  color: var(--dim);
  line-height: 1.7;
  grid-column: 2;
  grid-row: 1 / 3;
  max-width: 560px;
}

.repo-desc code {
  font-family: var(--mono);
  background: var(--surface);
  color: var(--text);
  padding: 0.1rem 0.35rem;
  border-radius: 2px;
  font-size: 0.85em;
  border: 1px solid var(--border2);
}

.repo-link,
.repo-link:visited {
  grid-column: 3;
  grid-row: 1;
  font-size: 0.72rem;
  color: var(--dim2);
  text-decoration: none;
  letter-spacing: 0.08em;
  white-space: nowrap;
  transition: color 0.15s;
  padding-top: 0.1rem;
}
.repo-link:hover { color: var(--text); }

/* ── RESPONSIVE ── */
@media (max-width: 700px) {
  .carousel-item.active { width: 80%; }
  .carousel-item.side { width: 8%; }
  .card-grid { flex-direction: column; gap: 0; }
  .access-card { border-right: none; border-bottom: 1px solid var(--border); }
  .repo-card { grid-template-columns: 1fr auto; }
  .repo-desc { grid-column: 1; grid-row: 3; }
  .repo-implements { grid-row: 2; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
}

/* ══════════════════════════════
   APIS TAB
══════════════════════════════ */

/* intro line */
.apis-intro {
  font-size: 0.9rem;
  color: var(--dim);
  line-height: 1.75;
  max-width: 640px;
  margin-bottom: 2.5rem;
  padding-bottom: 1.5rem;
  border-bottom: 1px solid var(--border);
}

/* API service cards */
.api-grid {
  display: grid;
  gap: 0;
  border-top: 1px solid var(--border);
  margin-bottom: 3rem;
}

.api-card {
  padding: 1.5rem 0;
  display: grid;
  grid-template-columns: 160px 1fr auto;
  grid-template-rows: auto auto;
  gap: 0.3rem 2rem;
  align-items: start;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background 0.15s;
}

.api-card:hover { background: var(--surface); }
.api-card.open  { background: var(--surface); }

.api-card-name {
  font-size: 0.9rem;
  color: var(--text);
  letter-spacing: 0.06em;
  grid-column: 1;
  grid-row: 1;
  padding-top: 0.1rem;
}

.api-card-kind {
  font-size: 0.78rem;
  letter-spacing: 0.1em;
  color: var(--dim2);
  text-transform: uppercase;
  grid-column: 1;
  grid-row: 2;
}

.api-card-desc {
  font-size: 0.95rem;
  color: var(--dim);
  line-height: 1.7;
  grid-column: 2;
  grid-row: 1 / 3;
  max-width: 560px;
}

.api-card-toggle {
  grid-column: 3;
  grid-row: 1;
  font-size: 0.72rem;
  color: var(--dim2);
  letter-spacing: 0.08em;
  white-space: nowrap;
  padding-top: 0.1rem;
  transition: color 0.15s;
  user-select: none;
}
.api-card:hover .api-card-toggle { color: var(--text); }

/* swagger drawer */
.swagger-drawer {
  display: none;
  grid-column: 1 / -1;
  border-top: 1px solid var(--border);
  padding: 1.5rem 0 0.5rem;
  margin-top: 0.75rem;
}
.api-card.open .swagger-drawer { display: block; }

.swagger-heading {
  font-size: 0.62rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--dim2);
  margin-bottom: 1rem;
}

.endpoint-list { display: flex; flex-direction: column; gap: 0.4rem; }

.endpoint {
  display: grid;
  grid-template-columns: 64px 1fr auto;
  gap: 0 1rem;
  align-items: start;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--border);
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}
.endpoint:hover { border-color: var(--border2); background: #1c1a17; }
.endpoint.ep-open { border-color: var(--border2); background: #1c1a17; }

.ep-method {
  font-size: 0.72rem;
  font-weight: 400;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding-top: 0.05rem;
}
.ep-method.get    { color: #4a9eff; }
.ep-method.post   { color: #3dd68c; }
.ep-method.head   { color: #b88cff; }

.ep-path {
  font-size: 0.82rem;
  color: var(--text);
  letter-spacing: 0.02em;
  line-height: 1.4;
}
.ep-path .ep-param { color: #4a9eff; }

.ep-summary {
  font-size: 0.78rem;
  color: var(--dim);
  text-align: right;
  padding-top: 0.05rem;
  white-space: nowrap;
}

/* expanded endpoint detail */
.ep-detail {
  display: none;
  grid-column: 1 / -1;
  padding: 0.75rem 0 0.25rem;
  border-top: 1px solid var(--border);
  margin-top: 0.5rem;
}
.endpoint.ep-open .ep-detail { display: block; }

.ep-desc {
  font-size: 0.88rem;
  color: var(--dim);
  line-height: 1.7;
  margin-bottom: 0.75rem;
}

.ep-params-heading {
  font-size: 0.62rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--dim2);
  margin-bottom: 0.5rem;
}

.ep-param-row {
  display: grid;
  grid-template-columns: 160px 80px 1fr;
  gap: 0 1rem;
  padding: 0.3rem 0;
  border-top: 1px solid var(--border);
  font-size: 0.82rem;
}
.ep-param-name { color: var(--text); }
.ep-param-type { color: var(--dim2); font-size: 0.75rem; padding-top: 0.06rem; }
.ep-param-desc { color: var(--dim); }

.ep-response-heading {
  font-size: 0.62rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--dim2);
  margin-top: 0.75rem;
  margin-bottom: 0.5rem;
}

.ep-response-block {
  background: #0c0b0a;
  border: 1px solid var(--border);
  padding: 0.75rem 1rem;
  font-size: 0.78rem;
  color: #3dd68c;
  line-height: 1.7;
  overflow-x: auto;
  white-space: pre;
}

/* repo card GitHub link + schema link */
.repo-schema-link,
.repo-schema-link:visited {
  display: block;
  margin-top: 0.75rem;
  font-size: 0.72rem;
  color: var(--dim2);
  text-decoration: none;
  letter-spacing: 0.08em;
  transition: color 0.15s;
}
.repo-schema-link:hover { color: var(--text); }

/* expandable repo cards (code example drawer) */
.repo-expand-toggle {
  grid-column: 1;
  grid-row: 3;
  font-size: 0.72rem;
  color: var(--dim2);
  letter-spacing: 0.08em;
  cursor: pointer;
  user-select: none;
  padding-top: 0.5rem;
  transition: color 0.15s;
}
.repo-card--expandable:hover .repo-expand-toggle { color: var(--text); }

.repo-code-drawer { display: none; grid-column: 1 / -1; }
.repo-card--expandable.open .repo-code-drawer { display: block; }
.repo-card--expandable.open .repo-expand-toggle { color: var(--text); }

.repo-code {
  margin-top: 0.75rem;
  background: #0c0b0a;
  border: 1px solid var(--border);
  padding: 0.75rem 1rem;
  font-size: 0.78rem;
  color: #3dd68c;
  line-height: 1.7;
  overflow-x: auto;
  white-space: pre;
  display: block;
}

@media (max-width: 700px) {
  .api-card { grid-template-columns: 1fr auto; }
  .api-card-desc { grid-column: 1; grid-row: 3; }
  .api-card-kind { grid-row: 2; }
  .endpoint { grid-template-columns: 54px 1fr; }
  .ep-summary { display: none; }
  .ep-param-row { grid-template-columns: 120px 1fr; }
  .ep-param-type { display: none; }
}

/* ══════════════════════════════
   HOME — VORTEX BAND
══════════════════════════════ */

.vortex-band {
  position: relative;
  height: 160px;
  overflow: hidden;
  background: var(--bg);
}
.vortex-band canvas#vortex {
  display: block;
  width: 100%;
  height: 100%;
}

/* ══════════════════════════════
   REPO ACTIONS + READABILITY
   (appended last so it wins on source order; grid-aware overrides
    of the base .repo-link / .repo-expand-toggle)
══════════════════════════════ */

/* Lift the text off the background — the base greys sit too close to --bg */
.repo-desc       { color: var(--body); }       /* was var(--dim)  #555 */
.repo-implements { color: var(--dim); }        /* was var(--dim2) #333 */

/* Primary CTA — the actual repo. Filled accent button, dark text. */
.repo-card > .repo-link,
.repo-card > .repo-link:visited {
  align-self: center;
  justify-self: end;
  display: inline-block;
  padding: 0.65rem 1.35rem;
  font-size: 1rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--bg);
  background: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 4px;
  white-space: nowrap;
  transition: filter 0.15s, transform 0.15s;
}
.repo-card > .repo-link:hover {
  color: var(--bg);
  filter: brightness(1.2);
  transform: translateY(-1px);
}

/* Secondary CTA — reveal the code. Outlined accent button. */
.repo-card--expandable > .repo-expand-toggle {
  justify-self: start;
  align-self: center;
  display: inline-block;
  margin-top: 0.75rem;
  padding: 0.65rem 1.35rem;
  font-size: 1rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--accent);
  background: transparent;
  border: 1px solid var(--accent);
  border-radius: 4px;
  transition: background 0.15s, color 0.15s;
}
.repo-card--expandable:hover > .repo-expand-toggle,
.repo-card--expandable > .repo-expand-toggle:hover {
  color: var(--text);
  background: rgba(138, 109, 59, 0.16);
}

/* Coming-soon — same footprint as the GitLab button, but muted + outlined
   so it reads as the pending version of the pill, not a clickable one. */
.repo-card > .repo-status {
  grid-column: 3;
  grid-row: 1;
  align-self: center;
  justify-self: end;
  font-size: 1rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--dim);
  background: transparent;
  border: 1px solid var(--border2);
  border-radius: 4px;
  padding: 0.65rem 1.35rem;
  white-space: nowrap;
  pointer-events: none;
}

/* keep the buttons placed sensibly on the 2-col mobile grid */
@media (max-width: 700px) {
  .repo-card > .repo-link,
  .repo-card > .repo-status { grid-column: 2; }
  .repo-card--expandable > .repo-expand-toggle { grid-column: 1; grid-row: 4; }
}

/* ══════════════════════════════
   SITE CONTRAST — lift text off the near-black background
   (appended last; the same lift applied to the repos tab, site-wide)
══════════════════════════════ */

:root {
  --body: #a29a8d;   /* readable body copy — the greys were sitting on --bg */
  --dim2: #6b665c;   /* quiet labels / idle links — was #333, near-invisible */
  --bad:  #c98a7e;   /* a refusal, a failure, an empty battery */
}

/* Body copy across every tab → the readable warm grey */
.principle-body,
.card-desc,
.proto-item-desc,
.api-card-desc,
.apis-intro,
.protocols-intro,
.ep-desc,
.ep-param-desc {
  color: var(--body);
}

/* ══════════════════════════════
   REPO PAPER / STANDARD LINK
   quiet secondary reference under the GitLab button (or Coming-soon chip)
══════════════════════════════ */
.repo-card > .repo-paper,
.repo-card > .repo-paper:visited {
  grid-column: 3;
  grid-row: 2;
  justify-self: end;
  align-self: start;
  margin-top: 0.6rem;
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  color: var(--dim2);
  text-decoration: none;
  white-space: nowrap;
  transition: color 0.15s;
}
.repo-card > .repo-paper:hover { color: var(--text); }

@media (max-width: 700px) {
  .repo-card > .repo-paper { grid-column: 2; grid-row: 2; justify-self: start; }
}

/* ══════════════════════════════
   SOLUTIONS
══════════════════════════════ */

/* three cards need more room than the original two */
.card-grid:has(> .access-card:nth-child(3)) { max-width: 900px; }

/* ── HERO: the loop, and four words ── */
.solutions-hero {
  min-height: 68vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  padding-bottom: 3rem;
  margin-bottom: 3.5rem;
  border-bottom: 1px solid var(--border);
}

.solutions-hero-title {
  font-family: var(--sans);
  font-size: clamp(1.8rem, 4vw, 2.6rem);
  font-weight: 400;
  letter-spacing: -0.02em;
  color: var(--text);
  margin-bottom: 2.5rem;
}

.loop-figure {
  width: 100%;
  max-width: 560px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 1.5rem 1rem;

  /* Loop-local tokens, mapped from the site palette. The reference used a
     blue accent; everything here derives from the gold and warm greys so the
     diagram sits inside the page rather than on top of it.

     The idle weights sit two steps above --border on purpose: the previous
     values (#2c2925 stroke on a #1e1c19 card) were the same colour to the
     eye, so the diagram read as a black box with a few gold dots. */
  --node-off:   var(--dim2);
  --node-on:    var(--accent);
  --node-glow:  rgba(138, 109, 59, 0.55);
  --edge-live:  rgba(138, 109, 59, 0.5);
  --edge-idle:  var(--border2);
  --box-stroke: var(--border2);
}

/* The SVG carries only a viewBox, so derive its height explicitly rather
   than relying on the browser inferring an intrinsic ratio from it. Without
   this the element can collapse to zero height and the figure renders as an
   empty dark panel. */
.loop-figure svg {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 600 / 360;
}

/* ── cluster boundaries ── */
.cluster-box {
  fill: rgba(255, 255, 255, 0.02);
  stroke: var(--box-stroke);
  stroke-width: 1;
  stroke-dasharray: 4 4;
  rx: 8;
}

.cluster-label {
  fill: var(--body);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  text-anchor: middle;
}

/* ── edges inside a cluster: live ones flow, idle ones don't ── */
.network-edge {
  stroke: var(--edge-idle);
  stroke-width: 1;
}
.network-edge.active {
  stroke: var(--edge-live);
  stroke-width: 1.5;
  stroke-dasharray: 4 4;
  animation: internalFlow 3s linear infinite;
}
@keyframes internalFlow { to { stroke-dashoffset: -16; } }

/* ── the loop between clusters ── */
.inter-cluster-edge {
  stroke: var(--border2);
  stroke-width: 1.5;
  stroke-dasharray: 6 4;
  animation: flowDash 20s linear infinite;
}
@keyframes flowDash { to { stroke-dashoffset: -100; } }

/* ── nodes, on and off ── */
.sub-node {
  fill: var(--node-off);
  transition: fill 0.4s, filter 0.4s;
}
.sub-node.active {
  fill: var(--node-on);
  filter: drop-shadow(0 0 6px var(--node-glow));
}

.packet {
  fill: var(--text);
  filter: drop-shadow(0 0 8px var(--node-glow));
}

/* motion is decoration; drop it for readers who ask */
@media (prefers-reduced-motion: reduce) {
  .network-edge.active,
  .inter-cluster-edge { animation: none; }
  .packet { display: none; }
}

/* ── THE ARGUMENT, REVEALED ON SCROLL ── */
.solutions-intro {
  font-size: 0.95rem;
  color: var(--body);
  line-height: 1.8;
  max-width: 640px;
  margin-bottom: 1.4rem;
}

.solutions-lead {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dim);
  max-width: 640px;
  margin: 2.5rem 0 1rem;
}

.levels {
  list-style: none;
  max-width: 640px;
  display: grid;
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
  margin-bottom: 2.5rem;
}

.levels li {
  display: grid;
  grid-template-columns: 2.5rem 1fr auto;
  gap: 1rem;
  align-items: baseline;
  background: var(--bg);
  padding: 0.85rem 1rem;
  font-family: var(--mono);
  font-size: 0.85rem;
}

.lvl-n { color: var(--accent); }
.lvl-v { color: var(--text); }
.lvl-d { color: var(--body); font-size: 0.8rem; text-align: right; }

.solutions-claim {
  font-size: 1rem;
  color: var(--text);
  max-width: 640px;
  margin: 0 0 3rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border);
}

/* ── TOOLING COMPARISON ── */
.solutions-table-wrap { overflow-x: auto; }

.solutions-table {
  border-collapse: collapse;
  width: 100%;
  font-size: 0.9rem;
}

.solutions-table th,
.solutions-table td {
  text-align: left;
  padding: 0.6rem 0.9rem;
  border-bottom: 1px solid var(--border);
}

.solutions-table th {
  font-size: 0.62rem;
  font-weight: 400;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--dim);
  white-space: nowrap;
  border-bottom: 1px solid var(--border2);
}

.solutions-table td { color: var(--body); }
.solutions-table td:first-child { color: var(--text); }
.solutions-table td:last-child { color: var(--dim); white-space: nowrap; }

.solutions-table .solutions-total td {
  color: var(--text);
  font-weight: 500;
  border-top: 1px solid var(--border2);
  border-bottom: none;
}

@media (max-width: 700px) {
  .solutions-hero { min-height: 56vh; }
  .levels li { grid-template-columns: 2.2rem 1fr; }
  .lvl-d { grid-column: 2; text-align: left; }
}

/* ══════════════════════════════
   SOLUTIONS — TRAINING PLANNER
══════════════════════════════ */

/* a card that leaves the page rather than opening a drawer */
.api-card--link { text-decoration: none; }

.planner-intro {
  font-size: 0.9rem;
  color: var(--body);
  line-height: 1.75;
  max-width: 640px;
  margin-bottom: 2.5rem;
  padding-bottom: 1.5rem;
  border-bottom: 1px solid var(--border);
}

.planner-step { margin-bottom: 2.5rem; }

.planner-step-title {
  font-family: var(--mono);
  font-size: 0.62rem;
  font-weight: 400;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--dim2);
  margin-bottom: 1rem;
}

/* one hairline grid, same joinery as .levels and .principles-grid */
.planner-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
}

.planner-check {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  padding: 0.85rem 1rem;
  background: var(--bg);
  cursor: pointer;
  transition: background 0.15s;
}
.planner-check:hover { background: var(--surface); }

.planner-check input {
  appearance: none;
  -webkit-appearance: none;
  flex: none;
  position: relative;
  width: 14px;
  height: 14px;
  margin: 0.3rem 0 0;
  border: 1px solid var(--border2);
  border-radius: 2px;
  background: transparent;
  cursor: pointer;
  transition: border-color 0.15s;
}
.planner-check input:checked { border-color: var(--accent); }
.planner-check input:checked::after {
  content: "";
  position: absolute;
  inset: 2px;
  background: var(--accent);
}
.planner-check input:focus-visible {
  outline: 1px solid var(--text);
  outline-offset: 2px;
}

.planner-check-text { display: flex; flex-direction: column; gap: 0.1rem; }
.planner-check-name { font-size: 0.85rem; color: var(--text); }
.planner-check-role { font-family: var(--mono); font-size: 0.72rem; color: var(--dim2); }

.planner-select {
  width: 100%;
  max-width: 640px;
  appearance: none;
  -webkit-appearance: none;
  background: var(--surface);
  border: 1px solid var(--border2);
  border-radius: 6px;
  color: var(--text);
  font-family: var(--mono);
  font-size: 0.8rem;
  padding: 0.75rem 1rem;
  cursor: pointer;
}
.planner-select:focus { outline: none; border-color: var(--accent); }

.planner-note {
  font-size: 0.72rem;
  color: var(--dim2);
  line-height: 1.6;
  max-width: 640px;
  margin-top: 0.6rem;
}

@media (max-width: 700px) {
  .planner-grid { grid-template-columns: 1fr; }
}

/* ── SOLUTIONS LANDING: the statement, then two links ── */
.solutions-statement {
  font-family: var(--sans);
  font-size: 1.05rem;
  color: var(--text);
  max-width: 640px;
  margin-bottom: 1.4rem;
}

.solutions-links {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin-top: 1rem;
}

.solutions-links a,
.solutions-links a:visited {
  font-family: var(--mono);
  font-size: 0.85rem;
  letter-spacing: 0.08em;
  color: var(--text);
  text-decoration: none;
  border: 1px solid var(--border2);
  border-radius: 4px;
  padding: 0.65rem 1.35rem;
  transition: border-color 0.15s, color 0.15s;
}
.solutions-links a:hover {
  color: var(--accent);
  border-color: var(--accent);
}

/* ══════════════════════════════
   SOLUTIONS — MATURITY REVEAL
   native <details>: no JS, keyboard-accessible for free
══════════════════════════════ */

.maturity {
  max-width: 640px;
  margin: 0 0 2.4rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg);
  overflow: hidden;
}

.maturity-summary {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.9rem 1rem;
  cursor: pointer;
  list-style: none;                 /* kill the default disclosure triangle */
  transition: background 0.15s;
}
.maturity-summary::-webkit-details-marker { display: none; }
.maturity-summary:hover { background: var(--surface); }
.maturity-summary:focus-visible { outline: 1px solid var(--text); outline-offset: -1px; }

.maturity-title {
  font-family: var(--mono);
  font-size: 0.85rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dim);
}

/* the &rarr; doubles as the affordance: rotates to point down when open */
.maturity-caret {
  flex: none;
  font-family: var(--mono);
  font-size: 0.95rem;
  color: var(--dim2);
  transition: transform 0.2s, color 0.15s;
}
.maturity-summary:hover .maturity-caret { color: var(--text); }
.maturity[open] .maturity-caret { transform: rotate(90deg); color: var(--accent); }

/* the stage blurbs are full sentences, so they take the whole row instead of
   the nowrap right-hand column .levels uses for its short descriptors */
.maturity-levels {
  border: none;
  border-radius: 0;
  margin: 0;
  /* .levels draws its dividers as a 1px grid gap backed by --border, which
     sits on the same pixel as our li border-top and swallows it. Collapse the
     gap so the row borders are the only line at each seam. */
  gap: 0;
}
.maturity-levels li {
  grid-template-columns: 2.5rem 1fr;
  border-top: 1px solid var(--border);
  padding: 0.9rem 1rem;
}
/* the box already provides the top edge; a row border here would double it */
.maturity-levels li:first-child { border-top: none; }

/* larger stage names; the number tracks them so the row stays aligned */
.maturity-levels .lvl-n { font-size: 1.25rem; }
.maturity-levels .lvl-v { font-size: 1.25rem; }

/* condensed blurbs: tighter leading, slight negative tracking, pulled up
   under the name rather than floating in a narrow right-hand column */
.maturity-levels .lvl-d {
  grid-column: 2;
  text-align: left;
  font-size: 1rem;
  line-height: 1.4;
  letter-spacing: -0.015em;
  max-width: 58ch;
  margin-top: 0.25rem;
}

/* the seam between development-side stages (01–02) and production-side
   stages (03–05). Stays in the same neutral family as the other seams and
   steps up exactly one shade (--border → --border2): a gold/accent line here
   reads as a different kind of rule, not the same one emphasised. */
.maturity-levels li.maturity-split {
  border-top-color: var(--border2);
}

/* ══════════════════════════════
   SOLUTIONS — DEPLOYMENT — THE BOARD
   A worked example. It keeps the page's palette and type, and runs its
   own board surfaces so a reader can tell it apart from the site chrome
   and read it as a demonstration rather than a live screen.
══════════════════════════════ */

/* the opening statement, set as a quotation */
.deploy-quote {
  max-width: 640px;
  margin: 0 0 2.5rem;
  padding: 0.15rem 0 0.15rem 1.25rem;
  border-left: 2px solid var(--accent);
}
.deploy-quote p {
  font-family: var(--sans);
  font-size: 1.05rem;
  font-style: italic;
  line-height: 1.7;
  color: var(--text);
}

/* two short explanations, side by side */
.deploy-split {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: 1.5rem 2.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border);
}
.deploy-split h2 {
  font-family: var(--mono);
  font-size: 0.82rem;
  font-weight: 400;
  letter-spacing: 0.08em;
  color: var(--text);
  margin-bottom: 0.6rem;
}
.deploy-split p {
  font-size: 0.92rem;
  line-height: 1.75;
  color: var(--body);
}

/* the one-line result */
.deploy-callout {
  display: flex;
  gap: 0.7rem;
  align-items: flex-start;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.85rem 1rem;
  margin: 2rem 0 2.5rem;
  font-family: var(--mono);
  font-size: 0.75rem;
  line-height: 1.65;
  color: var(--body);
}
.deploy-callout strong { font-weight: 400; color: var(--text); }

/* the four areas under watch */
.deploy-sites {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1rem;
}
.deploy-site {
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--body);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0.3rem 0.7rem;
  white-space: nowrap;
}

.deploy-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem 1rem;
  margin-bottom: 0.9rem;
}
.deploy-bar h2 {
  font-family: var(--sans);
  font-size: 1.05rem;
  font-weight: 400;
  color: var(--text);
}
.deploy-bar button {
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--dim);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  transition: color 0.15s;
}
.deploy-bar button:hover { color: var(--text); }

/* ── the four columns ── */
.deploy-board {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 215px), 1fr));
  gap: 0.75rem;
  align-items: start;
}
.deploy-col {
  background: rgba(255, 255, 255, 0.02);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.7rem;
  display: grid;
  gap: 0.6rem;
  align-content: start;
  min-height: 210px;
}
.deploy-col-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--border);
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dim);
}
.deploy-count {
  font-family: var(--mono);
  font-size: 0.62rem;
  color: var(--body);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 0 0.35rem;
}
.deploy-cards {
  display: grid;
  gap: 0.5rem;
  align-content: start;
  min-height: 100px;
}
.deploy-cards.over {
  outline: 1px dashed var(--accent);
  outline-offset: 3px;
}

/* ── a case ── */
.deploy-card {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0.6rem 0.7rem;
  display: grid;
  gap: 0.4rem;
  cursor: pointer;
  transition: border-color 0.15s;
}
.deploy-card:hover { border-color: var(--border2); }
.deploy-card.dragging { opacity: 0.4; }

.deploy-card-top {
  display: flex;
  justify-content: space-between;
  gap: 0.5rem;
  font-family: var(--mono);
  font-size: 0.62rem;
  color: var(--dim);
}
.deploy-card-top b { font-weight: 400; color: var(--body); }

.deploy-card-title {
  font-family: var(--sans);
  font-size: 0.85rem;
  font-weight: 400;
  line-height: 1.35;
  color: var(--text);
}

.deploy-card-foot {
  display: flex;
  justify-content: space-between;
  gap: 0.5rem;
  padding-top: 0.45rem;
  border-top: 1px solid var(--border);
  font-family: var(--mono);
  font-size: 0.62rem;
  color: var(--dim);
}

/* ── the card, opened ── */
.deploy-modal {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  background: rgba(8, 7, 6, 0.75);
}
.deploy-modal[hidden] { display: none; }

.deploy-modal-box {
  position: relative;
  width: 100%;
  max-width: 540px;
  max-height: calc(100vh - 2rem);
  overflow: auto;
  background: var(--bg);
  border: 1px solid var(--border2);
  border-radius: 8px;
  padding: 1.25rem;
  display: grid;
  gap: 1rem;
}
.deploy-modal-close {
  position: absolute;
  top: 0.9rem;
  right: 1rem;
  background: none;
  border: 0;
  color: var(--dim);
  font-family: var(--mono);
  font-size: 0.9rem;
  line-height: 1;
  cursor: pointer;
}
.deploy-modal-close:hover { color: var(--text); }

.deploy-modal-head { display: grid; gap: 0.35rem; padding-right: 1.5rem; }
.deploy-modal-head h3 {
  font-family: var(--sans);
  font-size: 1.15rem;
  font-weight: 400;
  line-height: 1.3;
  color: var(--text);
}

/* the frame the case was seen in */
.deploy-frame {
  position: relative;
  height: 11rem;
  border: 1px solid var(--border2);
  border-radius: 5px;
  background: #0c0b0a;
  display: grid;
  place-items: center;
}
.deploy-frame-mark {
  display: grid;
  gap: 0.3rem;
  width: 46%;
  height: 58%;
  padding: 0.35rem;
  border: 1px dashed var(--accent);
  border-radius: 3px;
  font-family: var(--mono);
  font-size: 0.6rem;
  color: var(--accent);
  align-content: space-between;
}
.deploy-frame-tag {
  position: absolute;
  bottom: 0.5rem;
  right: 0.6rem;
  font-family: var(--mono);
  font-size: 0.6rem;
  color: var(--dim);
}

.deploy-kv {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 0.7rem 1rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 0.8rem 0.9rem;
}
.deploy-kv dt {
  font-family: var(--mono);
  font-size: 0.58rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dim);
  margin-bottom: 0.2rem;
}
.deploy-kv dd { margin: 0; font-size: 0.85rem; color: var(--text); }

.deploy-field { display: grid; gap: 0.35rem; }
.deploy-field label {
  font-family: var(--mono);
  font-size: 0.58rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dim);
}
.deploy-field textarea {
  width: 100%;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 0.55rem 0.7rem;
  font-family: var(--mono);
  font-size: 0.78rem;
  line-height: 1.6;
  color: var(--text);
  resize: vertical;
}
.deploy-field textarea:focus { outline: none; border-color: var(--accent); }
.deploy-brief {
  font-size: 0.88rem;
  line-height: 1.7;
  color: var(--body);
}

.deploy-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  justify-content: flex-end;
  padding-top: 0.9rem;
  border-top: 1px solid var(--border);
}
.deploy-actions button {
  font-family: var(--mono);
  font-size: 0.72rem;
  border-radius: 4px;
  padding: 0.45rem 0.9rem;
  cursor: pointer;
  background: var(--accent);
  border: 1px solid var(--accent);
  color: var(--bg);
  transition: filter 0.15s;
}
.deploy-actions button:hover { filter: brightness(1.15); }
.deploy-actions span {
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--accent);
  align-self: center;
}

.deploy-strip {
  margin-top: 1rem;
  font-family: var(--mono);
  font-size: 0.68rem;
  color: var(--dim2);
}

@media (max-width: 700px) {
  .deploy-board { grid-template-columns: minmax(0, 1fr); }
  .deploy-col { min-height: 0; }
}

/* ══════════════════════════════
   SOLUTIONS — DEPLOYMENT — THE EXHIBIT
   Everything above is the site. The board is a different product, so it
   sits in a frame and runs its own tokens: cooler greys and a blue accent,
   taken from that product rather than from this page. The .deploy-* rules
   above read --bg, --surface, --border, --text and --accent, so inside
   .deploy-app they all repaint from this block and from nowhere else.
══════════════════════════════ */

.deploy-example {
  margin: 2.5rem 0 0;
  border: 1px solid var(--border);
  border-radius: 8px;
}

.deploy-example-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem 0.9rem;
  padding: 0.8rem 1.1rem;
  border-bottom: 1px solid var(--border);
}

.deploy-example-tag {
  font-family: var(--mono);
  font-size: 0.58rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 2px;
  padding: 0.1rem 0.45rem;
}

.deploy-example-title {
  font-family: var(--sans);
  font-size: 0.98rem;
  color: var(--text);
}

.deploy-example-meta {
  margin-left: auto;
  font-family: var(--mono);
  font-size: 0.66rem;
  color: var(--dim2);
}

.deploy-example-foot {
  padding: 0.75rem 1.1rem;
  border-top: 1px solid var(--border);
  font-family: var(--mono);
  font-size: 0.68rem;
  line-height: 1.6;
  color: var(--dim2);
}

.deploy-example-foot a { color: var(--dim); text-decoration: none; border-bottom: 1px solid var(--border2); }
.deploy-example-foot a:hover { color: var(--text); }

/* ── the exhibited product's own palette ── */
.deploy-app {
  --bg:      #0b1116;
  --surface: #141c24;
  --border:  #24313d;
  --border2: #34465a;
  --text:    #dfe7ee;
  --body:    #8fa1b2;
  --dim:     #5f7183;
  --dim2:    #44566a;
  --accent:  #5c9fd6;

  /* used by the backbone exhibit only */
  --well:    #070d16;
  --term:    #050a12;
  --ok:      #3f8f66;
  --warn:    #7d6bb0;
  --bad:     #a8544c;

  background: var(--bg);
  color: var(--body);
  font-family: var(--sans);
  padding: 0.9rem 1.1rem 1rem;
}

/* cards lift off the panel rather than sinking into it */
.deploy-app .deploy-card { background: var(--surface); }
.deploy-app .deploy-frame { background: #060a0e; }
.deploy-app .deploy-modal-box { background: var(--surface); }

/* the product's own chrome, above the board */
.deploy-appbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.45rem 0.7rem;
  padding-bottom: 0.7rem;
  margin-bottom: 0.9rem;
  border-bottom: 1px solid var(--border);
  font-family: var(--mono);
  font-size: 0.7rem;
}

.deploy-appbar-dot {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #4c9a6d;
}

.deploy-appbar-name {
  font-family: var(--sans);
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--text);
}

.deploy-appbar-sep { color: var(--border2); }
.deploy-appbar-sub { color: var(--dim); }

.deploy-appbar-right {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-left: auto;
}

.deploy-appbar-chip {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 0.1rem 0.5rem;
  color: var(--body);
}

.deploy-appbar-btn {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: var(--dim);
  cursor: pointer;
  transition: color 0.15s;
}
.deploy-appbar-btn:hover { color: var(--text); }

@media (max-width: 700px) {
  .deploy-example-meta { margin-left: 0; }
}

/* ══════════════════════════════
   SOLUTIONS — DEPLOYMENT — THE BACKBONE
   The second exhibit: the rollout that puts a model on the device. Same
   frame and same product palette as the board above, with its own parts.
   Everything here reads the tokens set by .deploy-app.
══════════════════════════════ */

.bb-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

.bb-btn {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.02em;
  border-radius: 4px;
  padding: 0.5rem 0.9rem;
  cursor: pointer;
  background: var(--accent);
  border: 1px solid var(--accent);
  color: var(--bg);
  transition: filter 0.15s, border-color 0.15s, color 0.15s;
}
.bb-btn:hover { filter: brightness(1.15); }
.bb-btn[disabled] { opacity: 0.45; cursor: default; filter: none; }

.bb-btn.is-ghost {
  background: transparent;
  color: var(--body);
  border-color: var(--border2);
}
.bb-btn.is-ghost:hover { color: var(--text); border-color: var(--accent); filter: none; }

.bb-btn.is-danger {
  background: transparent;
  color: #d9736a;
  border-color: var(--bad);
}
.bb-btn.is-danger:hover { background: rgba(168, 84, 76, 0.14); filter: none; }

.bb-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 240px);
  gap: 0.75rem;
  align-items: start;
}
@media (max-width: 820px) { .bb-grid { grid-template-columns: minmax(0, 1fr); } }

.bb-panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.8rem;
  min-width: 0;
}

.bb-title {
  font-family: var(--mono);
  font-size: 0.6rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
  margin-bottom: 0.6rem;
}

/* ── the network, drawn rather than mapped ── */
.bb-map {
  background: var(--well);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 0.4rem;
  margin-bottom: 0.6rem;
}
.bb-map svg { display: block; width: 100%; height: auto; }

.bb-ring {
  fill: rgba(92, 159, 214, 0.07);
  stroke: var(--accent);
  stroke-opacity: 0.35;
  stroke-dasharray: 3 3;
}
.bb-line { stroke: var(--border2); stroke-width: 2; stroke-dasharray: 4 4; }
.bb-line.on { stroke: var(--accent); animation: bbDash 1s linear infinite; }
@keyframes bbDash { to { stroke-dashoffset: -16; } }

.bb-hq   { fill: var(--accent); }
.bb-unit { fill: var(--dim); stroke: var(--surface); stroke-width: 2; transition: fill 0.35s; }
.bb-unit.shadow { fill: var(--warn); }
.bb-unit.ok     { fill: var(--ok); }
.bb-unit.bad    { fill: var(--bad); }

.bb-map-label { fill: var(--text); font-family: var(--sans); font-size: 12px; font-weight: 600; text-anchor: middle; }
.bb-map-sub   { fill: var(--dim2); font-family: var(--mono); font-size: 10px; text-anchor: middle; }

.bb-status {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.25rem 0.8rem;
  background: rgba(255, 255, 255, 0.03);
  border-radius: 4px;
  padding: 0.35rem 0.6rem;
  margin-bottom: 0.6rem;
  font-family: var(--mono);
  font-size: 0.66rem;
  color: var(--dim);
}

.bb-term {
  background: var(--term);
  border-radius: 5px;
  padding: 0.7rem 0.8rem;
  height: 150px;
  overflow-y: auto;
  font-family: var(--mono);
  font-size: 0.7rem;
  line-height: 1.7;
  color: #6cc79a;
  white-space: pre-wrap;
}
.bb-term .bad { color: #e08a80; }

/* ── the gates ── */
.bb-gates { list-style: none; margin: 0 0 1rem; padding: 0; display: grid; gap: 3px; }
.bb-gates li {
  font-family: var(--mono);
  font-size: 0.68rem;
  padding: 0.3rem 0.5rem;
  border: 1px solid var(--border);
  border-radius: 3px;
  color: var(--dim);
  transition: border-color 0.15s, color 0.15s;
}
.bb-gates li.now  { border-color: var(--accent); color: var(--text); }
.bb-gates li.pass { border-color: var(--ok);  color: #6cc79a; }
.bb-gates li.fail { border-color: var(--bad); color: #e08a80; }

/* ── the fleet ── */
.bb-node {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0.4rem 0.6rem;
  margin-bottom: 0.35rem;
  font-size: 0.78rem;
  color: var(--body);
}
.bb-gen {
  font-family: var(--mono);
  font-size: 0.62rem;
  border-radius: 3px;
  padding: 1px 6px;
  background: rgba(255, 255, 255, 0.05);
  color: var(--dim);
  white-space: nowrap;
}
.bb-gen.is-new    { background: rgba(63, 143, 102, 0.22);  color: #6cc79a; }
.bb-gen.is-shadow { background: rgba(125, 107, 176, 0.22); color: #a793d8; }
.bb-gen.is-bad    { background: rgba(168, 84, 76, 0.22);   color: #e08a80; }

/* ── the field-trial cards, in page scope ── */
.bb-link,
.bb-link:visited {
  display: inline-block;
  align-self: flex-start;
  margin-top: 0.6rem;
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.04em;
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color 0.15s;
}
.bb-link:hover { border-bottom-color: var(--accent); }

/* the field-trial photo. It sits on a card in the page's own scope, not
   inside the exhibit, so it takes a plain name and the site's border. */
.thumb {
  display: block;
  width: 100%;
  max-width: 130px;
  aspect-ratio: 1;
  object-fit: cover;
  border: 1px solid var(--border2);
  border-radius: 4px;
  margin: 0 0 0.7rem;
}

@media (prefers-reduced-motion: reduce) {
  .bb-line.on { animation: none; }
}

/* ══════════════════════════════
   SOLUTIONS — COST MODEL
   The Training planner's controls, plus a plain-SVG chart drawn by
   js/cost_model.js. Series colours are set here, not in the script.
══════════════════════════════ */

.cm-fields {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 0.9rem 1.25rem;
  max-width: 640px;
  margin-top: 1rem;
}
.planner-step > .cm-fields:first-of-type { margin-top: 0; }

.cm-field { display: grid; gap: 0.4rem; }

.cm-field-label,
.cm-subhead {
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--dim2);
}
.cm-subhead { margin: 1.4rem 0 0.6rem; }

/* the planner grid sized to however many choices there are: columns that
   would sit empty collapse, so no row ends in a blank cell */
.cm-choices { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }

/* radio buttons reuse the planner checkbox, drawn round */
.planner-check input[type="radio"] { border-radius: 50%; }
.planner-check input[type="radio"]:checked::after { border-radius: 50%; }

.cm-range {
  display: flex;
  align-items: center;
  gap: 1rem;
  max-width: 640px;
  margin-top: 1rem;
}
.cm-range[hidden] { display: none; }
.cm-range input { flex: 1; accent-color: var(--accent); }
.cm-range output { font-family: var(--mono); font-size: 0.85rem; color: var(--text); min-width: 2.5rem; text-align: right; }

.cm-summary {
  font-family: var(--mono);
  font-size: 0.78rem;
  color: var(--body);
  margin-bottom: 0.75rem;
}

.cm-chart {
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg);
  padding: 0.5rem 0.25rem 0.25rem;
  margin-bottom: 1.25rem;
}
.cm-chart svg { display: block; width: 100%; height: auto; }

.cm-phase       { fill: var(--surface); }
.cm-phase-label { font-family: var(--mono); font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; fill: var(--dim2); }
.cm-grid        { stroke: var(--border); stroke-width: 1; }
.cm-tick        { font-family: var(--mono); font-size: 10px; fill: var(--dim2); }

.cm-line        { stroke-width: 1.5; fill: none; opacity: 0.55; stroke-linecap: round; }
.cm-line.is-selected { stroke-width: 2.5; opacity: 1; }
.cm-labelling   { stroke: var(--accent); stroke-width: 2.5; opacity: 1; }
.cm-rig         { stroke-dasharray: 5 4; }

.cm-deploy       { stroke: var(--dim2); stroke-width: 1; stroke-dasharray: 2 3; }
.cm-marker       { stroke: var(--text); stroke-width: 1; stroke-dasharray: 2 3; opacity: 0.6; }
.cm-marker-label { font-family: var(--mono); font-size: 10px; fill: var(--body); }

/* series: the rig first, then each chosen cloud in order */
.cm-series-0 { stroke: #d8d2c6; background: #d8d2c6; }
.cm-series-1 { stroke: #6f9fb8; background: #6f9fb8; }
.cm-series-2 { stroke: #7fae8c; background: #7fae8c; }
.cm-series-3 { stroke: #b07c9e; background: #b07c9e; }
.cm-series-4 { stroke: #c9a35a; background: #c9a35a; }
.cm-series-5 { stroke: #8c8cc4; background: #8c8cc4; }

.cm-swatch {
  display: inline-block;
  width: 14px;
  height: 2px;
  margin: 0 0.6rem 0.2rem 0;
  vertical-align: middle;
}

.cm-table .cm-row { cursor: pointer; }
.cm-table .cm-row:hover td { background: var(--surface); }
.cm-table .cm-row.is-selected td { color: var(--text); }
.cm-table .cm-row:focus-visible { outline: 1px solid var(--text); outline-offset: -1px; }

.cm-messages { list-style: none; margin-top: 0.6rem; max-width: 640px; }
.cm-messages li {
  font-size: 0.75rem;
  color: var(--body);
  line-height: 1.6;
  padding-left: 1rem;
  position: relative;
}
.cm-messages li::before { content: "–"; position: absolute; left: 0; color: var(--dim2); }
.cm-messages li.is-error { color: #c98a7e; }

/* the explanation: a button until asked, then a short list */
.cm-explain { margin-top: 1.75rem; max-width: 640px; }
.cm-explain-btn {
  font-family: var(--mono);
  font-size: 0.8rem;
  letter-spacing: 0.06em;
  color: var(--text);
  background: transparent;
  border: 1px solid var(--border2);
  border-radius: 4px;
  padding: 0.6rem 1.2rem;
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s;
}
.cm-explain-btn:hover { color: var(--accent); border-color: var(--accent); }
.cm-explain-btn:disabled { opacity: 0.5; cursor: default; }
.cm-explain-btn[hidden] { display: none; }
.cm-explain-body .cm-subhead { margin-top: 0; }
.cm-explain-list { list-style: none; display: grid; gap: 0.6rem; margin-bottom: 0.4rem; }
.cm-explain-list li {
  font-size: 0.85rem;
  line-height: 1.65;
  color: var(--body);
  padding-left: 1rem;
  border-left: 1px solid var(--accent);
}
.cm-explain-list li.is-error { color: #c98a7e; border-left-color: #c98a7e; }

/* on a phone the five-column table has to fit, so it tightens and its
   headings wrap rather than pushing the page sideways */
@media (max-width: 700px) {
  .cm-table { font-size: 0.78rem; }
  .cm-table th, .cm-table td { padding: 0.5rem 0.35rem; }
  .cm-table th { white-space: normal; letter-spacing: 0.08em; }
  .cm-swatch { display: none; }
  .cm-choices { grid-template-columns: 1fr; }
}

/* ══════════════════════════════
   LARGER TYPE — .page-large
   The rest of the site sits at 9–13px. Pages marked .page-large read at
   15–19px with body copy in Inter and mono kept for labels, names and
   numbers. Written as one block so it can later move to the whole site.
══════════════════════════════ */

.page-large { max-width: 1080px; }
.page-large .dev-eyebrow { font-size: 0.75rem; letter-spacing: 0.16em; margin-bottom: 0.6rem; }
.page-large .dev-eyebrow a { color: var(--dim2); text-decoration: none; border-bottom: 1px solid var(--border2); }
.page-large .dev-eyebrow a:hover { color: var(--text); }
.page-large .dev-heading { font-size: 2.4rem; font-weight: 500; letter-spacing: -0.03em; margin-bottom: 1.25rem; }

.page-large .lead {
  font-family: var(--sans);
  font-size: 1.2rem;
  line-height: 1.6;
  color: var(--body);
  max-width: 44rem;
  margin-bottom: 3rem;
}

.page-large .mono { font-family: var(--mono); }

/* ── HOSTING ── */
.hosting-step { margin-bottom: 3.5rem; }

.hosting-step-title {
  font-family: var(--mono);
  font-size: 0.8rem;
  font-weight: 400;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--dim2);
  margin-bottom: 1.25rem;
}

.hosting-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr));
  gap: 0.9rem;
}

.hosting-choice {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
  padding: 1.25rem 1.25rem 1.1rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}
.hosting-choice:hover { border-color: var(--border2); }
.hosting-choice:has(input:checked) { border-color: var(--accent); }

.hosting-choice input {
  appearance: none;
  -webkit-appearance: none;
  flex: none;
  position: relative;
  width: 18px;
  height: 18px;
  margin-top: 0.2rem;
  border: 1px solid var(--border2);
  border-radius: 4px;
  cursor: pointer;
}
.hosting-choice input:checked { border-color: var(--accent); background: var(--accent); }
.hosting-choice input:checked::after {
  content: "";
  position: absolute;
  left: 5px; top: 1px;
  width: 5px; height: 10px;
  border: solid var(--bg);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.hosting-choice input:focus-visible { outline: 2px solid var(--text); outline-offset: 2px; }

.hosting-choice-text { display: grid; gap: 0.35rem; }
.hosting-choice-name { font-family: var(--sans); font-size: 1.1rem; font-weight: 500; color: var(--text); }
.hosting-choice-summary { font-family: var(--sans); font-size: 0.95rem; line-height: 1.5; color: var(--body); }
.hosting-choice-tool { font-family: var(--mono); font-size: 0.85rem; color: var(--accent); margin-top: 0.15rem; }

.hosting-table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--sans);
  font-size: 1rem;
}
.hosting-table th,
.hosting-table td {
  text-align: left;
  padding: 0.85rem 0.9rem;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}
.hosting-table th {
  font-family: var(--mono);
  font-size: 0.75rem;
  font-weight: 400;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dim2);
  white-space: nowrap;
  border-bottom-color: var(--border2);
}
.hosting-table td { color: var(--body); }
.hosting-table td:first-child { color: var(--text); }
.hosting-table td.mono { font-size: 0.9rem; }
.hosting-table .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.hosting-table a { color: var(--text); text-decoration: none; border-bottom: 1px solid var(--border2); }
.hosting-table a:hover { border-bottom-color: var(--accent); }
.hosting-total td {
  color: var(--text);
  font-weight: 600;
  border-top: 1px solid var(--border2);
  border-bottom: none;
}

.hosting-note {
  font-family: var(--sans);
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--dim2);
  max-width: 44rem;
  margin-top: 1rem;
}

.hosting-admin { margin-top: 1rem; }
.hosting-admin a {
  display: inline-block;
  font-family: var(--mono);
  font-size: 0.85rem;
  letter-spacing: 0.04em;
  color: var(--text);
  text-decoration: none;
  border: 1px solid var(--border2);
  border-radius: 6px;
  padding: 0.75rem 1.2rem;
  transition: border-color 0.15s, color 0.15s;
}
.hosting-admin a:hover { color: var(--accent); border-color: var(--accent); }

/* ── HOSTING REPORT ── */
.report-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 210px), 1fr));
  gap: 0.9rem;
  margin-bottom: 1rem;
}
.report-tile {
  display: grid;
  gap: 0.35rem;
  padding: 1.25rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
}
.report-tile.is-accent { border-color: var(--accent); }
.report-tile-label { font-family: var(--mono); font-size: 0.75rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--dim2); }
.report-tile-value { font-family: var(--sans); font-size: 2rem; font-weight: 500; color: var(--text); font-variant-numeric: tabular-nums; }
.report-tile-note { font-family: var(--sans); font-size: 0.85rem; color: var(--body); }

.report-h2 {
  font-family: var(--sans);
  font-size: 1.35rem;
  font-weight: 500;
  color: var(--text);
  margin: 3rem 0 0.5rem;
}
.report-table { font-size: 0.95rem; }
.report-sub { display: block; font-family: var(--mono); font-size: 0.8rem; color: var(--accent); margin-top: 0.2rem; }
.report-table .is-negative { color: #c98a7e; }
.report-list { list-style: none; display: grid; gap: 0.6rem; max-width: 44rem; }
.report-list li { font-family: var(--sans); font-size: 0.95rem; line-height: 1.6; color: var(--body); padding-left: 1rem; border-left: 1px solid var(--border2); }
.report-list code { font-family: var(--mono); font-size: 0.85rem; color: var(--text); }

@media (max-width: 700px) {
  .page-large .dev-heading { font-size: 1.9rem; }
  .page-large .lead { font-size: 1.05rem; }
}

/* ── WORK-IN-PROGRESS BANNER ── reusable on any page */
.wip-banner {
  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.55;
  color: var(--text);
  background: rgba(201, 163, 90, 0.10);
  border: 1px solid rgba(201, 163, 90, 0.55);
  border-left-width: 4px;
  border-radius: 8px;
  padding: 0.9rem 1.15rem;
  margin: 0 0 2.25rem;
  max-width: 48rem;
}
.wip-banner strong { color: #e3c27f; font-weight: 600; }

/* ── HOSTING PROFILES ── */
.profile-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr));
  gap: 1rem;
}
.profile-card {
  display: grid;
  align-content: start;
  gap: 0.6rem;
  padding: 1.4rem 1.4rem 1.3rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  transition: border-color 0.15s;
}
.profile-card:hover { border-color: var(--border2); }
.profile-card.is-chosen { border-color: var(--accent); }
.profile-card.is-covered { opacity: 0.75; }

.profile-head { display: flex; align-items: center; gap: 0.85rem; cursor: pointer; }
.profile-head input,
.profile-option input {
  appearance: none;
  -webkit-appearance: none;
  flex: none;
  position: relative;
  width: 20px;
  height: 20px;
  border: 1px solid var(--border2);
  border-radius: 5px;
  cursor: pointer;
}
.profile-option input { width: 16px; height: 16px; border-radius: 4px; }
.profile-option input[type="radio"] { border-radius: 50%; }
.profile-head input:checked,
.profile-option input:checked { border-color: var(--accent); background: var(--accent); }
.profile-head input:checked::after {
  content: ""; position: absolute; left: 6px; top: 2px; width: 5px; height: 11px;
  border: solid var(--bg); border-width: 0 2px 2px 0; transform: rotate(45deg);
}
.profile-option input:checked::after {
  content: ""; position: absolute; inset: 4px; background: var(--bg); border-radius: inherit;
}
.profile-head input:disabled { cursor: default; opacity: 0.6; }
.profile-head input:focus-visible,
.profile-option input:focus-visible { outline: 2px solid var(--text); outline-offset: 2px; }

.profile-number { font-family: var(--mono); font-size: 0.85rem; color: var(--accent); }
.profile-name { font-family: var(--sans); font-size: 1.3rem; font-weight: 500; color: var(--text); letter-spacing: -0.01em; }
.profile-access { margin-left: auto; font-family: var(--mono); font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--dim2); border: 1px solid var(--dim2); border-radius: 3px; padding: 0.15rem 0.45rem; white-space: nowrap; }
.hosting-table tr.is-uncompared td { color: var(--dim2); }
.profile-summary { font-family: var(--sans); font-size: 1rem; line-height: 1.55; color: var(--body); }
.profile-input { font-family: var(--sans); font-size: 0.9rem; color: var(--dim2); }
.profile-included { font-family: var(--mono); font-size: 0.8rem; letter-spacing: 0.06em; color: var(--accent); }

.profile-options {
  display: grid;
  gap: 0.5rem;
  margin-top: 0.4rem;
  padding-top: 0.85rem;
  border-top: 1px solid var(--border);
}
.profile-options[hidden] { display: none; }
.profile-option { display: flex; align-items: center; gap: 0.6rem; font-family: var(--sans); font-size: 0.95rem; color: var(--text); cursor: pointer; }
.profile-option em { font-style: normal; color: var(--dim2); }
.profile-option-label { font-family: var(--mono); font-size: 0.75rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--dim2); margin-top: 0.3rem; }

.hosting-hint {
  font-family: var(--sans);
  font-size: 1rem;
  color: var(--text);
  margin-top: 1rem;
  padding: 0.8rem 1rem;
  border: 1px dashed var(--border2);
  border-radius: 8px;
  max-width: 48rem;
}
.hosting-hint[hidden] { display: none; }
.hosting-hint a { color: var(--text); border-bottom: 1px solid var(--accent); text-decoration: none; }

#hosting-result[hidden] { display: none; }

.hosting-columns {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
  gap: 1.5rem 2.5rem;
  margin: 2rem 0 0.5rem;
}
.hosting-subhead { font-family: var(--sans); font-size: 1.1rem; font-weight: 500; color: var(--text); margin: 2rem 0 0.75rem; }
.hosting-columns .hosting-subhead { margin-top: 0; }
.hosting-outputs { list-style: none; display: grid; gap: 0.5rem; }
.hosting-outputs li { font-family: var(--sans); font-size: 1rem; line-height: 1.5; color: var(--body); padding-left: 1rem; border-left: 2px solid var(--accent); }
.hosting-tools { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.tool-chip { font-family: var(--mono); font-size: 0.85rem; color: var(--text); background: var(--surface); border: 1px solid var(--border2); border-radius: 999px; padding: 0.25rem 0.7rem; }

/* ── ANDROID ── */
.app-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 400px), 1fr)); gap: 1rem; }
.app-card { display: grid; align-content: start; gap: 0.8rem; padding: 1.6rem; background: var(--surface); border: 1px solid var(--border); border-radius: 12px; }
.app-role { font-family: var(--mono); font-size: 0.8rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--accent); }
.app-name { font-family: var(--sans); font-size: 1.6rem; font-weight: 500; letter-spacing: -0.02em; color: var(--text); }
.app-body { font-family: var(--sans); font-size: 1.02rem; line-height: 1.6; color: var(--body); }

/* ── BYOC ── */
.byoc-points { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr)); gap: 1rem; }
.byoc-point { padding: 1.5rem; background: var(--surface); border: 1px solid var(--border); border-radius: 12px; }
.byoc-point-title { font-family: var(--sans); font-size: 1.25rem; font-weight: 500; color: var(--text); margin-bottom: 0.85rem; }
.byoc-point .report-list strong { color: var(--text); font-weight: 500; }
.byoc-point a, .byoc-text a { color: var(--text); text-decoration: none; border-bottom: 1px solid var(--accent); }
.byoc-text { font-family: var(--sans); font-size: 1.02rem; line-height: 1.65; color: var(--body); max-width: 44rem; }
.byoc-table td.is-ours { color: var(--text); }
.byoc-table th:last-child { color: var(--accent); }

.byoc-contact { margin-top: 1rem; }
.byoc-form { display: grid; gap: 1.1rem; max-width: 36rem; margin-top: 1.25rem; }
.byoc-field { display: grid; gap: 0.4rem; }
.byoc-label { font-family: var(--mono); font-size: 0.78rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--dim2); }
.byoc-field input, .byoc-field select, .byoc-field textarea {
  font-family: var(--sans); font-size: 1rem; color: var(--text);
  background: var(--surface); border: 1px solid var(--border2); border-radius: 8px;
  padding: 0.75rem 0.9rem; width: 100%;
}
.byoc-field input:focus, .byoc-field select:focus, .byoc-field textarea:focus { outline: none; border-color: var(--accent); }
.byoc-field.has-error input, .byoc-field.has-error select, .byoc-field.has-error textarea { border-color: #c98a7e; }
.byoc-error { font-family: var(--sans); font-size: 0.9rem; color: #c98a7e; }
.byoc-submit {
  justify-self: start; font-family: var(--mono); font-size: 0.9rem; letter-spacing: 0.04em;
  color: var(--bg); background: var(--accent); border: none; border-radius: 8px;
  padding: 0.85rem 1.4rem; cursor: pointer;
}
.byoc-submit:hover { filter: brightness(1.12); }
.byoc-sent { font-family: var(--sans); font-size: 1.1rem; color: var(--text); padding: 1rem 1.2rem; border: 1px solid var(--accent); border-radius: 8px; max-width: 36rem; }
.byoc-lines { list-style: none; display: grid; gap: 0.9rem; max-width: 44rem; margin-bottom: 1rem; }
.byoc-lines li { font-family: var(--sans); font-size: 1.1rem; line-height: 1.55; color: var(--body); padding-left: 1.1rem; border-left: 2px solid var(--accent); }
.byoc-lines strong { color: var(--text); font-weight: 500; }

.report-tile[hidden], #hosting-compare[hidden] { display: none; }
.report-tiles:has(.report-tile[hidden]) { grid-template-columns: minmax(0, 1fr); max-width: 22rem; }
.hosting-compute { max-width: 46rem; margin: 0 0 2.5rem; padding-left: 1rem; border-left: 2px solid var(--accent, #c9a24a); color: var(--text); font-size: 1.1rem; line-height: 1.6; }
.hosting-compute a { color: inherit; text-decoration: underline; text-underline-offset: 3px; }
.report-tile-note a { color: inherit; text-decoration: underline; text-underline-offset: 3px; }
.hosting-compute { font-family: var(--sans); }

/* ══════════════════════════════
   LARGER TYPE, CONTINUED — the Cost Model and Field Trials pages
   share Hosting's scale: mono labels at 0.75–0.8rem, Inter body at
   1–1.2rem, notes at 0.9rem.
══════════════════════════════ */
.page-large .planner-step { margin-bottom: 3.5rem; }
.page-large .planner-step-title { font-size: 0.8rem; letter-spacing: 0.16em; margin-bottom: 1.25rem; }
.page-large .cm-field-label,
.page-large .cm-subhead { font-size: 0.75rem; letter-spacing: 0.12em; }
.page-large .cm-fields { max-width: 44rem; gap: 1rem 1.5rem; }
.page-large .planner-select { font-family: var(--sans); font-size: 1rem; padding: 0.75rem 1rem; max-width: none; }
.page-large .planner-grid { border-radius: 10px; }
.page-large .planner-check { padding: 1rem 1.25rem; align-items: center; }
.page-large .planner-check input { width: 18px; height: 18px; margin: 0; }
.page-large .planner-check-name { font-family: var(--sans); font-size: 1.05rem; }
.page-large .cm-range output { font-size: 1rem; }
.page-large .cm-summary { font-family: var(--sans); font-size: 1.1rem; color: var(--text); margin-bottom: 1rem; }
.page-large .cm-chart { border-radius: 10px; }
.page-large .solutions-table { font-family: var(--sans); font-size: 1rem; }
.page-large .solutions-table th,
.page-large .solutions-table td { padding: 0.85rem 0.9rem; }
.page-large .solutions-table th { font-family: var(--mono); font-size: 0.75rem; letter-spacing: 0.12em; color: var(--dim2); }
.page-large .solutions-table td:last-child { color: var(--body); }
.page-large .planner-note,
.page-large .cm-messages li { font-family: var(--sans); font-size: 0.9rem; line-height: 1.6; max-width: 44rem; }
.page-large .planner-note { margin-top: 1rem; }
.page-large .planner-note a { color: var(--text); text-decoration: underline; text-underline-offset: 3px; }
.page-large .cm-explain { max-width: 44rem; }
.page-large .cm-explain-btn { font-size: 0.85rem; padding: 0.75rem 1.2rem; border-radius: 6px; }
.page-large .cm-explain-list li { font-family: var(--sans); font-size: 1rem; }

/* Field Trials */
.page-large .solutions-statement { font-size: 1.5rem; font-weight: 500; letter-spacing: -0.015em; line-height: 1.35; max-width: 44rem; margin-bottom: 1.5rem; }
.page-large .solutions-intro { font-family: var(--sans); font-size: 1.1rem; line-height: 1.7; max-width: 44rem; }
.page-large .solutions-lead { font-size: 0.8rem; letter-spacing: 0.16em; margin-top: 0; }
.page-large .principles-grid { margin-top: 2.5rem; }
.page-large .principle-label { font-family: var(--mono); font-size: 0.8rem; }
.page-large .principle-title { font-size: 1.3rem; font-weight: 500; }
.page-large .principle-body { font-family: var(--sans); font-size: 1rem; line-height: 1.6; color: var(--body); }
.page-large .bb-link { font-size: 0.85rem; }
.page-large .deploy-quote { max-width: 44rem; }
.page-large .deploy-quote p { font-size: 1.25rem; line-height: 1.6; }
.page-large .deploy-example-foot { font-family: var(--sans); font-size: 0.9rem; line-height: 1.6; }
.page-large .bb-btn { font-size: 0.85rem; }
.page-large .bb-gates li { font-size: 0.85rem; }
.page-large .bb-node-x,
.page-large .bb-node { font-size: 0.95rem; }

.coming-soon {
  max-width: 44rem;
  padding: 1.5rem 1.75rem;
  border: 1px dashed var(--border2);
  border-radius: 10px;
  font-family: var(--sans);
  font-size: 1.1rem;
  color: var(--text);
}
.coming-soon span { display: block; margin-top: 0.4rem; font-size: 0.95rem; color: var(--body); }

/* the developer tabs scroll sideways on a phone instead of widening the page */
.tab-bar { overflow-x: auto; scrollbar-width: none; }
.tab-bar::-webkit-scrollbar { display: none; }
.tab-btn { flex: none; white-space: nowrap; }
/* scrolling clips anything outside the bar, so the rule is drawn inside it */
.tab-bar { border-bottom: none; box-shadow: inset 0 -1px 0 var(--border); }
.tab-bar .tab-btn { margin-bottom: 0; }
.page-large .principles-grid { grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); }
.page-large .cm-tick, .page-large .cm-phase-label, .page-large .cm-marker-label { font-size: 12px; }

/* Edge Spine: the headquarters label sits beside its node, clear of both links,
   and a node receiving an update is ringed in the accent until it confirms */
.bb-map-label.is-side, .bb-map-sub.is-side { text-anchor: start; }
.bb-unit.incoming { fill: var(--accent); stroke: var(--accent); stroke-opacity: 0.35; stroke-width: 8; }

/* ══════════════════════════════
   THE WIP PAGE — CAPITAL LOOP
   A budget spent on one pass through a pipeline, against the same budget
   spent on a pass that leaves enough to run again. Built from the site's
   own parts: hairlines, the gold accent, mono labels. The mode switch
   repaints the panel through two local tokens; nothing here leaves the page.
══════════════════════════════ */

.wip-main {
  width: 100%;
  max-width: 1040px;
  margin: 0 auto;
  padding: 2rem 2.5rem 4rem;
}
.wip-head { margin-bottom: 1.75rem; }

.cap {
  /* open-loop is the default: grey links, a refused edge, a rose glow */
  --cap-link: var(--border2);
  --cap-hot: var(--bad);
  --cap-glow: rgba(201, 138, 126, 0.30);

  padding: 1.25rem;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
}
.cap[data-mode="closed-loop"] {
  --cap-link: var(--accent);
  --cap-hot: var(--accent);
  --cap-glow: rgba(138, 109, 59, 0.40);
}

/* ── controls ── */
.cap-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.9rem;
  padding-bottom: 1.1rem;
  margin-bottom: 1.25rem;
  border-bottom: 1px solid var(--border);
}

.cap-mode {
  display: flex;
  gap: 2px;
  padding: 2px;
  border: 1px solid var(--border2);
  border-radius: 6px;
  background: var(--bg);
}

.cap-mode-btn {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dim);
  background: none;
  border: 0;
  border-radius: 4px;
  padding: 0.45rem 0.9rem;
  cursor: pointer;
  transition: color 0.15s, background 0.15s;
}
.cap-mode-btn:hover { color: var(--text); }
.cap-mode-btn.is-active { color: var(--text); background: var(--surface); }
.cap[data-mode="open-loop"] .cap-mode-btn.is-active { color: var(--bad); }
.cap[data-mode="closed-loop"] .cap-mode-btn.is-active { color: var(--accent); }
.cap-mode-btn:focus-visible { outline: 1px solid var(--text); outline-offset: 2px; }

/* the way past the animation: skip means skip, so it sits at the panel's
   top right, opposite the mode switch rather than under the diagram */
.cap-skip {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dim);
  text-decoration: none;
  transition: color 0.15s;
}
.cap-skip:hover { color: var(--text); }
.cap-skip:focus-visible { outline: 1px solid var(--text); outline-offset: 3px; }

/* ── the two panels ── */
.cap-stage {
  display: grid;
  grid-template-columns: 9rem minmax(0, 1fr);
  gap: 1.25rem;
  align-items: stretch;
}

/* ── the budget: a level indicator ──
   One thin track and the figure above it. The level is --cap-level, set by
   capital-loop.js: upright beside the line, flat above it on narrow screens. */
.cap-gauge-panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.6rem;
  padding: 1.1rem 0.9rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
}

.cap-gauge-title {
  font-size: 0.6rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--dim);
}

.cap-gauge-value {
  font-family: var(--mono);
  font-size: 1.15rem;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.cap-gauge {
  --cap-level: 100%;
  position: relative;
  flex: 1;
  width: 6px;
  min-height: 12rem;
  border-radius: 3px;
  background: var(--border);
  overflow: hidden;
}
.cap-gauge-fill {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: var(--cap-level);
  background: var(--accent);
  transition: height 0.25s linear, width 0.25s linear, background 0.3s;
}
.cap-gauge.is-warn .cap-gauge-fill { background: #c9a35a; }
.cap-gauge.is-bad .cap-gauge-fill { background: var(--bad); }
.cap-gauge-panel:has(.cap-gauge.is-bad) .cap-gauge-value { color: var(--bad); }

/* ── the line ── */
.cap-diagram {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem 1.25rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
}

/* Two layouts for the same three stages. Open-loop is the pipeline as it
   was: a row, left to right, 620 x 240. Closed-loop closes that row into an
   equilateral triangle, base at the top, 620 x 440. Either way the node
   percentages and the edge coordinates in the matching SVG are read against
   the same box, so the drawing and the cards cannot drift apart. */
.cap-flow {
  position: relative;
  width: 100%;
  max-width: 620px;
  aspect-ratio: 620 / 240;
}
.cap[data-mode="closed-loop"] .cap-flow { aspect-ratio: 620 / 440; }

.cap-node {
  position: absolute;
  width: 26%;                 /* 161 of the 620 the edges are drawn in */
  transform: translate(-50%, -50%);
  display: grid;
  gap: 0.75rem;
  padding: 1.1rem 1rem;
  border: 1px solid var(--border2);
  border-radius: 10px;
  background: var(--surface);
  transition: border-color 0.3s, box-shadow 0.3s;
}
.cap-node.is-active {
  border-color: var(--cap-hot);
  box-shadow: 0 0 25px var(--cap-glow);
}

/* open-loop: one stage after another, along the middle line */
.cap-node--ingest   { left: 16.5%; top: 50%; }
.cap-node--training { left: 50%;   top: 50%; }
.cap-node--deploy   { left: 83.5%; top: 50%; }

/* closed-loop: the base at the top, the apex below and between */
.cap[data-mode="closed-loop"] .cap-node { width: 29%; }
.cap[data-mode="closed-loop"] .cap-node--ingest   { left: 22.6%; top: 15.9%; }
.cap[data-mode="closed-loop"] .cap-node--training { left: 77.4%; top: 15.9%; }
.cap[data-mode="closed-loop"] .cap-node--deploy   { left: 50%;   top: 82.7%; }

.cap-node-label {
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--body);
}

.cap-node-track {
  height: 4px;
  border-radius: 2px;
  background: var(--border);
  overflow: hidden;
}
.cap-node-bar {
  width: 0;
  height: 100%;
  background: var(--cap-hot);
  transition: width 0.1s linear;
}

/* the edges: one per side of the triangle, drawn in the box the cards sit in */
.cap-edges {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.cap-edge {
  stroke: var(--cap-link);
  stroke-width: 1.5;
  stroke-linecap: round;
  transition: stroke 0.3s, opacity 0.35s, stroke-width 0.18s;
}

/* the link the run is crossing goes bold for a beat, then settles back */
.cap-edge.is-linking { stroke-width: 3; }

/* one drawing per layout; the mode decides which is on the page */
.cap-edges--triangle { display: none; }
.cap[data-mode="closed-loop"] .cap-edges--linear   { display: none; }
.cap[data-mode="closed-loop"] .cap-edges--triangle { display: block; }

.cap-head-fill { fill: var(--cap-link); transition: fill 0.3s; }

/* the triangle needs about 620px to keep its proportions; below that the
   three stages stack and the drawn edges go */
@media (max-width: 980px) {
  .cap-stage { grid-template-columns: minmax(0, 1fr); }
  .cap-gauge-panel { flex-direction: row; flex-wrap: wrap; align-items: center; gap: 0.5rem 1rem; }
  .cap-gauge { flex: 1 1 100%; width: auto; height: 6px; min-height: 0; order: 3; }
  .cap-gauge-fill { top: 0; right: auto; height: auto; width: var(--cap-level); }
  .cap-flow,
  .cap[data-mode="closed-loop"] .cap-flow { aspect-ratio: auto; }
  .cap-edges,
  .cap[data-mode="closed-loop"] .cap-edges--triangle { display: none; }
  .cap-node,
  .cap[data-mode="closed-loop"] .cap-node { position: static; width: auto; transform: none; }
  .cap-flow > .cap-node + .cap-node { margin-top: 0.6rem; }
}

@media (max-width: 760px) {
  .wip-main { padding: 1.5rem 1.25rem 3rem; }
}

/* ══════════════════════════════
   THE WIZARD — one stage at a time
   Three cards under the loop: meet a stage, choose how to fill it, move on.
   One card is in the page at a time; the others stay in the DOM, empty, so
   steps two and three can be written without disturbing the walk.
══════════════════════════════ */

.wiz {
  margin-top: 1.25rem;
  padding: 1.25rem;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
}

/* on its own page the wizard is the page, so it does not sit under anything */
.wizard-main .wiz { margin-top: 0; }

.wiz-steps {
  display: flex;
  gap: 0.4rem;
  list-style: none;
  padding: 0 0 1.1rem;
  margin-bottom: 1.25rem;
  border-bottom: 1px solid var(--border);
}

.wiz-dot {
  width: 1.9rem;
  height: 1.9rem;
  display: grid;
  place-items: center;
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--dim);
  border: 1px solid var(--border2);
  border-radius: 50%;
  transition: color 0.2s, border-color 0.2s, background 0.2s;
}
.wiz-dot.is-done { color: var(--body); background: var(--bg); }
.wiz-dot.is-current { color: var(--accent); border-color: var(--accent); }

.wiz-card {
  display: grid;
  gap: 0.6rem;
  align-content: start;
  min-height: 12rem;
}
.wiz-card[hidden] { display: none; }

/* steps two and three have no copy yet: the empty card says so by being empty */
.wiz-card:empty {
  border: 1px dashed var(--border2);
  border-radius: 8px;
}

.wiz-role {
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
}

.wiz-name {
  font-family: var(--sans);
  font-size: 1.5rem;
  font-weight: 500;
  letter-spacing: -0.02em;
  color: var(--text);
}

.wiz-body {
  font-family: var(--sans);
  font-size: 1.02rem;
  line-height: 1.6;
  color: var(--body);
  max-width: 46rem;
}

.wiz-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  align-self: end;
  margin-top: 0.6rem;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
}

.wiz-btn {
  font-family: var(--mono);
  font-size: 0.8rem;
  letter-spacing: 0.04em;
  color: var(--accent);
  background: transparent;
  border: 1px solid var(--accent);
  border-radius: 6px;
  padding: 0.65rem 1.2rem;
  cursor: pointer;
  transition: color 0.15s, background 0.15s, filter 0.15s;
}
.wiz-btn:hover { color: var(--text); background: rgba(138, 109, 59, 0.16); }
.wiz-btn:focus-visible { outline: 1px solid var(--text); outline-offset: 2px; }
.wiz-btn.is-primary {
  color: var(--bg);
  background: var(--accent);
  border-color: var(--accent);
}
.wiz-btn.is-primary:hover { color: var(--bg); filter: brightness(1.15); }

/* ══════════════════════════════
   STACK — the four -AS products (partials/stack*.html)
   Brought over from the landing-stack branch; used by the wizard's step 2.
══════════════════════════════ */

/* DIN for the A and S of Affaible Systems and for the product names.
   Barlow, from Google Fonts, stands in for D-DIN (Datto, SIL OFL).
   To switch: put D-DIN-Bold.woff2 in static/fonts/, then add an @font-face
   here for family 'D-DIN', weight 700, whose src points at
   ../fonts/D-DIN-Bold.woff2. Add it only once the file exists: collectstatic
   rewrites every url() in this file, even inside comments, and fails on a
   missing one. */
:root { --din: 'D-DIN', 'Barlow', var(--sans); }

.stack { margin: 1.5rem 0 5rem; }

.stack-title {
  font-family: var(--sans);
  font-size: 3.2rem;
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 1.05;
  color: var(--text);
}
.stack-title .din,
.stack-as {
  font-family: var(--din);
  font-weight: 700;
  color: var(--accent-hi, #c9a15d);
  letter-spacing: 0.01em;
}
.stack-sub {
  font-family: var(--sans);
  font-size: 1.6rem;
  font-weight: 400;
  letter-spacing: -0.02em;
  color: var(--body);
  margin-top: 0.35rem;
}
.stack-deal {
  font-family: var(--mono);
  font-size: 0.8rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text);
  margin: 1.4rem 0 2.75rem;
}

.stack-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.stack-card {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  padding: 1.25rem 1.1rem 1.1rem;
  border-right: 1px solid var(--border);
  min-width: 0;
}
.stack-card:last-child { border-right: none; }

.stack-screen {
  position: relative;
  aspect-ratio: 1 / 1;
  background: #0f0e0c;
  border: 1px solid var(--border);
  border-radius: 4px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  margin-bottom: 0.6rem;
  outline: none;
}
.stack-screen:focus-visible { border-color: var(--accent); }
.stack-screen.is-empty {
  align-items: center;
  justify-content: center;
  font-family: var(--mono);
  font-size: 0.65rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
}
.stack-dots { display: block; width: 100%; flex: 1 1 auto; min-height: 0; }
.stack-term {
  font-family: var(--mono);
  font-size: 0.62rem;
  line-height: 1.5;
  color: var(--body);
  padding: 0.45rem 0.6rem 0.55rem;
  border-top: 1px solid var(--border);
  white-space: pre;
  overflow: hidden;
  min-height: 7.2em;
}
.stack-term .t-cmd  { color: var(--text); }
.stack-term .t-done { color: var(--dim); }
.stack-term .t-ok   { color: #c9a15d; }
.stack-badge {
  position: absolute;
  top: 0.4rem;
  right: 0.5rem;
  font-family: var(--mono);
  font-size: 0.55rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #e3c27f;
  background: rgba(20, 19, 17, 0.8);
  padding: 0.1rem 0.35rem;
  border: 1px solid #5a4a2c;
  border-radius: 3px;
}

.stack-name {
  font-family: var(--din);
  font-size: 1.55rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  line-height: 1.1;
  color: var(--text);
}
.stack-line {
  font-family: var(--sans);
  font-size: 0.95rem;
  line-height: 1.5;
  color: var(--body);
  flex: 1;
}
.stack-actions {
  font-family: var(--mono);
  font-size: 0.8rem;
  letter-spacing: 0.08em;
  color: var(--dim);
  margin-top: 0.4rem;
}
.stack-actions a {
  color: var(--text);
  text-decoration: none;
  border-bottom: 1px solid var(--border2);
}
.stack-actions a:hover { border-bottom-color: var(--accent); }

.stack-tagline {
  font-family: var(--sans);
  font-size: 1.15rem;
  color: var(--text);
  margin-top: 2rem;
}

/* dots: drawn by static/js/stack.js */
.stack-dots circle { transition: fill 0.35s, stroke 0.35s, opacity 0.35s, r 0.35s; }
.stack-dots circle.is-pulse { animation: stack-pulse 1.1s ease-in-out infinite; }
@keyframes stack-pulse { 50% { opacity: 0.25; } }

@media (max-width: 900px) {
  .stack-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .stack-card:nth-child(2n) { border-right: none; }
  .stack-card:nth-child(-n+2) { border-bottom: 1px solid var(--border); }
}
@media (max-width: 560px) {
  .stack-title { font-size: 2.3rem; }
  .stack-sub { font-size: 1.25rem; }
  .stack-grid { grid-template-columns: minmax(0, 1fr); }
  .stack-card { border-right: none; border-bottom: 1px solid var(--border); }
  .stack-card:last-child { border-bottom: none; }
  /* one column: the dots keep their own shape and the terminal its full
     height, rather than both squeezed into a fixed box */
  .stack-screen { aspect-ratio: auto; }
  .stack-screen.is-empty { aspect-ratio: 100 / 62; }
  .stack-dots { flex: none; aspect-ratio: 100 / 62; height: auto; }
}
@media (prefers-reduced-motion: reduce) {
  .stack-dots circle { transition: none; }
  .stack-dots circle.is-pulse { animation: none; }
}

/* Landing: the stack hero */
.landing-stack { padding-top: 0; align-items: stretch; }
.landing-stack .dev-main { padding-top: 0.5rem; }
.landing-stack .stack { margin-top: 0; }
.landing-workshop { display: inline-flex; line-height: 0; padding: 0.25rem; }
.landing-workshop:focus-visible { outline: 1px solid var(--accent); outline-offset: 3px; border-radius: 3px; }

/* Access (Request early access / Talk to us) */
.access-main { max-width: 760px; }
.access-hp { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
.stack-actions a { white-space: nowrap; }

/* ── Stack cards: text only. "See the run / view / tournament" opens the
   product's demo in the right-hand panel (.stack-sheet, below). ── */
.stack-hint {
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  color: var(--dim);
  margin-top: 0.2rem;
  text-align: left;
  line-height: 1.6;
  display: block;
}
button.stack-hint {
  background: none;
  border: none;
  padding: 0;
  color: var(--body);
  cursor: pointer;
  align-self: flex-start;
  border-bottom: 1px solid transparent;
}
button.stack-hint:hover { color: #c9a15d; border-bottom-color: var(--accent); }
button.stack-hint:focus-visible { outline: 1px solid var(--accent); outline-offset: 3px; }

/* the demos, inside the panel */
.stack-sheet.stack-sheet-wide { width: min(860px, 100vw); }
/* the provenance panel slides out further: the record wants the room */
.stack-sheet.stack-sheet-proof { width: min(1040px, 100vw); }
.stack-sheet-nav { display: flex; gap: 0.5rem; margin: 0 6rem 1.25rem 0; min-height: 1.6rem; }
.stack-sheet-step {
  font-family: var(--mono); font-size: 0.72rem; letter-spacing: 0.06em; color: var(--body);
  background: transparent; border: 1px solid var(--border2); border-radius: 4px; padding: 0.2rem 0.65rem; cursor: pointer;
}
.stack-sheet-step:hover { color: var(--text); border-color: var(--accent); }
.stack-sheet-step[hidden] { display: none; }
.stack-sheet-title.stack-sheet-title { font-family: var(--din); font-size: 1.8rem; font-weight: 700; letter-spacing: 0.01em; }
.stack-sheet-actions { margin-top: 1.5rem; }
.stack-demo { margin-top: 0.5rem; }
.stack-demo-tag {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.04em;
  color: #9cc59a;
  margin-bottom: 0.8rem;
}
.stack-demo-tag b { font-weight: 400; text-transform: uppercase; letter-spacing: 0.14em; }
.stack-demo-term {
  font-family: var(--mono);
  font-size: 0.72rem;
  line-height: 1.45;
  color: var(--body);
  white-space: pre;
  overflow-x: auto;
  margin: 0;
  background: #0f0e0c;
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0.9rem 1rem;
}
.stack-demo-term .t-cmd  { color: var(--text); }
.stack-demo-term .t-ok   { color: #c9a15d; }
.stack-demo-term .t-done { color: var(--dim); }
.stack-demo-note {
  font-family: var(--sans);
  font-size: 0.85rem;
  color: var(--body);
  margin-top: 0.8rem;
}
.stack-demo-split { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1rem; }
.stack-demo-video {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #000;
  border: 1px solid var(--border);
  border-radius: 4px;
}

/* the tagline: bigger, with the second half carrying the weight */
.stack-tagline {
  font-size: 2rem;
  line-height: 1.25;
  letter-spacing: -0.02em;
  color: var(--body);
  margin-top: 2.5rem;
}
.stack-tagline strong { color: var(--text); font-weight: 600; }
@media (max-width: 560px) { .stack-tagline { font-size: 1.45rem; } }
.dev-provenance { margin: -0.5rem 0 1.75rem; }

/* Under the tagline: the run's numbers, and "See the working", which slides
   out one item's chain of custody from the right (full screen on phones). */
.stack-proof-line { font-family: var(--sans); font-size: 0.95rem; color: var(--body); margin-top: 1rem; max-width: 46rem; }
.stack-proof-line b { color: var(--text); font-weight: 500; }
.stack-proof-open {
  font-family: var(--mono);
  font-size: 0.8rem;
  letter-spacing: 0.06em;
  color: var(--text);
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--accent);
  padding: 0 0 1px;
  cursor: pointer;
  white-space: nowrap;
}
.stack-proof-open:hover { color: #c9a15d; }
.stack-proof-open:focus-visible { outline: 1px solid var(--accent); outline-offset: 3px; }

.stack-sheet {
  margin: 0 0 0 auto;
  height: 100vh;
  max-height: 100vh;
  width: min(560px, 100vw);
  max-width: 100vw;
  padding: 0;
  border: none;
  border-left: 1px solid var(--accent);
  background: var(--bg);
  color: var(--text);
  box-shadow: -24px 0 48px rgba(0, 0, 0, 0.45);
}
.stack-sheet[open] { animation: stack-sheet-in 0.22s ease-out; }
.stack-sheet::backdrop { background: rgba(5, 5, 4, 0.55); }
@keyframes stack-sheet-in { from { transform: translateX(40px); opacity: 0; } to { transform: none; opacity: 1; } }
.stack-sheet-body { padding: 1.5rem 1.5rem 2rem; position: relative; }
.stack-sheet-title { font-family: var(--sans); font-size: 1.4rem; font-weight: 600; margin: 0 5rem 0.5rem 0; }
.stack-sheet-lead { font-family: var(--sans); font-size: 0.9rem; color: var(--body); margin-bottom: 1.1rem; }
.stack-sheet-close {
  position: absolute; top: 1.25rem; right: 1.25rem;
  font-family: var(--sans); font-size: 0.8rem; color: var(--text);
  background: transparent; border: 1px solid var(--border2); border-radius: 4px; padding: 0.25rem 0.75rem; cursor: pointer;
}
.stack-sheet-close:hover { border-color: var(--dim); }
.stack-sheet.pp .pp-card { max-width: none; }   /* beats polyphon's .pp .pp-card cap */
.stack-sheet-proof.pp .pp-chaincard-head { grid-template-columns: 160px minmax(0, 1fr); }
.stack-sheet-proof.pp .pp-chaincard-head img { width: 160px; height: 160px; }
@media (max-width: 560px) {
  .stack-sheet-proof.pp .pp-chaincard-head { grid-template-columns: 88px minmax(0, 1fr); }
  .stack-sheet-proof.pp .pp-chaincard-head img { width: 88px; height: 88px; }
}
.stack-proof-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem 1.5rem; margin-top: 1rem; }
.stack-sheet .stack-proof-next {
  font-family: var(--mono);
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  color: var(--text);
  background: transparent;
  border: 1px solid var(--border2);
  border-radius: 4px;
  padding: 0.35rem 0.8rem;
  cursor: pointer;
}
.stack-sheet .stack-proof-next:hover { border-color: var(--accent); }
.stack-sheet .stack-proof-next:focus-visible { outline: 1px solid var(--accent); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { .stack-sheet[open] { animation: none; } }

/* a demo told as a sequence: several terminal blocks shown as one terminal */
.stack-demo-seq {
  background: #0f0e0c;
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0.9rem 1rem;
  overflow-x: auto;
}
.stack-demo-seq .stack-demo-term {
  background: none;
  border: 0;
  border-radius: 0;
  padding: 0;
  overflow: visible;
}

/* one Early access / Talk to us for all four products */
.stack-cta { display: flex; flex-wrap: wrap; gap: 0.75rem 2rem; margin-top: 1.25rem; font-family: var(--mono); font-size: 0.85rem; letter-spacing: 0.08em; }
.stack-cta a { color: var(--text); text-decoration: none; border-bottom: 1px solid var(--border2); }
.stack-cta a:hover { border-bottom-color: var(--accent); }
.stack-cta a:first-child { color: #c9a15d; border-bottom-color: var(--accent); }
.stack-demo-seq .stack-demo-term + .stack-demo-term { margin-top: 1.45em; }

/* crude-AS panel: the pitch above the run, the market line below it */
.stack-demo-pitch { font-family: var(--sans); font-size: 1rem; line-height: 1.6; color: var(--body); margin: 0 0 1.1rem; }
.stack-demo-pitch b { color: var(--text); font-weight: 600; }
.stack-demo-market {
  font-family: var(--sans); font-size: 0.95rem; color: var(--text);
  border-left: 2px solid var(--accent); padding-left: 0.9rem; margin-top: 1.25rem;
}

/* Hosting: plain cost tables */
.hosting-table tfoot td { border-top: 1px solid var(--border2); color: var(--text); }
.hosting-muted { color: var(--body); font-size: 0.78rem; }
.hosting-table small a { color: var(--body); }

/* ══════════════════════════════
   THE WIZARD, STEPS 2 AND 3 — the -AS stack, then Zerdira
   Step 2 carries the stack's cards (and, by level, its demo panel and
   "Show your working"); the rules here fit them inside a wizard card.
══════════════════════════════ */
.wiz-card-stack .stack-wiz-name { font-family: var(--sans); }
.wiz-card-stack .stack-wiz-name .stack-as { font-size: 1.05em; }
.wiz-card-stack .stack-grid { margin-top: 0.5rem; }
.wiz-card-stack .stack-card { padding: 1rem 0.9rem 0.9rem; }
.wiz-card-stack .stack-name { font-size: 1.35rem; }
.wiz-card-stack .stack-tagline { font-size: 1.35rem; margin-top: 1.25rem; }
.wiz-card-stack .stack-proof-line { margin-top: 0.4rem; }

.wiz-behind {
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  color: var(--dim);
  margin-top: 0.4rem;
}
.wiz-behind a { color: var(--body); text-decoration: none; border-bottom: 1px solid var(--border2); }
.wiz-behind a:hover { color: var(--text); border-bottom-color: var(--accent); }

/* after the last step: what was chosen, step by step */
.wiz-done {
  display: grid;
  gap: 0.6rem;
  outline: none;
}
.wiz-done[hidden] { display: none; }
.wiz-done-list { list-style: none; border-top: 1px solid var(--border); }
.wiz-done-list li {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--border);
  font-family: var(--sans);
  color: var(--text);
}
.wiz-done-list li span + span { font-family: var(--mono); font-size: 0.8rem; color: var(--accent); }

/* ── SUBTITLES (static/js/subtitles.js) ──
   While a line plays: words to come are dim, words said are bright, and the
   word being said sits on a gold block, as captions do on social video. */
.sub-w {
  border-radius: 3px;
  padding: 0 0.08em;
  margin: 0 -0.08em;
  transition: color 0.12s, background-color 0.12s;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}
[data-subtitle].is-playing .sub-w { color: var(--dim); }
[data-subtitle].is-playing .sub-w.is-said { color: var(--text); }
[data-subtitle].is-playing .sub-w.is-now { color: var(--bg); background-color: #c9a15d; }
@media (prefers-reduced-motion: reduce) { .sub-w { transition: none; } }

/* ══════════════════════════════
   THE SHOPFRONT — Affaible Stacks, the loop, "Show your working"
══════════════════════════════ */
.stack-head { margin-bottom: 2rem; }
.stack-head .stack-title { font-size: 2.6rem; }
.stack-head .stack-sub { font-size: 1.3rem; }
.stack-head .stack-deal { margin-top: 0.6rem; }
@media (max-width: 560px) {
  .stack-head .stack-title { font-size: 2rem; }
  .stack-head .stack-sub { font-size: 1.1rem; }
}

.stack-proof { margin-top: 2.5rem; }
.stack-proof .stack-tagline { margin-top: 0; }

/* header: the spanner sits by Logout, for those who may use it */
.site-header-tools { display: flex; align-items: center; gap: 1.1rem; }

/* ══════════════════════════════
   THE SHOP — choosing stacks, and the basket
══════════════════════════════ */
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
}

/* a fieldset that lays out like the stack grid */
fieldset.stack-pick-grid { min-width: 0; margin: 0.5rem 0 0; padding: 0; border-left: 0; border-right: 0; }

.wiz-hint { display: block; margin-top: 0.5rem; color: var(--text); font-weight: 500; }

/* each card is a checkbox: the whole of name and line is the target */
.stack-pick {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  flex: 1;
  cursor: pointer;
}
.stack-pick-box {
  position: absolute;
  opacity: 0;
  width: 1px; height: 1px;
}
.stack-pick-mark {
  position: absolute;
  top: 0.15rem;
  right: 0;
  width: 1.15rem;
  height: 1.15rem;
  border: 1px solid var(--border2);
  border-radius: 50%;
  transition: background 0.15s, border-color 0.15s;
}
.stack-pick-mark::after {
  content: "";
  position: absolute;
  left: 0.36rem;
  top: 0.16rem;
  width: 0.3rem;
  height: 0.58rem;
  border: solid var(--bg);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
  opacity: 0;
}
.stack-pick .stack-name { padding-right: 1.6rem; }
.stack-pick-note {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  color: var(--dim);
}
.stack-pick-state {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  min-height: 1em;
}

.stack-card { transition: background 0.15s, box-shadow 0.15s; }
.stack-pick-grid .stack-card:hover { background: rgba(138, 109, 59, 0.06); }
.stack-card:has(.stack-pick-box:focus-visible) { box-shadow: inset 0 0 0 1px var(--text); }
.stack-card.is-picked { background: rgba(138, 109, 59, 0.12); box-shadow: inset 0 0 0 1px var(--accent); }
.stack-card.is-picked .stack-pick-mark { background: var(--accent); border-color: var(--accent); }
.stack-card.is-picked .stack-pick-mark::after { opacity: 1; }
.stack-card.is-included { background: rgba(138, 109, 59, 0.05); }
.stack-card.is-included .stack-pick { cursor: default; }
.stack-card.is-included .stack-pick-mark { border-color: var(--accent); background: transparent; }
.stack-card.is-included .stack-pick-mark::after { opacity: 1; border-color: var(--accent); }
.stack-card.is-included .stack-pick-state { color: var(--body); }

.stack-pick-tip {
  font-family: var(--sans);
  font-size: 0.9rem;
  color: var(--body);
  border-left: 2px solid var(--accent);
  padding-left: 0.8rem;
}
.stack-pick-tip[hidden] { display: none; }

.wiz-btn:disabled,
.wiz-btn:disabled:hover { opacity: 0.45; cursor: not-allowed; filter: none; }
a.wiz-btn { text-decoration: none; display: inline-flex; align-items: center; }

.wiz-error { font-family: var(--sans); color: var(--bad); margin-bottom: 1rem; }

/* the basket */
.wiz-done-list li span:first-child small {
  display: block;
  font-family: var(--mono);
  font-size: 0.65rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
  margin-bottom: 0.15rem;
}
.wiz-done-list li { align-items: center; }
.wiz-done-list li span + span { text-align: right; }
.wiz-comment { margin-top: 0.4rem; max-width: 46rem; }
.wiz-comment textarea { width: 100%; }
.wiz-sent { display: grid; gap: 0.6rem; }

/* ══════════════════════════════
   FRONT — the shopfront and the shop (body.front): "Backroom"
   The workshop keeps the sombre house style; the front room gets light.
     gold    the brand: the A and S, the word Stacks
     teal    the instrument light: anything you can act on
     hazard  look here now: Skip once lit, a nudge, capital running out
   and one colour per stack (--stack), so "includes" can be read at a glance:
     crude hazard orange · cool teal · classy violet · solid gold
   Stamped labels and dashed edges are the texture; everything else is the
   same hairlines, mono and spacing as the rest of the site.
══════════════════════════════ */
:root {
  --gold:       #d4a24c;
  --teal:       #2ec4b6;
  --teal-ink:   #062b27;
  --hazard:     #ff6b35;
  --hazard-ink: #2b0f04;
  --violet:     #a78bfa;
}
.front [data-stack="crude"]  { --stack: var(--hazard); }
.front [data-stack="cool"]   { --stack: var(--teal); }
.front [data-stack="classy"] { --stack: var(--violet); }
.front [data-stack="solid"]  { --stack: var(--gold); }

/* brand */
.front .stack-title .din,
.front .stack-as { color: var(--gold); }
.front .stack-card .stack-name .stack-as { color: var(--stack, var(--gold)); }

/* stamped labels: Collect / Train / Deploy, Your basket, Capital */
.front .wiz-role {
  display: inline-block;
  justify-self: start;
  color: var(--hazard);
  border: 1px solid var(--hazard);
  border-radius: 3px;
  padding: 0.12rem 0.5rem;
  transform: rotate(-1.5deg);
}
.front .cap-gauge-title { color: var(--body); }

/* actions: teal */
.front .wiz-btn { color: var(--teal); border-color: var(--teal); }
.front .wiz-btn:hover { color: var(--text); background: color-mix(in srgb, var(--teal) 14%, transparent); }
.front .wiz-btn.is-primary { color: var(--teal-ink); background: var(--teal); border-color: var(--teal); }
.front .wiz-btn.is-primary:hover { color: var(--teal-ink); filter: brightness(1.1); }
.front .wiz-dot.is-current { color: var(--teal); border-color: var(--teal); }
.front .wiz-dot.is-done { color: var(--teal); border-color: color-mix(in srgb, var(--teal) 40%, transparent); }
.front .wiz-done-list li span + span { color: var(--teal); }
.front .byoc-field textarea:focus { border-color: var(--teal); }
.front .wiz-hint { color: var(--teal); }

/* the stack cards: each in its own colour */
.front .stack-card { box-shadow: inset 3px 0 0 var(--stack, var(--border2)); }
.front .stack-pick-grid .stack-card:hover { background: color-mix(in srgb, var(--stack) 7%, transparent); }
.front .stack-card.is-picked {
  background: color-mix(in srgb, var(--stack) 14%, transparent);
  box-shadow: inset 3px 0 0 var(--stack), inset 0 0 0 1px var(--stack);
}
.front .stack-card.is-picked .stack-pick-mark { background: var(--stack); border-color: var(--stack); }
.front .stack-card.is-picked .stack-pick-state { color: var(--stack); }
.front .stack-card.is-included {
  background: color-mix(in srgb, var(--stack) 6%, transparent);
  box-shadow: inset 3px 0 0 var(--stack);
  outline: 1px dashed color-mix(in srgb, var(--stack) 60%, transparent);
  outline-offset: -1px;
}
.front .stack-card.is-included .stack-pick-mark { border-color: var(--stack); border-style: dashed; }
.front .stack-card.is-included .stack-pick-mark::after { border-color: var(--stack); }
.front [data-subtitle].is-playing .sub-w.is-now { color: var(--bg); background-color: var(--stack, var(--gold)); }
.front .stack-pick-tip { border-left-color: var(--gold); }

/* "See the run / view / tournament": a teal link, and a nudge when read */
.front button.stack-hint {
  color: var(--teal);
  border-bottom: 1px dashed var(--teal);
  padding: 0.15rem 0;
}
.front button.stack-hint:hover { color: var(--text); border-bottom-style: solid; }
.front button.stack-hint.is-nudge { animation: front-nudge 0.75s ease-in-out 3; }
@keyframes front-nudge {
  50% { color: var(--hazard); border-bottom-color: var(--hazard); transform: translateX(3px); text-shadow: 0 0 10px rgba(255, 107, 53, 0.55); }
}

/* the loop: open-loop burns hazard, closed-loop runs teal */
.front .cap { --cap-hot: var(--hazard); --cap-glow: rgba(255, 107, 53, 0.30); }
.front .cap[data-mode="closed-loop"] {
  --cap-link: var(--teal);
  --cap-hot: var(--teal);
  --cap-glow: rgba(46, 196, 182, 0.35);
}
.front .cap[data-mode="open-loop"] .cap-mode-btn.is-active { color: var(--hazard); }
.front .cap[data-mode="closed-loop"] .cap-mode-btn.is-active { color: var(--teal); }
.front .cap-gauge-fill { background: var(--teal); }
.front .cap-gauge.is-warn .cap-gauge-fill { background: var(--hazard); }

/* Skip: quiet dark text while the loop makes its point, then lit up once
   both runs have been seen (.is-lit, from capital-loop.js) */
.front .cap-skip {
  color: var(--body);
  background: transparent;
  border: 1px solid var(--border2);
  border-radius: 6px;
  padding: 0.5rem 0.95rem;
  font-size: 0.8rem;
  letter-spacing: 0.06em;
  text-decoration: none;
  transition: background 0.3s, color 0.3s, border-color 0.3s, transform 0.3s;
}
.front .cap-skip:hover { color: var(--teal); border-color: var(--teal); }
.front .cap-skip.is-lit:hover { color: var(--hazard-ink); filter: brightness(1.1); }
.front .cap-skip.is-lit {
  color: var(--hazard-ink);
  background: var(--hazard);
  border-color: var(--hazard);
  transform: rotate(-2deg);
  animation: front-lit 1.6s ease-in-out infinite;
}
@keyframes front-lit {
  50% { box-shadow: 0 0 0 6px rgba(255, 107, 53, 0.18), 0 0 22px rgba(255, 107, 53, 0.45); }
}

/* "Show your working": the claim is the button. Quiet until the loop has
   made its point, then it lights up with Skip. */
.stack-tagline-open {
  font: inherit;
  letter-spacing: inherit;
  line-height: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  text-align: left;
  cursor: pointer;
}
.stack-tagline-open:focus-visible { outline: 1px solid var(--text); outline-offset: 4px; }
.stack-tagline-open strong { transition: box-shadow 0.4s, color 0.4s, text-shadow 0.4s; }
.front .stack-tagline-open:hover strong { color: var(--teal); }
.front .stack-proof.is-lit .stack-tagline-open strong {
  color: var(--text);
  box-shadow: inset 0 -0.18em 0 color-mix(in srgb, var(--teal) 75%, transparent);
  animation: front-proof-lit 1.6s ease-in-out 4;
}
@keyframes front-proof-lit {
  50% { color: var(--teal); text-shadow: 0 0 18px color-mix(in srgb, var(--teal) 55%, transparent); }
}

/* the spanner: teal on hover, like every other control here */
.front .landing-spanner:hover { color: var(--teal); border-color: var(--teal); }

@media (prefers-reduced-motion: reduce) {
  .front .cap-skip.is-lit,
  .front button.stack-hint.is-nudge,
  .front .stack-proof.is-lit .stack-tagline-open strong { animation: none; }
}

/* ── the loop's verdict: one line under the diagram, set by the mode ──
   Open-loop is the thing to avoid (hazard, struck through by its tag);
   closed-loop is the thing to build (teal). Same rhythm, so the two read
   as one argument as the loop switches. */
.cap-verdict {
  margin-top: 1.25rem;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
  font-family: var(--mono);
  font-size: 0.95rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text);
  min-height: 1.6em;
}
.cap-verdict > span { display: none; align-items: center; gap: 0.9rem; flex-wrap: wrap; }
.cap[data-mode="open-loop"]   .cap-verdict-open   { display: flex; }
.cap[data-mode="closed-loop"] .cap-verdict-closed { display: flex; }
.cap-verdict-tag {
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  border: 1px solid currentColor;
  border-radius: 3px;
  padding: 0.1rem 0.45rem;
  transform: rotate(-2deg);
}
.cap-verdict-open { color: var(--bad); }
.cap-verdict-closed { color: var(--accent); }
.front .cap-verdict-open { color: var(--hazard); }
.front .cap-verdict-closed { color: var(--teal); }
.cap-verdict > span { animation: cap-verdict-in 0.45s ease-out; }
@keyframes cap-verdict-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .cap-verdict > span { animation: none; } }
@media (max-width: 560px) { .cap-verdict { font-size: 0.8rem; letter-spacing: 0.08em; } }

/* ══════════════════════════════
   MY ACCOUNT — the customer's basket: code, apps, stacks
══════════════════════════════ */
.acct-section { display: grid; gap: 0.75rem; margin-bottom: 1.25rem; }
.acct-flash {
  font-family: var(--mono);
  font-size: 0.85rem;
  letter-spacing: 0.06em;
  color: var(--teal, var(--accent));
  border-left: 2px solid var(--teal, var(--accent));
  padding-left: 0.8rem;
  margin-bottom: 1.25rem;
}
.acct-code code {
  font-family: var(--mono);
  font-size: 1.6rem;
  letter-spacing: 0.12em;
  color: var(--text);
  background: var(--bg);
  border: 1px dashed var(--teal, var(--border2));
  border-radius: 6px;
  padding: 0.5rem 0.9rem;
  display: inline-block;
  user-select: all;
}
.acct-list { list-style: none; border-top: 1px solid var(--border); }
.acct-list li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--border);
}
.acct-list li > div { display: grid; gap: 0.2rem; min-width: 0; }
.acct-name { font-family: var(--sans); font-size: 1.05rem; color: var(--text); }
.acct-list .stack-name { font-family: var(--din); font-size: 1.25rem; font-weight: 700; }
.front .acct-list [data-stack] .stack-as { color: var(--stack, var(--gold)); }
.acct-meta { font-family: var(--sans); font-size: 0.85rem; color: var(--body); }
.acct-soon {
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
  border: 1px dashed var(--border2);
  border-radius: 3px;
  padding: 0.2rem 0.5rem;
  white-space: nowrap;
}
.acct-list a.wiz-btn { white-space: nowrap; }
.acct-help { font-family: var(--sans); font-size: 0.88rem; color: var(--body); max-width: 46rem; }
.acct-history { list-style: none; display: grid; gap: 0.4rem; }
.acct-history li { display: grid; grid-template-columns: 11rem minmax(0, 1fr); gap: 1rem; font-family: var(--mono); font-size: 0.78rem; color: var(--body); }
.acct-note { font-family: var(--sans); font-size: 0.8rem; color: var(--dim); max-width: 46rem; margin-top: 0.5rem; }
@media (max-width: 560px) {
  .acct-list li { flex-direction: column; align-items: flex-start; }
  .acct-history li { grid-template-columns: minmax(0, 1fr); gap: 0.1rem; }
  .acct-code code { font-size: 1.15rem; }
}
.front .header-account:hover { color: var(--teal); border-color: var(--teal); }

/* ══════════════════════════════
   THE SHOP, ON ONE PAGE — Collect, Train, Deploy, and the basket
   Three numbered sections and a basket beside them (below, on a phone).
   Tidyflow is always in; its mode follows the Trug choice through
   form[data-trug] (static/js/shop.js keeps that in step).
══════════════════════════════ */
.shop { display: grid; grid-template-columns: minmax(0, 1fr) 19rem; gap: 1.25rem; align-items: start; }
.shop-steps { display: grid; gap: 1.25rem; min-width: 0; }
.shop-step { position: relative; display: grid; gap: 0.6rem; margin: 0; }
.shop-n {
  position: absolute;
  top: 1.1rem;
  right: 1.25rem;
  font-family: var(--din);
  font-weight: 700;
  font-size: 2.2rem;
  line-height: 1;
  color: var(--border2);
}
.front .shop-n { color: color-mix(in srgb, var(--teal) 35%, transparent); }

.shop-more summary {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--body);
  cursor: pointer;
  width: max-content;
}
.shop-more[open] summary { margin-bottom: 0.4rem; }
.shop-more .wiz-body + .wiz-body { margin-top: 0.4rem; }

.shop-choice { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.6rem; margin-top: 0.4rem; }
.shop-option {
  display: flex;
  gap: 0.7rem;
  align-items: flex-start;
  padding: 0.8rem 0.9rem;
  border: 1px solid var(--border2);
  border-radius: 8px;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}
.shop-option input { margin-top: 0.25rem; accent-color: var(--teal, var(--accent)); }
.shop-option b { display: block; font-family: var(--sans); font-weight: 500; color: var(--text); }
.shop-option small { display: block; font-family: var(--sans); font-size: 0.8rem; color: var(--body); margin-top: 0.1rem; }
.shop-option:hover { border-color: var(--body); }
.shop-option:has(input:checked) {
  border-color: var(--teal, var(--accent));
  background: color-mix(in srgb, var(--teal, var(--accent)) 10%, transparent);
}
.shop-option:has(input:focus-visible) { outline: 1px solid var(--text); outline-offset: 2px; }

.shop-included {
  display: inline-block;
  vertical-align: middle;
  margin-left: 0.5rem;
  font-family: var(--mono);
  font-size: 0.65rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--teal, var(--accent));
  border: 1px solid currentColor;
  border-radius: 3px;
  padding: 0.12rem 0.45rem;
}
.shop-soon { color: var(--gold, #d4a24c); }
/* developers only: from Tidyflow down to the stacks it is built from */
.shop-dev {
  justify-self: start;
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  color: var(--teal, var(--accent));
  text-decoration: none;
  border-bottom: 1px dashed currentColor;
  padding-bottom: 1px;
}
.shop-dev:hover { color: var(--text); }

.shop-mode {
  font-family: var(--sans);
  font-size: 0.95rem;
  color: var(--body);
  border-left: 2px solid var(--teal, var(--accent));
  padding: 0.3rem 0 0.3rem 0.8rem;
}
.shop-mode b { color: var(--text); font-weight: 500; }
.shop-mode-own { display: none; }
.shop[data-trug="own"] .shop-mode-trug { display: none; }
.shop[data-trug="own"] .shop-mode-own { display: inline; }

/* a product's list price, beside its name, from the catalog */
.shop-price {
  display: inline-block;
  vertical-align: middle;
  margin-left: 0.75rem;
  font-family: var(--mono);
  font-size: 0.85rem;
  font-weight: 400;
  letter-spacing: 0.04em;
  color: var(--teal, var(--accent));
  white-space: nowrap;
}
.shop-per { color: var(--dim); margin-left: 0.15rem; }

/* the running total in the basket */
.shop-total {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border2);
  font-family: var(--sans);
  font-size: 1.1rem;
  color: var(--text);
}
.shop-total span + span {
  font-family: var(--mono);
  font-size: 1.15rem;
  color: var(--teal, var(--accent));
  font-variant-numeric: tabular-nums;
}
.shop-terms { font-size: 0.9rem; color: var(--dim); }

.shop-basket { position: sticky; top: 1rem; display: grid; gap: 0.75rem; margin: 0; }
.shop-send { width: 100%; justify-content: center; }
.shop-send-hint { font-family: var(--sans); font-size: 0.85rem; color: var(--body); }
/* unmistakably off, rather than merely translucent on the teal fill */
.front .wiz-btn.is-primary:disabled,
.front .wiz-btn.is-primary:disabled:hover {
  background: var(--border2);
  border-color: var(--border2);
  color: var(--dim);
  opacity: 1;
  filter: none;
}
.shop-send-hint[hidden] { display: none; }

/* ══════════════════════════════
   ONBOARDING — what a design partner sees after paying
══════════════════════════════ */
.onb-status { display: grid; gap: 0.7rem; }

.onb-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  justify-self: start;
  font-family: var(--mono);
  font-size: 0.8rem;
  letter-spacing: 0.04em;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border2);
  border-radius: 999px;
  padding: 0.4rem 0.9rem;
}
.onb-dot {
  flex: none;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--dim);
}
.onb-pill--ok   { border-color: var(--teal, var(--accent)); }
.onb-pill--ok   .onb-dot { background: var(--teal, var(--accent)); }
.onb-pill--warn { border-color: var(--gold, #d4a24c); }
.onb-pill--warn .onb-dot { background: var(--gold, #d4a24c); }
.onb-pill--bad  { border-color: var(--bad, #c98a7e); }
.onb-pill--bad  .onb-dot { background: var(--bad, #c98a7e); }

.onb-code {
  font-family: var(--mono);
  font-size: 0.95rem;
  letter-spacing: 0.1em;
  color: var(--text);
  background: var(--bg);
  border: 1px dashed var(--border2);
  border-radius: 5px;
  padding: 0.15rem 0.5rem;
  user-select: all;
}

.onb-ref {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  padding-top: 0.85rem;
  border-top: 1px solid var(--border);
}
.onb-ref-value {
  flex: 1 1 14rem;
  min-width: 0;
  font-family: var(--mono);
  font-size: 0.8rem;
  letter-spacing: 0.06em;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border2);
  border-radius: 6px;
  padding: 0.5rem 0.65rem;
}
.onb-copy { white-space: nowrap; }

/* the three steps: a numbered column, then the words */
.onb-checklist { list-style: none; display: grid; gap: 0; border-top: 1px solid var(--border); }
.onb-step {
  display: grid;
  grid-template-columns: 3.5rem minmax(0, 1fr);
  gap: 1rem;
  padding: 1.4rem 0;
  border-bottom: 1px solid var(--border);
}
.onb-step-n {
  font-family: var(--din);
  font-weight: 700;
  font-size: 1.6rem;
  line-height: 1;
  color: var(--border2);
}
.front .onb-step-n { color: color-mix(in srgb, var(--teal) 35%, transparent); }
.onb-step-body { display: grid; gap: 0.5rem; min-width: 0; }
.onb-step-title {
  font-family: var(--sans);
  font-size: 1.2rem;
  font-weight: 500;
  color: var(--text);
  letter-spacing: -0.01em;
}
.onb-step-what { font-family: var(--sans); font-size: 1rem; line-height: 1.6; color: var(--body); }
.onb-step-do {
  font-family: var(--mono);
  font-size: 0.78rem;
  line-height: 1.65;
  color: var(--body);
  border-left: 2px solid var(--teal, var(--accent));
  padding: 0.15rem 0 0.15rem 0.8rem;
}

/* the tools in this basket, and only those */
.onb-tools { list-style: none; display: grid; gap: 0.4rem; margin-top: 0.2rem; }
.onb-tools li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.6rem 0.75rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
}
.onb-tools li > div { display: grid; gap: 0.15rem; min-width: 0; }
.onb-tool-name { font-family: var(--din); font-size: 1.1rem; font-weight: 700; color: var(--text); }
.onb-tool-what { font-family: var(--sans); font-size: 0.88rem; color: var(--body); }
.onb-tools .wiz-btn { white-space: nowrap; text-decoration: none; }

.onb-help a {
  color: var(--text);
  text-decoration: none;
  border-bottom: 1px solid var(--teal, var(--accent));
}

@media (max-width: 560px) {
  .onb-step { grid-template-columns: 2.2rem minmax(0, 1fr); gap: 0.6rem; }
  .onb-step-n { font-size: 1.2rem; }
  .onb-tools li { flex-direction: column; align-items: flex-start; }
}

/* the running total in the basket */
.shop-total {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border2);
  font-family: var(--sans);
  font-size: 1.1rem;
  color: var(--text);
}
.shop-total span + span {
  font-family: var(--mono);
  font-size: 1.15rem;
  color: var(--teal, var(--accent));
  font-variant-numeric: tabular-nums;
}
.shop-terms { font-size: 0.9rem; color: var(--dim); }

/* ── design partner code: list price struck, allowance shown, rate applied ── */
.shop-promo {
  display: grid;
  gap: 0.5rem;
  padding-top: 0.85rem;
  border-top: 1px solid var(--border);
}
.shop-promo-label { font-family: var(--sans); font-size: 0.9rem; color: var(--body); }
.shop-promo-row { display: flex; gap: 0.4rem; }
.shop-promo-input {
  flex: 1;
  min-width: 0;
  font-family: var(--mono);
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border2);
  border-radius: 6px;
  padding: 0.5rem 0.65rem;
}
.shop-promo-input:focus { outline: none; border-color: var(--teal, var(--accent)); }
.shop-promo-btn {
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  color: var(--teal, var(--accent));
  background: transparent;
  border: 1px solid var(--teal, var(--accent));
  border-radius: 6px;
  padding: 0.5rem 0.8rem;
  cursor: pointer;
  transition: color 0.15s, background 0.15s;
}
.shop-promo-btn:hover { color: var(--bg); background: var(--teal, var(--accent)); }
.shop-promo-btn:disabled { opacity: 0.45; cursor: default; }
.shop-promo-error { font-family: var(--sans); font-size: 0.85rem; color: var(--bad, #c98a7e); }
.shop-promo-error[hidden] { display: none; }
.shop-promo-done { display: grid; gap: 0.5rem; }
.shop-promo-done[hidden] { display: none; }
.shop-promo-badge {
  justify-self: start;
  font-family: var(--mono);
  font-size: 0.65rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--hazard-ink, #2b0f04);
  background: var(--hazard, #ff6b35);
  border-radius: 3px;
  padding: 0.15rem 0.5rem;
  transform: rotate(-1.5deg);
}
.shop-promo-lines { list-style: none; display: grid; gap: 0.25rem; }
.shop-promo-lines li {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  font-family: var(--sans);
  font-size: 0.9rem;
  color: var(--body);
}
.shop-promo-lines li span + span,
.shop-promo-lines del { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.shop-promo-lines del { color: var(--dim); }

/* who is buying: the .byoc-field parts, stacked in the narrow basket column */
.shop-buyer {
  display: grid;
  gap: 0.6rem;
  padding-top: 0.85rem;
  border-top: 1px solid var(--border);
}
.shop-buyer .byoc-label { display: flex; align-items: center; gap: 0.5rem; }
.shop-buyer input { padding: 0.55rem 0.7rem; font-size: 0.95rem; }
.shop-promo-link { justify-self: start; text-decoration: none; }
.shop-promo-link[hidden] { display: none; }

@media (max-width: 900px) {
  .shop { grid-template-columns: minmax(0, 1fr); }
  .shop-basket { position: static; }
}
@media (max-width: 560px) {
  .shop-choice { grid-template-columns: minmax(0, 1fr); }
  .shop-n { font-size: 1.7rem; }
}

/* ══════════════════════════════
   THE SHOP, IN TWO PAGES
   Page 1 configures (/wizard/), page 2 reviews and pays (/checkout/).
   Palette is scoped to body.shop-page and body.checkout-page so the rest of
   the site keeps its own:

     base      #0F172A   surface   #1E293B   line   #26344A
     headline  #FFFFFF   body copy #E2E8F0   muted  #94A3B8
     action    #F97316   selected  #06B6D4

   Action orange appears once per page -- the one button that moves the buyer
   forward -- and never as decoration, so "the thing to press" needs no
   hunting. Cyan is only ever "this is selected". Appended last so it wins on
   source order over the .front rules above.
══════════════════════════════ */

/* A light neutral room for the three shop pages: #F4F5F7 for the page, white
   for the cards standing on it, slate for the prose, and two accents that
   each mean exactly one thing. Orange is the action; teal is the selection;
   nothing else may use either.

   These are literal values, not mappings onto --bg / --surface / --text.
   Those are the site's dark tokens, and deriving from them is why the pages
   stayed dark however the layout above them changed. */
.shop-page, .checkout-page {
  --co-bg:      #F4F5F7;
  --co-surface: #FFFFFF;
  --co-raise:   #FAFBFC;
  --co-line:    #E4E7EC;
  --co-line-2:  #D0D5DD;
  --co-text:    #101828;
  --co-body:    #344054;
  --co-muted:   #667085;
  --co-cta:     #F97316;
  --co-cta-hi:  #EA6A0C;
  --co-cta-ink: #21130A;
  --co-sel:     #0E7490;   /* #06B6D4 held at 700, so prices read on white */
  --co-bad:     #B42318;

  background: var(--co-bg);
  color: var(--co-body);
  font-family: var(--sans);
}

/* The canvas, not just the body. `html, body` above gives both the site's
   near-black, and a body shorter than the viewport would leave that dark
   showing at the edges -- which reads as "the background did not change".
   Paint all three: the document, the body, and the shell. Literal values,
   because custom properties set on the body do not inherit upwards. */
/* ── the canvas ──
   Painted on the document, the body and the shell, and marked important,
   because this is the one thing on these pages that is not negotiable: a
   shop page is #F4F5F7 from edge to edge. `html, body` at the top of this
   file gives both the site's near-black, so every corner that is not
   explicitly repainted here shows dark. */
html:has(body.shop-page),
html:has(body.checkout-page),
html body.shop-page,
html body.checkout-page,
html body.shop-page .shell,
html body.checkout-page .shell {
  background: #F4F5F7 !important;
}
html body.shop-page,
html body.checkout-page { color: #344054; }

/* the shell, the header and the footer sit in the same room as the cards,
   rather than in the site's near-black chrome */
.shop-page .site-header,
.checkout-page .site-header {
  background: var(--co-surface);
  border-bottom: 1px solid var(--co-line);
}
.shop-page .logo,
.checkout-page .logo { color: var(--co-text); }
.shop-page .login-link,
.shop-page .logout-link,
.shop-page .header-account,
.checkout-page .login-link,
.checkout-page .logout-link,
.checkout-page .header-account { color: var(--co-muted); }
.shop-page .login-link:hover,
.shop-page .logout-link:hover,
.shop-page .header-account:hover,
.checkout-page .login-link:hover,
.checkout-page .logout-link:hover,
.checkout-page .header-account:hover { color: var(--co-text); }
.shop-page .site-footer,
.checkout-page .site-footer {
  border-top: 1px solid var(--co-line);
  color: var(--co-muted);
}

/* ── the one action ── */
.co-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  width: 100%;
  font-family: var(--mono);
  font-size: 0.95rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--co-cta-ink);
  background: var(--co-cta);
  border: 1px solid var(--co-cta);
  border-radius: 8px;
  padding: 0.95rem 1.4rem;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.15s, border-color 0.15s, transform 0.12s;
}
.co-cta:hover {
  color: var(--co-cta-ink);
  background: var(--co-cta-hi);
  border-color: var(--co-cta-hi);
  transform: translateY(-1px);
}
.co-cta:focus-visible { outline: 2px solid var(--co-text); outline-offset: 3px; }

/* Not ready yet: flat grey, no lift, a cursor that says so. This is a state,
   not a dimmed call to action, so it must not read as something to press --
   the previous greyed-out primary button was the complaint that started the
   shop's redesign, and the answer is to grey it deliberately rather than to
   leave it orange and refuse on the next page. */
.co-cta:disabled,
.co-cta:disabled:hover,
.co-cta[aria-disabled="true"] {
  color: #98A2B3;
  background: #E4E7EC;
  border-color: #D0D5DD;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

/* ── page 1: the configurator ── */
.shop-page .wip-main,
.checkout-page .wip-main { max-width: 1180px; padding: 2.5rem 2rem 5rem; }

.shop-page .wip-title,
.checkout-page .wip-title { color: var(--co-text); }

/* step 1 is the choices alone: the basket has a page of its own, so the form
   is one column rather than a main column and a sidebar */
.shop-page .shop { display: block; max-width: 52rem; }
.shop-page .shop-steps { gap: 1.75rem; }

.shop-page .shop-step,
.shop-page .wiz.shop-step {
  margin: 0;
  padding: 1.75rem 1.75rem 1.6rem;
  background: var(--co-surface);
  border: 1px solid var(--co-line);
  border-radius: 12px;
}

.shop-page .shop-n {
  top: 1.5rem;
  right: 1.6rem;
  font-size: 1.9rem;
  color: var(--co-line-2);
}
.shop-page .wiz-role { color: var(--co-muted); }
.shop-page .wiz-name { color: var(--co-text); }
.shop-page .wiz-body { color: var(--co-body); }
.shop-page .shop-price { color: var(--co-sel); }
.shop-page .shop-per { color: var(--co-muted); }
.shop-page .shop-more summary { color: var(--co-muted); }
.shop-page .shop-more summary:hover { color: var(--co-text); }

.shop-page .shop-choice {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.75rem;
  margin-top: 0.9rem;
}

.shop-page .shop-option {
  padding: 1rem 1.1rem;
  background: var(--co-bg);
  border: 1px solid var(--co-line-2);
  border-radius: 10px;
}
.shop-page .shop-option b { color: var(--co-text); }
.shop-page .shop-option small { color: var(--co-muted); }
.shop-page .shop-option:hover { border-color: var(--co-sel); }
.shop-page .shop-option:has(input:checked) {
  border-color: var(--co-sel);
  box-shadow: inset 0 0 0 1px var(--co-sel);
  background: color-mix(in srgb, var(--co-sel) 10%, var(--co-bg));
}
.shop-page .shop-option input { accent-color: var(--co-sel); }
.shop-page .shop-option:has(input:focus-visible) {
  outline: 2px solid var(--co-sel);
  outline-offset: 2px;
}
.shop-page .shop-mode {
  color: var(--co-body);
  border-left-color: var(--co-sel);
}
.shop-page .shop-mode b { color: var(--co-text); }
.shop-page .shop-included {
  color: var(--co-sel);
  border-color: var(--co-sel);
}
.shop-page .shop-soon { color: var(--co-muted); }
.shop-page .shop-dev { color: var(--co-sel); }
.shop-page .acct-soon { color: var(--co-muted); border-color: var(--co-line-2); }

/* ── the basket, beside it ── */
.shop-page .shop-basket,
.shop-page .wiz.shop-basket {
  top: 1.5rem;
  gap: 0;
  padding: 0;
  background: var(--co-surface);
  border: 1px solid var(--co-line);
  border-radius: 12px;
  overflow: hidden;
}
.shop-page .shop-basket > .wiz-role {
  margin: 0;
  padding: 1.1rem 1.3rem 0.9rem;
  background: var(--co-bg);
  border-bottom: 1px solid var(--co-line);
  color: var(--co-muted);
}
.shop-page .wiz-done-list { padding: 0 1.3rem; }
.shop-page .wiz-done-list li {
  border-bottom: 1px solid var(--co-line);
  color: var(--co-text);
  padding: 0.7rem 0;
}
.shop-page .wiz-done-list li:last-child { border-bottom: 0; }
.shop-page .wiz-done-list small { color: var(--co-muted); }
.shop-page .wiz-done-list li span + span { color: var(--co-sel); }

.shop-page .shop-promo {
  padding: 1rem 1.3rem;
  border-top: 1px solid var(--co-line);
}
.shop-page .shop-promo-label { color: var(--co-muted); }
.shop-page .shop-promo-input {
  background: var(--co-bg);
  border-color: var(--co-line-2);
  color: var(--co-text);
}
.shop-page .shop-promo-input:focus { border-color: var(--co-sel); }
.shop-page .shop-promo-btn { color: var(--co-sel); border-color: var(--co-sel); }
.shop-page .shop-promo-btn:hover { color: var(--co-bg); background: var(--co-sel); }
/* an accepted code is a state, so it takes the selection colour: orange is
   kept for the button that takes money */
.shop-page .shop-promo-badge {
  color: #FFFFFF;
  background: var(--co-sel);
  transform: none;
}

.shop-page .shop-calc {
  padding: 1rem 1.3rem 1.15rem;
  background: var(--co-bg);
  border-top: 1px solid var(--co-line);
}
.shop-page .shop-calc-row { color: var(--co-body); }
.shop-page .shop-calc-row dt { color: var(--co-muted); }
.shop-page .shop-calc-row dd {
  color: var(--co-text);
  font-size: 1rem;
}
.shop-page .shop-calc-row[data-calc-allowance-row] dd { color: var(--co-sel); }
.shop-page .shop-calc-due { border-top-color: var(--co-line-2); }
.shop-page .shop-calc-due dt { color: var(--co-text); }
.shop-page .shop-calc-due dd,
.shop-page .shop-calc-due dd span {
  color: var(--co-text);
  font-size: 1.6rem;
}

.shop-page .shop-proceed { margin: 0 1.3rem 0.5rem; width: auto; }
.shop-page .shop-proceed-note {
  margin: 0 1.3rem 1.3rem;
  font-family: var(--sans);
  font-size: 0.82rem;
  color: var(--co-muted);
}

/* ── page 2: review and pay ── */
.co-head { margin-bottom: 2.25rem; }
.co-eyebrow {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--co-sel);
  margin-bottom: 0.6rem;
}
.co-title {
  font-family: var(--sans);
  font-size: clamp(1.8rem, 3.4vw, 2.4rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--co-text);
  margin-bottom: 0.5rem;
}
.co-sub {
  font-family: var(--sans);
  font-size: 1.05rem;
  line-height: 1.6;
  color: var(--co-body);
  max-width: 46rem;
}

.co-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 22rem;
  gap: 2.5rem;
  align-items: start;
}

.co-card {
  display: grid;
  gap: 1rem;
  padding: 1.6rem 1.6rem 1.5rem;
  background: var(--co-surface);
  border: 1px solid var(--co-line);
  border-radius: 12px;
}
.co-review { display: grid; gap: 1.5rem; min-width: 0; }
.co-card-label {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--co-muted);
}
.co-body { font-family: var(--sans); font-size: 1rem; line-height: 1.6; color: var(--co-body); }

.co-lines { list-style: none; border-top: 1px solid var(--co-line); }
.co-line {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.9rem 0;
  border-bottom: 1px solid var(--co-line);
}
.co-line-what { display: grid; gap: 0.15rem; min-width: 0; }
.co-line-name { font-family: var(--sans); font-size: 1.1rem; color: var(--co-text); }
.co-line-sku {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  color: var(--co-muted);
}
.co-line-price {
  font-family: var(--mono);
  font-size: 1.05rem;
  color: var(--co-text);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.co-per { color: var(--co-muted); margin-left: 0.2rem; }

.co-totals { display: grid; gap: 0.5rem; }
.co-total-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  font-family: var(--sans);
  font-size: 1rem;
  color: var(--co-body);
}
.co-total-row dt { color: var(--co-muted); }
.co-total-row dd {
  margin: 0;
  font-family: var(--mono);
  font-size: 1rem;
  color: var(--co-text);
  font-variant-numeric: tabular-nums;
}
.co-total-row--allowance dd { color: var(--co-sel); }
.co-total-row--due {
  margin-top: 0.5rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--co-line-2);
  align-items: center;
}
.co-total-row--due dt {
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--co-text);
}
.co-total-row--due dd,
.co-total-row--due dd span {
  font-size: 2rem;
  line-height: 1.1;
  color: var(--co-text);
}

.co-note { font-family: var(--sans); font-size: 0.9rem; color: var(--co-muted); }
.co-back {
  justify-self: start;
  font-family: var(--mono);
  font-size: 0.8rem;
  letter-spacing: 0.06em;
  color: var(--co-muted);
  text-decoration: none;
  border-bottom: 1px dashed var(--co-line-2);
  padding-bottom: 1px;
}
.co-back:hover { color: var(--co-text); border-bottom-color: var(--co-sel); }

.co-trust { list-style: none; display: grid; gap: 0.5rem; }
.co-trust li {
  position: relative;
  padding-left: 1.4rem;
  font-family: var(--sans);
  font-size: 0.92rem;
  line-height: 1.5;
  color: var(--co-body);
}
.co-trust li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.45em;
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 50%;
  border: 1px solid var(--co-sel);
}
.co-trust a { color: var(--co-text); text-decoration: none; border-bottom: 1px solid var(--co-line-2); }
.co-trust a:hover { border-bottom-color: var(--co-sel); }

/* the form, beside the review */
.co-details { position: sticky; top: 1.5rem; }
.co-details .co-card { gap: 0.9rem; }

.co-field { display: grid; gap: 0.35rem; }
.co-label {
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--co-muted);
}
/* Field annotations, in one place.
   The form asks for three things and requires two, so it says which is which:
   a note above the fields gives the rule, each required label repeats it, and
   the optional field is the one marked rather than the two that are not. Quiet
   mono, not red -- a payment page does not need three asterisks competing with
   the button at the bottom. */
.co-req,
.co-optional {
  font-family: var(--mono);
  font-size: 0.62rem;
  font-weight: 400;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  vertical-align: middle;
  margin-left: 0.45rem;
  color: var(--co-muted);
}

/* the sentence above the fields, set apart from them */
.co-fields-note {
  padding-bottom: 0.8rem;
  margin-bottom: 0.1rem;
  border-bottom: 1px solid var(--co-line);
}
.co-input {
  font-family: var(--sans);
  font-size: 1rem;
  color: var(--co-text);
  background: var(--co-bg);
  border: 1px solid var(--co-line-2);
  border-radius: 8px;
  padding: 0.7rem 0.85rem;
  width: 100%;
}
.co-input:focus {
  outline: none;
  border-color: var(--co-sel);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--co-sel) 22%, transparent);
}
.co-field.has-error .co-input { border-color: var(--co-bad); }
.co-error { font-family: var(--sans); font-size: 0.85rem; color: var(--co-bad); }
.co-hint { font-family: var(--sans); font-size: 0.82rem; line-height: 1.5; color: var(--co-muted); }

.co-buy { margin-top: 0.4rem; }
.co-buy-note { text-align: center; }

.co-warn {
  font-family: var(--sans);
  font-size: 0.95rem;
  line-height: 1.55;
  color: var(--co-text);
  background: color-mix(in srgb, var(--co-bad) 8%, var(--co-surface));
  border: 1px solid color-mix(in srgb, var(--co-bad) 45%, transparent);
  border-left-width: 3px;
  border-radius: 8px;
  padding: 0.85rem 1.1rem;
  margin-bottom: 1.25rem;
}
.co-warn a { color: var(--co-text); }

.co-empty { max-width: 34rem; }
.co-empty-title { font-family: var(--sans); font-size: 1.3rem; color: var(--co-text); }
.co-empty-cta { width: auto; align-self: start; }

@media (max-width: 900px) {
  .shop-page .shop { grid-template-columns: minmax(0, 1fr); gap: 1.5rem; }
  .shop-page .shop-basket { position: static; }
  .co-grid { grid-template-columns: minmax(0, 1fr); gap: 1.5rem; }
  .co-details { position: static; }
}
@media (max-width: 560px) {
  .shop-page .wip-main,
  .checkout-page .wip-main { padding: 1.5rem 1.1rem 3rem; }
  .shop-page .shop-step,
  .shop-page .wiz.shop-step { padding: 1.2rem 1.1rem 1.1rem; }
  .shop-page .shop-choice { grid-template-columns: minmax(0, 1fr); }
  .shop-page .shop-n { font-size: 1.4rem; top: 1.1rem; right: 1.1rem; }
  .co-card { padding: 1.2rem 1.1rem; }
  .co-total-row--due dd,
  .co-total-row--due dd span { font-size: 1.6rem; }
  .co-buy { font-size: 0.9rem; padding: 0.85rem 1rem; }
}

/* ── the heads: the site's mono title, set as a sentence instead ── */
.shop-page .wip-title,
.checkout-page .wip-title {
  font-family: var(--sans);
  font-size: clamp(1.8rem, 3.4vw, 2.4rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.15;
  text-transform: none;
}
.shop-page .shop-head { margin-bottom: 2rem; }
.shop-page .shop-eyebrow {
  font-family: var(--sans);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--co-sel);
  margin-bottom: 0.5rem;
}
.shop-page .shop-lede {
  font-family: var(--sans);
  font-size: 1.05rem;
  line-height: 1.6;
  color: var(--co-body);
  max-width: 46rem;
  margin-top: 0.6rem;
}
.shop-page .wiz-error { color: var(--co-bad); }

/* ── step 1's foot: the one thing to press ── */
.shop-next { display: grid; gap: 0.55rem; justify-items: start; margin-top: 2rem; }
.shop-page .shop-next .shop-proceed { width: auto; min-width: 17rem; margin: 0; }
.shop-page .shop-next .shop-proceed-note {
  margin: 0;
  max-width: 34rem;
  font-family: var(--sans);
  font-size: 0.9rem;
  color: var(--co-muted);
}

/* ── the action itself: sans, so it reads as a button, not a label ── */
.shop-page .co-cta,
.checkout-page .co-cta {
  font-family: var(--sans);
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: 0;
}

/* ── step 2: the basket on its own page ── */
.basket-page .wip-main { max-width: 46rem; }
/* the script toggles [hidden] on rows that are already display:flex, so the
   attribute has to outrank the class here */
.basket-page [hidden] { display: none !important; }
.basket-card { gap: 1.25rem; }
.basket-page .co-line-name { font-weight: 500; }
.basket-page .co-line-price.is-quiet {
  font-family: var(--sans);
  font-size: 0.95rem;
  color: var(--co-muted);
}
.basket-page .shop-promo {
  padding: 1.1rem 0 0;
  border-top: 1px solid var(--co-line);
}
.basket-page .shop-promo-error { color: var(--co-bad); }
.basket-page .shop-promo-btn {
  font-family: var(--sans);
  font-size: 0.9rem;
  font-weight: 600;
}
.basket-page .co-buy { margin-top: 0.25rem; }
.basket-page .co-back { margin-top: 0.25rem; }

/* ══════════════════════════════
   THE PIPELINE CONFIGURATOR — the same light room as the rest of the shop
   (/wizard/ only: <body class="shop-page wizard-page">)

   The three steps used to sit in a framed panel on the app's charcoal, which
   left one page of the shop in a different room from the basket and the
   checkout. There is no frame now and no second palette: the page is the
   shop's own #F4F5F7, the steps are the white cards .shop-page already
   draws, and the header and footer are the ones the other two pages have.
   What is left below is the wrapper the template still carries, told to
   stop drawing.

     chosen    #0D9488   teal, for what is selected; focus ring #14B8A6
     action    #F97316   the one button, kept from .co-cta
══════════════════════════════ */
.wizard-page {
  --wk-check:    #0D9488;
  --wk-check-hi: #14B8A6;
}

/* The template wraps the steps in .shop-workspace. The frame it drew is no
   longer wanted, so the element stays -- nothing changes in the markup, and
   the layout it was providing is now the page's own. */
.shop-workspace {
  max-width: none;
  margin: 0;
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}


/* the product a step sells, named under its tier title */
.shop-product {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--co-muted);
  margin-top: -0.35rem;
}

/* ── teal is what is chosen ── */
.wizard-page .shop-option input { accent-color: var(--wk-check); }
.wizard-page .shop-option:hover { border-color: var(--wk-check); }
.wizard-page .shop-option:has(input:checked) {
  border-color: var(--wk-check);
  background: color-mix(in srgb, var(--wk-check) 9%, #FFFFFF);
  box-shadow: inset 0 0 0 1px var(--wk-check);
}
.wizard-page .shop-option:has(input:focus-visible) {
  outline: 2px solid var(--wk-check-hi);
  outline-offset: 2px;
}
.wizard-page .shop-mode { border-left-color: var(--wk-check); }
.wizard-page .shop-dev { color: var(--wk-check); }
.wizard-page .shop-more summary { color: var(--wk-check); }
.wizard-page .shop-more summary:hover { color: #0F766E; }
.wizard-page .acct-soon { color: var(--co-muted); border-color: #D0D5DD; }

@media (max-width: 560px) {
  .wizard-page .shop-step,
  .wizard-page .wiz.shop-step { padding: 1.4rem 1.25rem 1.25rem; }
}

/* ══════════════════════════════
   THE FRONT DOOR — the marketing page at / (body.front-page)

   A light editorial page in front of the dark workshop. Every rule below is
   scoped to .front-page and named .front-*: .site-header and .site-footer
   further up this file are the site's dark chrome, and a page that borrowed
   those names would repaint them for every other page.

   Its own tokens, because the palette is its own: white and stone paper,
   charcoal ink, one deep green for the accent. --bg / --text are the
   workshop's, so they are not read here at all.
══════════════════════════════ */
.front-page {
  --fp-white:    #ffffff;
  --fp-stone:    #fafaf9;
  --fp-ink:      #18181b;
  --fp-ink-2:    #27272a;
  --fp-body:     #52525b;
  --fp-muted:    #71717a;
  --fp-line:     #e4e4e7;
  --fp-line-2:   #d4d4d8;
  --fp-green:    #14532d;
  --fp-green-hi: #166534;

  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.65;
  color: var(--fp-ink);
  background: var(--fp-white);
  -webkit-font-smoothing: antialiased;
}

/* The document, not just the body. `html, body` at the top of this file sets
   both to the site's near-black at 15px; a body shorter than the viewport
   would leave that dark showing at the edges, and every rem on this page
   would resolve against 15px. Literal values, because custom properties set
   on the body do not inherit upwards. */
html:has(body.front-page) { background: #ffffff; font-size: 16px; }
html body.front-page,
html body.front-page .shell { background: #ffffff; }

.front-container { max-width: 1100px; margin: 0 auto; padding: 0 28px; }

/* ── nav: the two ways off the page ── */
.front-header { border-bottom: 1px solid var(--fp-line); }
.front-header .front-container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-top: 22px;
  padding-bottom: 22px;
}
.front-wordmark {
  font-family: var(--mono);
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fp-ink);
  text-decoration: none;
}
.front-nav { display: flex; align-items: center; gap: 26px; }
.front-nav a {
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--fp-body);
  text-decoration: none;
  transition: color 0.15s;
}
.front-nav a:hover { color: var(--fp-ink); }

/* ── band 1: the hero ── */
.front-hero { padding: 112px 0 96px; border-bottom: 1px solid var(--fp-line); }
.front-hero-inner { max-width: 760px; }
.front-headline {
  margin-bottom: 24px;
  font-size: clamp(2.5rem, 5vw, 3.6rem);
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -0.025em;
  color: var(--fp-ink);
}
/* The third beat has a line of its own, and the word AI takes the page's
   green: the promise ends on the brand's colour rather than on charcoal, and
   the eye lands there before the paragraph underneath it. */
.front-headline-ai { color: var(--fp-green); }
/* the hero now ends with this paragraph, so it carries no trailing gap of its
   own -- the band's own padding closes the section */
.front-sub { margin-bottom: 0; font-size: 1.2rem; line-height: 1.7; color: var(--fp-body); }

/* The hero's two buttons and its trust line were removed with the copy they
   belonged to: the brief's sign-in is the gate, and the page's one link out
   is the bridge at the foot. .front-bridge-link carries the same weight the
   old primary button did, so no button style is needed on this page. */

/* ── band 2: the 1:2:3 workflow ── */
.front-band { padding: 96px 0; border-bottom: 1px solid var(--fp-line); }
.front-band--stone { background: var(--fp-stone); }
.front-h2 {
  margin-bottom: 48px;
  font-size: 1.9rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--fp-ink);
}
.front-lede { max-width: 660px; margin: -32px 0 48px; font-size: 1.1rem; color: var(--fp-body); }

.front-steps {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 28px;
}
.front-step {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 32px 28px;
  background: var(--fp-white);
  border: 1px solid var(--fp-line);
  border-radius: 6px;
}
.front-step-n {
  display: inline-block;
  margin-bottom: 14px;
  font-family: var(--mono);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  color: var(--fp-green);
}
.front-step-title { margin-bottom: 12px; font-size: 1.2rem; font-weight: 700; color: var(--fp-ink); }
.front-step-desc { margin-bottom: 28px; font-size: 0.95rem; color: var(--fp-body); }
.front-video {
  padding-top: 16px;
  border-top: 1px solid var(--fp-line);
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--fp-green);
  text-decoration: none;
}
.front-video:hover { color: var(--fp-green-hi); text-decoration: underline; }

/* ── band 3: the layered architecture ── */
.front-arch { display: flex; flex-direction: column; gap: 16px; max-width: 880px; }
.front-layer {
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr);
  gap: 24px;
  align-items: center;
  padding: 28px 32px;
  background: var(--fp-white);
  border: 1px solid var(--fp-line);
  border-radius: 6px;
}
/* All three rules are the page's one accent, the same --fp-green as the
   Get Started button: on this page green means "this is ours", and the
   layers are all ours. They used to step ink -> grey -> green to suggest
   depth, which read as three unrelated marks down the page. */
.front-layer--top  { border-left: 3px solid var(--fp-green); }
.front-layer--mid  { border-left: 3px solid var(--fp-green); }
.front-layer--base { border-left: 3px solid var(--fp-green); background: var(--fp-stone); }
.front-layer-label {
  display: block;
  margin-bottom: 6px;
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--fp-muted);
}
.front-layer-title { font-size: 1.125rem; font-weight: 700; color: var(--fp-ink); }
.front-layer-desc { font-size: 0.95rem; color: var(--fp-body); }

/* ── the page's three ways on ──
   Get Started is the action -- filled in the page's green, which is the only
   colour this page has ever used for doing something. Design keeps the
   charcoal as the argument, and Trust stays outlined as the evidence, so the
   three read as one decision and its two supporting cases rather than as
   three equal choices. All three share a footprint, so the row sits level. */
.front-more {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin: 32px 0 0;
}
.front-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 14px 28px;
  font-size: 0.975rem;
  font-weight: 600;
  color: #ffffff;
  background: var(--fp-ink);
  border: 1px solid var(--fp-ink);
  border-radius: 4px;
  text-decoration: none;
  transition: background 0.15s, border-color 0.15s;
}
.front-action:hover { background: var(--fp-ink-2); border-color: var(--fp-ink-2); }
.front-action:focus-visible { outline: 2px solid var(--fp-ink); outline-offset: 3px; }

/* the second path: same footprint, so the pair sits level */
.front-action--alt {
  color: var(--fp-ink);
  background: transparent;
  border-color: var(--fp-line-2);
}
.front-action--alt:hover {
  color: var(--fp-ink);
  background: var(--fp-stone);
  border-color: var(--fp-ink);
}

/* the action: the one filled button in the row, and the only place green is
   used to invite rather than to label */
.front-action--go {
  color: #ffffff;
  background: var(--fp-green);
  border-color: var(--fp-green);
}
.front-action--go:hover {
  color: #ffffff;
  background: var(--fp-green-hi);
  border-color: var(--fp-green-hi);
}
.front-action--go:focus-visible { outline: 2px solid var(--fp-green); outline-offset: 3px; }

/* ── foot ──
   Two rows: the standing links, then the company details. Separated so the
   links can grow without pushing the facts around, and the whole thing
   wraps rather than shrinking at narrow widths. The top hairline closes the
   page the way the hero's bottom border opens it. */
.front-footer { padding: 40px 0 36px; border-top: 1px solid var(--fp-line); }
.front-footer .front-container {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px 32px;
}
.front-foot-links { display: flex; flex-wrap: wrap; gap: 10px 24px; }
.front-foot-links a {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--fp-body);
  text-decoration: none;
  transition: color 0.15s;
}
.front-foot-links a:hover { color: var(--fp-ink); text-decoration: underline; }
.front-foot-links a:focus-visible { outline: 2px solid var(--fp-ink); outline-offset: 3px; }
.front-foot-facts {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 24px;
  font-size: 0.82rem;
  color: var(--fp-muted);
}

@media (max-width: 860px) {
  .front-hero { padding: 72px 0 64px; }
  .front-band { padding: 64px 0; }
  .front-steps { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 720px) {
  .front-layer { grid-template-columns: minmax(0, 1fr); gap: 12px; padding: 24px; }
}

/* ── the way back up, on the brief ──
   The brief is behind the gate and carries the site header, so the link home
   is part of the page's own content rather than a header control. */
.brief-back {
  display: inline-block;
  margin-bottom: 1.5rem;
  font-family: var(--mono);
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  color: var(--body);
  text-decoration: none;
  border-bottom: 1px dashed var(--border2);
  padding-bottom: 1px;
  transition: color 0.15s, border-color 0.15s;
}
.brief-back:hover { color: var(--text); border-bottom-color: var(--accent); }
.brief-back:focus-visible { outline: 1px solid var(--text); outline-offset: 3px; }

/* The reel is the front door's own band: public, and the thing the three
   "Watch" links jump to. .carousel-stage pads itself, so only the band's
   spacing is set here -- the carousel's own rules below are untouched. */
.front-reel { padding: 56px 0; }
.front-reel .carousel-stage { padding: 0; }
.front-reel .carousel-item video { background: var(--fp-stone); border: 1px solid var(--fp-line); }

/* The reel must not move the page. An item's height follows its width, and
   the widths animate (12% -> 60%), so while two items trade places the
   tallest of them is briefly shorter than either was: the band contracts,
   and the bands below it jump. Reserving the height of one active frame --
   60% of the track, 16:9 -- keeps the track still and centres the items in
   it. Purely layout: the widths, the transitions and the stills are as
   they were. */
.front-reel .carousel-track {
  align-items: center;
  aspect-ratio: 100 / 33.75;   /* 0.60 x 100 x 9 / 16 */
}
.front-reel .carousel-item { align-self: center; }

@media (max-width: 860px) { .front-reel { padding: 40px 0; } }

/* at this size one item fills 80% of the track, so the reservation grows with
   it -- the same frame, not a second one */
@media (max-width: 700px) {
  .front-reel .carousel-track { aspect-ratio: 100 / 45; }
}

/* ══════════════════════════════
   THE ENGINE ROOM — the technical brief (body.brief-page)

   Two palettes, stepped rather than jumped: warm stone for the reading
   surface, charcoal for the engine, and nothing anywhere near pitch black.
   The darkest thing on the page is an #18181b card standing on a #27272a
   container, so arriving here from the front door's white is a step down
   rather than a flash.

     stone     #fafaf9   the page
     ink       #18181b   headings
     charcoal  #3f3f46   the engine's container
     card      #2a2a30   the panels standing on it
     line      #5a5a63   edges inside the engine
     sky       #38bdf8   status and metrics
     teal      #2dd4bf   progress

   The loop (.cap) and the chain-of-custody sheet (.pp, from polyphon.css)
   are existing components: both read --bg, --surface, --border, --text,
   --body and --accent. They are repainted here by remapping those tokens
   inside .brief-engine -- so neither their rules nor capital-loop.js or
   stack.js are touched. A <dialog> in the top layer still inherits: the top
   layer changes painting, not the cascade, so the sheet opens dark too.
══════════════════════════════ */
.brief-page {
  --br-stone:    #fafaf9;
  --br-ink:      #18181b;
  --br-charcoal: #3f3f46;   /* the engine's container: a step up from zinc-800 */
  --br-card:     #2a2a30;   /* the panels standing on it, one step down */
  --br-line:     #5a5a63;   /* edges inside the engine */
  --br-body:     #52525b;
  --br-muted:    #71717a;
  --br-green:    #14532d;
  --br-sky:      #38bdf8;
  --br-teal:     #2dd4bf;

  font-family: var(--sans);
  color: var(--br-ink);
}

/* The canvas, not just the body -- the same reason as the front door: a body
   shorter than the viewport would leave the site's near-black at the edges.
   Literal values, because custom properties set on the body do not inherit
   upwards. */
html:has(body.brief-page) { background: #fafaf9; font-size: 16px; }
html body.brief-page,
html body.brief-page .shell { background: #fafaf9 !important; color: #18181b; }

/* the site chrome, repainted for this page the way the shop pages are */
.brief-page .site-header { background: #fafaf9; border-bottom: 1px solid #e4e4e7; }
.brief-page .logo { color: var(--br-ink); }
.brief-page .login-link,
.brief-page .logout-link,
.brief-page .header-account { color: var(--br-body); }
.brief-page .login-link:hover,
.brief-page .logout-link:hover,
.brief-page .header-account:hover { color: var(--br-ink); }
.brief-page .landing-spanner {
  color: var(--br-ink);
  background: #ffffff;
  border-color: #e4e4e7;
}
.brief-page .landing-spanner:hover { color: var(--br-green); border-color: var(--br-green); }
.brief-page .site-footer { border-top: 1px solid #e4e4e7; color: var(--br-muted); }

/* The reading column reads the page's light tokens -- .brief-back, the title
   and the prose all take --text / --body / --dim / --accent -- so they are
   remapped once here rather than restyled rule by rule. --gold is remapped
   too: the .din spans on the A and S are painted with it further up this
   file, and on stone they need the forest green, not the house gold. */
.brief-room {
  --text:    var(--br-ink);
  --body:    var(--br-body);
  --dim:     var(--br-muted);
  --border:  #e4e4e7;
  --border2: #d4d4d8;
  --accent:  var(--br-green);
  --gold:    var(--br-green);

  max-width: 1100px;
  font-family: var(--sans);
}

/* ── the head: the site's .stack-head, re-inked for stone ──
   Only the title and the spacing are set here. The subline is the site's
   .stack-sub, which .stack-head already sizes, and .brief-room has already
   remapped --body, so it inherits the page's own grey. */
.brief-head { max-width: 46rem; margin-bottom: 2.5rem; }
.brief-room .brief-title {
  font-family: var(--sans);
  font-size: clamp(2rem, 4vw, 2.9rem);
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -0.03em;
  color: var(--br-ink);
}

/* ── the engine: charcoal, so the loop is a room rather than a hole ──
   The token ladder is shared by the loop's container and by the proof
   sheet: the sheet now lives on the light page, so it can no longer inherit
   these from the box it used to sit in. The greys are lifted a step each --
   the site's --dim2 (#71717a) lands at about 3.7:1 on a card this dark,
   which fails for the 10-12px mono labels polyphon sets in it. The ladder
   below clears 4.5:1 at every step. */
/* The sheet is used in two places and needs the same ladder in both: as a
   <dialog> slid out over the shopfront (.stack-sheet-proof), and inline on
   the provenance page (.pp, inside .brief-room). Keying it on .pp as well
   means the inline card does not fall back to the light page's --text while
   keeping the dark --surface, which renders near-black on near-black. */
.brief-room .stack-sheet-proof,
.brief-room .pp {
  --bg:      #26262b;
  --surface: var(--br-card);
  --border:  var(--br-line);
  --border2: #6b6b75;
  --text:    #f4f4f5;
  --body:    #d4d4d8;
  --dim:     #c4c4cc;
  --dim2:    #a1a1aa;
  --accent:  var(--br-teal);
  --teal:    var(--br-teal);
}


/* ── the argument, under the subtitle ──
   Three paragraphs on the page's own paper, with the first set larger: in a
   brief, the first sentence is the summary and the rest is the case for it.
   No card, no frame -- the text is the object, and the figure below is where
   the drawing starts. */
.brief-prose {
  max-width: 44rem;
  margin: 0 0 2.75rem;
  font-family: var(--sans);
  color: var(--br-body);
}
.brief-prose p {
  margin: 0 0 1.1em;
  font-size: 1.1rem;
  line-height: 1.7;
}
.brief-prose p:first-child {
  font-size: 1.35rem;
  line-height: 1.45;
  letter-spacing: -0.015em;
  color: var(--br-ink);
}
.brief-prose p:last-child { margin-bottom: 0; }

/* The page's punchline, given the site's tagline treatment: the setup in body
   grey, the turn in ink, with the hairline the rest of the site puts above a
   concluding line. Colours are read from --body / --text / --border, which
   .brief-room has already remapped for this page, so this rule follows the
   site's palette rather than naming a hex of its own. Set larger than the
   lede above it: on the site a tagline is the loudest line in its block. */
.brief-prose .brief-tagline {
  margin: 1.9rem 0 0;
  padding-top: 1.4rem;
  border-top: 1px solid var(--border);
  font-size: 1.5rem;
  line-height: 1.4;
  letter-spacing: -0.015em;
  color: var(--body);
}
.brief-prose .brief-tagline strong {
  font-weight: 600;
  color: var(--text);
}

/* ── the provenance page's title ──
   The brand is the only coloured word on either page: the same forest green
   as the A and S on the brief, so the two pages open the same way. The
   script changes the word, not the colour; the transition is there because
   the word changes under a coloured span and the eye reads that as a repaint. */
.brief-page .brief-brand { color: var(--br-green); transition: color 0.5s ease; }

/* ── the proof sheet, following prose rather than a figure ──
   .stack-proof brings 2.5rem of top margin for following a stack of cards;
   here the paragraphs above already carry 2.75rem, so the sheet's is taken
   off and the two do not open a hole between them. */
.brief-page .brief-proof { margin: 0 0 2.5rem; }
.brief-page .brief-proof .stack-tagline { margin-top: 0; }

/* The tagline is not written on this page: it comes from
   partials/stack_proof_sheet.html, which the section above includes, so there
   is one copy and it is the linked one. These rules only repaint it.

   The body keeps class="front" because the sheet is styled through it, and
   .front paints this underline teal -- the shopfront's colour. Here it is the
   page's forest green, the same --br-green as .brief-brand and
   .brief-more-link, so the prose and the working share one colour doing one
   job. Declared later in this file than the .front rules and equal to them in
   specificity, which is why these win. */
.brief-page .stack-proof.is-lit .stack-tagline-open strong {
  box-shadow: inset 0 -0.18em 0 rgba(20, 83, 45, 0.55);
  animation-name: brief-proof-lit;
}
.brief-page .stack-tagline-open:hover strong { color: var(--br-green); }

/* .front's pulse turns the word teal mid-beat; same beat, green here */
@keyframes brief-proof-lit {
  50% {
    color: var(--br-green);
    text-shadow: 0 0 18px rgba(20, 83, 45, 0.45);
  }
}

/* ── the way on to the working ──
   A text link under the figure, not a button: the brief is an argument and
   this is the footnote that backs it. Quiet, so the page has one accent (the
   CTA in the figure) and one way further in. */
.brief-more { margin: 1.75rem 0 0; }
.brief-more-link {
  font-family: var(--sans);
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--br-green);
  text-decoration: none;
  border-bottom: 1px solid rgba(20, 83, 45, 0.35);
  padding-bottom: 2px;
  transition: color 0.15s, border-color 0.15s;
}
.brief-more-link:hover {
  color: var(--br-ink);
  border-bottom-color: var(--br-ink);
}
.brief-more-link:focus-visible { outline: 2px solid var(--br-green); outline-offset: 3px; }

/* ── DATA PROVENANCE: the room the sheet will stand in ──
   The brief's sheet has its own page now. Until the proof markup lands, the
   page says what it will hold: a dashed card, so it reads as a frame waiting
   for a drawing rather than as content that failed to load. */
.prov-placeholder {
  display: grid;
  gap: 0.6rem;
  max-width: 44rem;
  padding: 2.25rem 2rem;
  background: #ffffff;
  border: 1px dashed #d4d4d8;
  border-radius: 8px;
}
.prov-placeholder-label {
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 400;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--br-muted);
}
.prov-placeholder-title {
  font-family: var(--sans);
  font-size: 1.3rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--br-ink);
}
.prov-placeholder-body {
  max-width: 38rem;
  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.65;
  color: var(--br-body);
}

@media (max-width: 860px) {
  .prov-placeholder { padding: 1.75rem 1.25rem; }
}

/* ══════════════════════════════
   THE TECHNICAL BRIEF — FIG. 01: the architecture figure

   A schematic printed on the page rather than a dark-mode panel dropped
   onto it: brushed stone, matte, no neon. Three ideas hold it together:

     frame   a light bezel with its caption, so the drawing reads as a
             figure in an editorial page rather than a widget
     paper   stone greys stepping down from frame to panel to well to card;
             the three stage cards are the only white on the page
     ink     one colour per meaning -- forest green for the loop that
             closes, amber for the pass that does not -- and nothing else
             coloured at all

   Every animation is a CSS keyframe keyed off [data-mode] on the figure:
   the chevrons sweep once in amber for open-loop and loop continuously in
   green for closed-loop, the three cards carry a matching pulse, and the
   cards themselves animate their left/top between the row and the triangle
   via a transition. The capital bar is the exception: its drain time
   changes with the mode, so architecture-figure.js drives it by writing a
   transform + transition, and clears/redraws between passes.

   Type is the system sans throughout, including the caption and the
   button. There are no percentages on the capital well: just a sight-glass
   with ticks at the quarters, and the level is the argument.
══════════════════════════════ */

.brief-page .arch {
  --arch-sans:    -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --arch-frame:   #f4f4f5;
  --arch-panel:   #e7e5e4;
  --arch-well:    #f5f5f4;
  --arch-card:    #ffffff;
  --arch-line:    #d6d3d1;
  --arch-line-2:  #e4e4e7;
  --arch-ink:     #1c1917;
  --arch-muted:   #57534e;
  --arch-caption: #52525b;
  --arch-green:      #15803d;
  --arch-green-glow: rgba(21, 128, 61, 0.35);
  --arch-amber:      #b45309;
  --arch-amber-glow: rgba(180, 83, 9, 0.35);
  --arch-off:     #d6d3d1;
  --arch-btn:     #a8a29e;

  margin: 0 0 2.5rem;
  padding: 16px;
  background: var(--arch-frame);
  border: 1px solid var(--arch-line-2);
  border-radius: 6px;
  font-family: var(--arch-sans);
  color: var(--arch-ink);
}

/* the caption sits in the frame, above the panel */
.brief-page .arch-caption {
  margin: 2px 0 12px;
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--arch-caption);
}

.brief-page .arch-panel {
  padding: 28px;
  background: var(--arch-panel);
  border: 1px solid var(--arch-line);
  border-radius: 4px;
}

/* ── head: the switch, and the rule under it ── */
.brief-page .arch-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-start;
  gap: 12px;
  padding-bottom: 20px;
  margin-bottom: 24px;
  border-bottom: 1px solid var(--arch-line);
}

.brief-page .arch-toggle {
  display: inline-flex;
  gap: 4px;
  padding: 3px;
  background: var(--arch-well);
  border: 1px solid var(--arch-line);
  border-radius: 4px;
}

.brief-page .arch-tab {
  font-family: inherit;
  font-size: 0.8rem;
  font-weight: 500;
  line-height: 1;
  color: var(--arch-muted);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 3px;
  padding: 6px 14px;
  cursor: pointer;
  user-select: none;
  transition: color 0.2s ease, background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
}
.brief-page .arch-tab:hover { color: var(--arch-ink); }
.brief-page .arch-tab:focus-visible { outline: 2px solid var(--arch-ink); outline-offset: 2px; }
.brief-page .arch-tab.is-active {
  background: var(--arch-card);
  color: var(--arch-ink);
}
/* the active chip carries the colour of its mode: amber for the open loop,
   green for closed. That is the only place the mode colour appears before
   the drawing has begun to speak. */
.brief-page .arch[data-mode="open-loop"] .arch-tab.is-active {
  border-color: var(--arch-amber);
  box-shadow: 0 0 0 1px rgba(180, 83, 9, 0.18), 0 1px 2px rgba(28, 25, 23, 0.06);
}
.brief-page .arch[data-mode="closed-loop"] .arch-tab.is-active {
  border-color: var(--arch-green);
  box-shadow: 0 0 0 1px rgba(21, 128, 61, 0.18), 0 1px 2px rgba(28, 25, 23, 0.06);
}

/* ── body: the budget, then the well ── */
.brief-page .arch-body {
  display: grid;
  grid-template-columns: 96px minmax(0, 1fr);
  gap: 16px;
  margin-bottom: 24px;
}

/* the capital well: a sight-glass, no figure */
.brief-page .arch-well {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 20px 12px;
  background: var(--arch-well);
  border: 1px solid var(--arch-line);
  border-radius: 4px;
}

.brief-page .arch-well-label {
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--arch-muted);
}

.brief-page .arch-well-track {
  position: relative;
  width: 16px;
  height: 164px;
  background: var(--arch-panel);
  border: 1px solid var(--arch-btn);
  border-radius: 3px;
  overflow: hidden;
}

/* hairline ticks at the quarters, drawn over the fill (z-index: 2) so the
   level reads as a real gauge rather than an anonymous bar */
.brief-page .arch-well-ticks {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background-image: linear-gradient(
    to bottom,
    transparent 24.5%, rgba(28, 25, 23, 0.18) 24.5%, rgba(28, 25, 23, 0.18) 25.5%, transparent 25.5%,
    transparent 49.5%, rgba(28, 25, 23, 0.18) 49.5%, rgba(28, 25, 23, 0.18) 50.5%, transparent 50.5%,
    transparent 74.5%, rgba(28, 25, 23, 0.18) 74.5%, rgba(28, 25, 23, 0.18) 75.5%, transparent 75.5%
  );
}

/* the fill is a single-plane scaleY (or scaleX on a phone), so the drain is
   one GPU transform from full to empty. Duration and colour are set by
   architecture-figure.js because they change with the mode. */
.brief-page .arch-well-fill {
  position: absolute;
  inset: 0;
  transform-origin: bottom center;
  transform: scaleY(1);
  background: var(--arch-amber);
  box-shadow: 0 0 6px var(--arch-amber-glow);
}
.brief-page .arch[data-mode="closed-loop"] .arch-well-fill {
  background: var(--arch-green);
  box-shadow: 0 0 6px var(--arch-green-glow);
}

/* ── the well the pipeline is drawn in ── */
.brief-page .arch-pipeline {
  position: relative;
  height: 260px;
  overflow: hidden;
  background: var(--arch-well);
  border: 1px solid var(--arch-line);
  border-radius: 4px;
}

/* one SVG per shape, cross-faded on data-mode. preserveAspectRatio="none"
   lets the chevrons stretch rather than clip on a narrow well. */
.brief-page .arch-linear,
.brief-page .arch-triangle {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.35s ease;
}
.brief-page .arch[data-mode="open-loop"]   .arch-linear   { opacity: 1; }
.brief-page .arch[data-mode="closed-loop"] .arch-triangle { opacity: 1; }

.brief-page .arch-chevron {
  fill: none;
  stroke: var(--arch-off);
  stroke-width: 2.25;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* open-loop: a single amber sweep, left to right, then quiet */
.brief-page .arch[data-mode="open-loop"] .arch-linear .arch-chevron {
  animation: arch-fleche-amber 0.6s ease-in-out forwards;
}
.brief-page .arch[data-mode="open-loop"] .arch-linear .arch-chevron:nth-child(1) { animation-delay: 0.2s; }
.brief-page .arch[data-mode="open-loop"] .arch-linear .arch-chevron:nth-child(2) { animation-delay: 0.3s; }
.brief-page .arch[data-mode="open-loop"] .arch-linear .arch-chevron:nth-child(3) { animation-delay: 0.4s; }
.brief-page .arch[data-mode="open-loop"] .arch-linear .arch-chevron:nth-child(4) { animation-delay: 0.5s; }
.brief-page .arch[data-mode="open-loop"] .arch-linear .arch-chevron:nth-child(5) { animation-delay: 0.9s; }
.brief-page .arch[data-mode="open-loop"] .arch-linear .arch-chevron:nth-child(6) { animation-delay: 1.0s; }
.brief-page .arch[data-mode="open-loop"] .arch-linear .arch-chevron:nth-child(7) { animation-delay: 1.1s; }
.brief-page .arch[data-mode="open-loop"] .arch-linear .arch-chevron:nth-child(8) { animation-delay: 1.2s; }

/* closed-loop: a green wave that never stops, once per 3s */
.brief-page .arch[data-mode="closed-loop"] .arch-triangle .arch-chevron {
  animation: arch-fleche-loop 3s infinite ease-in-out;
}
.brief-page .arch[data-mode="closed-loop"] .arch-triangle .arch-chevron:nth-child(1)  { animation-delay: 0.0s; }
.brief-page .arch[data-mode="closed-loop"] .arch-triangle .arch-chevron:nth-child(2)  { animation-delay: 0.2s; }
.brief-page .arch[data-mode="closed-loop"] .arch-triangle .arch-chevron:nth-child(3)  { animation-delay: 0.4s; }
.brief-page .arch[data-mode="closed-loop"] .arch-triangle .arch-chevron:nth-child(4)  { animation-delay: 0.6s; }
.brief-page .arch[data-mode="closed-loop"] .arch-triangle .arch-chevron:nth-child(5)  { animation-delay: 0.8s; }
.brief-page .arch[data-mode="closed-loop"] .arch-triangle .arch-chevron:nth-child(6)  { animation-delay: 1.0s; }
.brief-page .arch[data-mode="closed-loop"] .arch-triangle .arch-chevron:nth-child(7)  { animation-delay: 1.2s; }
.brief-page .arch[data-mode="closed-loop"] .arch-triangle .arch-chevron:nth-child(8)  { animation-delay: 1.4s; }
.brief-page .arch[data-mode="closed-loop"] .arch-triangle .arch-chevron:nth-child(9)  { animation-delay: 1.6s; }
.brief-page .arch[data-mode="closed-loop"] .arch-triangle .arch-chevron:nth-child(10) { animation-delay: 1.8s; }
.brief-page .arch[data-mode="closed-loop"] .arch-triangle .arch-chevron:nth-child(11) { animation-delay: 2.0s; }
.brief-page .arch[data-mode="closed-loop"] .arch-triangle .arch-chevron:nth-child(12) { animation-delay: 2.2s; }
.brief-page .arch[data-mode="closed-loop"] .arch-triangle .arch-chevron:nth-child(13) { animation-delay: 2.4s; }
.brief-page .arch[data-mode="closed-loop"] .arch-triangle .arch-chevron:nth-child(14) { animation-delay: 2.6s; }
.brief-page .arch[data-mode="closed-loop"] .arch-triangle .arch-chevron:nth-child(15) { animation-delay: 2.8s; }

@keyframes arch-fleche-amber {
  0%, 100%   { stroke: var(--arch-off); filter: none; }
  35%, 65%   { stroke: var(--arch-amber); filter: drop-shadow(0 0 3px var(--arch-amber-glow)); }
}
@keyframes arch-fleche-loop {
  0%, 100%   { stroke: var(--arch-off); filter: none; }
  10%, 24%   { stroke: var(--arch-green); filter: drop-shadow(0 0 3px var(--arch-green-glow)); }
}

/* ── the three stage cards ──
   Positioned by percentage; a mode change moves left/top and the transition
   animates it, so the same three cards walk from a row into a triangle. */
.brief-page .arch-node {
  position: absolute;
  width: 124px;
  transform: translate(-50%, -50%);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 12px 16px;
  background: var(--arch-card);
  border: 1px solid var(--arch-line);
  border-radius: 4px;
  box-shadow: 0 1px 2px rgba(28, 25, 23, 0.04);
  transition:
    left 0.6s cubic-bezier(0.22, 1, 0.36, 1),
    top 0.6s cubic-bezier(0.22, 1, 0.36, 1),
    border-color 0.25s ease,
    box-shadow 0.25s ease;
}

.brief-page .arch-node-name {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--arch-ink);
  text-align: center;
}

/* open-loop: one stage after another, along the middle line. Each card
   pulses amber once as its share of the budget goes. */
.brief-page .arch[data-mode="open-loop"] .arch-node--collect {
  left: 17%; top: 50%;
  animation: arch-node-amber 0.8s ease-in-out 0.0s forwards;
}
.brief-page .arch[data-mode="open-loop"] .arch-node--train {
  left: 50%; top: 50%;
  animation: arch-node-amber 0.8s ease-in-out 0.7s forwards;
}
.brief-page .arch[data-mode="open-loop"] .arch-node--deploy {
  left: 83%; top: 50%;
  animation: arch-node-pulse-amber 1.5s ease-in-out 1.4s infinite;
}

/* closed-loop: the base at the top, the apex below. Each card breathes
   green on the same beat the chevrons travel on. */
.brief-page .arch[data-mode="closed-loop"] .arch-node--collect {
  left: 25%; top: 23%;
  animation: arch-node-loop 3s infinite ease-in-out 0s;
}
.brief-page .arch[data-mode="closed-loop"] .arch-node--train {
  left: 75%; top: 23%;
  animation: arch-node-loop 3s infinite ease-in-out 1s;
}
.brief-page .arch[data-mode="closed-loop"] .arch-node--deploy {
  left: 50%; top: 77%;
  animation: arch-node-loop 3s infinite ease-in-out 2s;
}

@keyframes arch-node-amber {
  0%, 100%   { border-color: var(--arch-line); box-shadow: 0 1px 2px rgba(28, 25, 23, 0.04); }
  25%, 75%   { border-color: var(--arch-amber); box-shadow: 0 0 0 1px rgba(180, 83, 9, 0.18), 0 1px 3px rgba(180, 83, 9, 0.10); }
}
@keyframes arch-node-pulse-amber {
  0%, 100%   { border-color: var(--arch-line); box-shadow: 0 1px 2px rgba(28, 25, 23, 0.04); }
  50%        { border-color: var(--arch-amber); box-shadow: 0 0 0 1px rgba(180, 83, 9, 0.22), 0 0 8px rgba(180, 83, 9, 0.15); }
}
@keyframes arch-node-loop {
  0%, 34%, 100% { border-color: var(--arch-line); box-shadow: 0 1px 2px rgba(28, 25, 23, 0.04); }
  8%, 26%       { border-color: var(--arch-green); box-shadow: 0 0 0 1px rgba(21, 128, 61, 0.18), 0 1px 3px rgba(21, 128, 61, 0.10); }
}

/* ── foot: the sentence, and the way further in ── */
.brief-page .arch-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 24px;
  padding-top: 20px;
  border-top: 1px solid var(--arch-line);
}

.brief-page .arch-statement {
  font-family: var(--arch-sans);
  font-size: 0.875rem;
  line-height: 1.4;
  color: var(--arch-ink);
}
.brief-page .arch-statement > span { display: none; }
.brief-page .arch[data-mode="closed-loop"] .arch-statement-closed {
  display: inline-flex; align-items: center; gap: 8px;
}
.brief-page .arch[data-mode="open-loop"] .arch-statement-open {
  display: inline-flex; align-items: center; gap: 8px;
}

/* the status mark: upright, inline, one colour per meaning; the sentence
   that follows it does the arguing */
.brief-page .arch-mark {
  font-family: var(--arch-sans);
  font-weight: 600;
  font-size: 0.95rem;
  line-height: 1;
}
.brief-page .arch-statement-closed .arch-mark { color: var(--arch-green); }
.brief-page .arch-statement-open   .arch-mark { color: var(--arch-amber); }

.brief-page .arch-cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 18px;
  font-family: inherit;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--arch-ink);
  text-decoration: none;
  background: var(--arch-well);
  border: 1px solid var(--arch-btn);
  border-radius: 4px;
  white-space: nowrap;
  transition: background-color 0.15s ease;
}
.brief-page .arch-cta:hover { background: var(--arch-panel); }
.brief-page .arch-cta:focus-visible { outline: 2px solid var(--arch-ink); outline-offset: 2px; }

/* motion is decoration: the drawing says the same thing standing still */
@media (prefers-reduced-motion: reduce) {
  .brief-page .arch-chevron,
  .brief-page .arch-node { animation: none !important; }
  .brief-page .arch-node { transition: none; }
  .brief-page .arch-well-fill { transition: none !important; }
}

/* on a phone the budget lies down and the well stacks under it */
@media (max-width: 680px) {
  .brief-page .arch { padding: 12px; }
  .brief-page .arch-panel { padding: 18px; }

  .brief-page .arch-body {
    grid-template-columns: minmax(0, 1fr);
    gap: 12px;
  }

  .brief-page .arch-well {
    flex-direction: row;
    align-items: center;
    gap: 12px;
    padding: 12px 16px;
  }
  .brief-page .arch-well-track {
    flex: 1;
    width: auto;
    height: 14px;
    min-width: 0;
  }
  .brief-page .arch-well-ticks {
    background-image: linear-gradient(
      to right,
      transparent 24.5%, rgba(28, 25, 23, 0.18) 24.5%, rgba(28, 25, 23, 0.18) 25.5%, transparent 25.5%,
      transparent 49.5%, rgba(28, 25, 23, 0.18) 49.5%, rgba(28, 25, 23, 0.18) 50.5%, transparent 50.5%,
      transparent 74.5%, rgba(28, 25, 23, 0.18) 74.5%, rgba(28, 25, 23, 0.18) 75.5%, transparent 75.5%
    );
  }
  .brief-page .arch-well-fill { transform-origin: left center; }

  .brief-page .arch-node { width: 104px; padding: 10px 12px; }
}

