/* runupbiz hub: the components only the hub has. Every token, the type, grid, header, buttons, tiles, ladder, climb and
   footer come from the one design system /rb/steps/v1/rb-steps.css (FE framework/templates/landing-static/system).
   This file defines no colour, size or font token of its own (tests/hub-structure.test.mjs checks it). */

/* the logo in header and footer: mark B + the name set in the display face; "Biz" takes the link colour of the theme */
.logo { display: inline-flex; align-items: center; gap: var(--rb-s2); }
.logo-mark-wrap, .logo-mark { display: block; width: 28px; height: 28px; }
.logo-word { font: 800 1.1875rem/1 var(--rb-font-display); letter-spacing: -0.02em; color: var(--rb-ink-1); }
.logo-word b { font-weight: 800; color: var(--rb-link); }

/* header buttons and the phone menu (public/rb-theme.js toggles .is-open and aria-expanded) */
.hub-icon-btn { display: inline-grid; place-items: center; width: 44px; height: 44px; border-radius: var(--rb-r2); border: 1px solid var(--rb-line); background: transparent; color: var(--rb-ink-1); cursor: pointer; }
.hub-icon-btn:hover { border-color: var(--rb-line-strong); }
.theme-moon { display: none; }
:root[data-theme="light"] .theme-sun { display: none; }
:root[data-theme="light"] .theme-moon { display: block; }
@media (prefers-color-scheme: light) { :root:not([data-theme="dark"]) .theme-sun { display: none; } :root:not([data-theme="dark"]) .theme-moon { display: block; } }
.hub-nav__login { display: none !important; }
@media (max-width: 767px) {
  .site-header .rb-actions { gap: var(--rb-s1); }
  .site-header.is-open .rb-nav { display: grid; position: absolute; inset: var(--rb-header) 0 auto 0; padding: var(--rb-s3) var(--rb-gutter) var(--rb-s5); background: var(--rb-bg); border-bottom: 1px solid var(--rb-line); }
  .site-header.is-open .hub-nav__login { display: inline-flex !important; }
}
@media (min-width: 768px) { .menu-btn { display: none; } }

/* phones: the hero buttons run the full width in every language (the copy column sizes its children to their content) */
@media (max-width: 479px) { .rb-hero__copy > .rb-actions-row { justify-self: stretch; } }

/* hero: the proof line under the buttons */
.hub-proof { display: flex; flex-wrap: wrap; align-items: center; gap: var(--rb-s2) var(--rb-s3); margin: 0; padding: 0; list-style: none; font-size: var(--rb-t-small); color: var(--rb-ink-2); }
.hub-proof li { display: inline-flex; align-items: baseline; gap: var(--rb-s2); }
.hub-proof li:first-child { margin-inline-end: var(--rb-s2); }
.hub-proof b { font: 800 1.125rem/1 var(--rb-font-display); color: var(--rb-ink-1); font-variant-numeric: tabular-nums; }
/* each state count is drawn as its own ladder (S2), so the signature is above the fold on a phone too */
.hub-proof .rb-ladder { padding-block: var(--rb-s1); }
.hub-proof .rb-ladder b { font-size: 1em; color: inherit; margin-inline-end: 0.3em; }

/* hero: the staircase, mark B's stroke at hero size (tread = riser, a heavy stroke, the dot above and past the top step).
   A product stands on each tread with its number and its state; the base of the stairs lines up with the proof line, so
   the hero has one ground. The step state is set as words without the pill here: a pill that wraps reads as a blob. */
.hub-stairs { position: relative; display: none; grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: end; align-self: end; margin: 0; padding: 0 3rem 0 0; list-style: none; width: 100%; max-width: 40rem; justify-self: end; }
@media (min-width: 768px) { .hub-stairs { display: grid; } }
.hub-stairs > li { position: relative; min-width: 0; border-bottom: 10px solid var(--rb-violet); }
.hub-stairs > li:nth-child(1) { border-bottom-left-radius: 5px; }
.hub-stairs > li:nth-child(2) { margin-bottom: 6.5rem; }
.hub-stairs > li:nth-child(3) { margin-bottom: 13rem; border-bottom-right-radius: 5px; }
.hub-stairs > li + li::before { content: ""; position: absolute; left: -10px; bottom: -6.5rem; width: 10px; height: calc(6.5rem + 10px); background: var(--rb-violet); }
.hub-stairs a { display: grid; gap: var(--rb-s2); justify-items: start; padding: 0 var(--rb-s2) var(--rb-s4) var(--rb-s4); color: inherit; text-decoration: none; }
.hub-stairs a:hover .hub-stairs__name > span:first-child { text-decoration: underline; }
.hub-stairs .p-icon { margin-bottom: var(--rb-s1); box-shadow: 0 12px 28px -14px var(--p-glow); }
.hub-stairs__name { display: flex; flex-direction: column; align-items: flex-start; gap: var(--rb-s1); font: 800 1.125rem/1.2 var(--rb-font-display); color: var(--rb-ink-1); }
:lang(zh) .hub-stairs__name { font-weight: 700; }
.hub-stairs .rb-ladder { padding: 0; background: none; white-space: nowrap; line-height: 1.3; }
.hub-stairs .rb-ladder__bars { flex: none; }
.hub-stairs__dot { position: absolute; right: -2.5rem; bottom: 3.25rem; width: 22px; height: 22px; border-radius: 50%; background: var(--rb-violet); box-shadow: 0 0 28px var(--p-glow); }
/* the state words on a step need about 145 px on one line ("Coming to Google Play", measured), so the hero keeps one
   column up to 1279 px with the stairs under the copy, and from 1280 px the copy column is held to the headline's width and
   the stairs take the rest (about 150 px of words per step) */
@media (min-width: 1024px) and (max-width: 1279px) { #top > .hub-hero--stairs { grid-template-columns: minmax(0, 1fr); } }
@media (min-width: 1280px) { #top > .hub-hero--stairs { grid-template-columns: minmax(31rem, 1fr) minmax(0, 1.25fr); } }
/* tablets and small laptops: the stairs sit under the copy at full width, so they climb less and do not push the index off the screen */
@media (min-width: 768px) and (max-width: 1279px) {
  .hub-stairs { max-width: 42rem; margin-top: calc(-1 * var(--rb-s6)); }
  .hub-stairs > li:nth-child(2) { margin-bottom: 4rem; }
  .hub-stairs > li:nth-child(3) { margin-bottom: 8rem; }
  .hub-stairs > li + li::before { bottom: -4rem; height: calc(4rem + 10px); }
  .hub-stairs__name { flex-direction: row; align-items: baseline; gap: var(--rb-s2); }
}
@media (prefers-reduced-motion: no-preference) {
  .hub-stairs > li { animation: hub-climb 0.6s cubic-bezier(0.16, 1, 0.3, 1) both; }
  .hub-stairs > li:nth-child(2) { animation-delay: 0.12s; }
  .hub-stairs > li:nth-child(3) { animation-delay: 0.24s; }
  @keyframes hub-climb { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
}

/* hero: the flagship (only when products.json names one with a public listing) */
.hub-flagship { margin: 0; display: grid; gap: var(--rb-s4); padding: var(--rb-s6); border: 1px solid var(--rb-line); border-radius: var(--rb-r3); background: var(--rb-surface); box-shadow: 0 30px 60px -30px var(--p-glow); }
.hub-flagship__link { display: grid; gap: var(--rb-s3); justify-items: start; color: inherit; text-decoration: none; }
.hub-flagship__name { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--rb-s1) var(--rb-s3); font: 800 var(--rb-t-h2)/1.05 var(--rb-font-display); color: var(--rb-ink-1); }
:lang(zh) .hub-flagship__name { font-weight: 700; }
/* from 768 px the flagship stands on the top tread of the mark's stroke: its base is the tread, a riser and a lower tread
   lead into it from the left, the dot sits past it; the base lines up with the proof line like the staircase does */
@media (min-width: 768px) {
  .hub-flagship { position: relative; align-self: end; margin: 0 3rem 6.5rem 3.5rem; border-bottom: 10px solid var(--rb-violet); border-radius: var(--rb-r3) var(--rb-r3) 0 5px; }
  .hub-flagship::before { content: ""; position: absolute; right: 100%; bottom: calc(-6.5rem - 10px); width: 3.5rem; height: calc(6.5rem + 10px); border: 0 solid var(--rb-violet); border-width: 0 10px 10px 0; border-bottom-left-radius: 5px; }
  .hub-flagship::after { content: ""; position: absolute; right: -2.5rem; bottom: 3.25rem; width: 22px; height: 22px; border-radius: 50%; background: var(--rb-violet); box-shadow: 0 0 28px var(--p-glow); }
}
.hub-flagship__tag { font-size: var(--rb-t-lead); }
.hub-flagship__foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--rb-s3); }
.hub-tile--flag { grid-column: span 2; }
/* the featured tile leads the index: the mark's violet stroke along its top, the glow of the hero in its corner, a larger
   icon and name; everything else (ladder, number, link) is the same tile */
.hub-tile--flag > .rb-tile { box-shadow: inset 0 4px 0 var(--rb-violet); background-image: radial-gradient(26rem 12rem at 100% 0%, var(--p-glow), transparent 70%); }
.hub-tile--flag .p-icon.is-md { width: 56px; height: 56px; }
.hub-tile--flag .rb-tile__name { font-size: 1.5rem; line-height: 1.15; }
/* two columns (640-1023): when the cells are odd (the flagship counts two) the last tile takes the whole row, no empty cell */
@media (min-width: 640px) and (max-width: 1023px) {
  .rb-lines--3 > li:first-child:not(.hub-tile--flag) ~ li:last-child:nth-child(odd),
  .rb-lines--3 > .hub-tile--flag ~ li:last-child:nth-child(even) { grid-column: 1 / -1; }
}
@media (max-width: 639px) { .hub-tile--flag { grid-column: auto; } }

/* product tiles carry the product icon (ProductIcon) */
.p-icon { flex: none; display: inline-grid; place-items: center; overflow: hidden; border-radius: 24%; font: 800 1rem/1 var(--rb-font-display); }
.p-icon img { width: 100%; height: 100%; }
.p-icon.is-sm { width: 32px; height: 32px; } .p-icon.is-md { width: 44px; height: 44px; } .p-icon.is-lg { width: 64px; height: 64px; font-size: 1.5rem; }
.rb-tile .p-icon { grid-row: 1 / span 2; }

/* build log: newest first; the violet stroke runs down the list, the newest dot is filled */
.hub-log { margin: 0; padding: 0; list-style: none; display: grid; max-width: 56rem; }
.hub-log > li { position: relative; display: grid; grid-template-columns: 7rem auto 1fr; align-items: center; gap: var(--rb-s4); min-height: 64px; padding: var(--rb-s3) 0 var(--rb-s3) var(--rb-s5); border-left: 2px solid var(--rb-violet); }
.hub-log > li::before { content: ""; position: absolute; left: -7px; top: 50%; width: 12px; height: 12px; margin-top: -6px; border-radius: 50%; background: var(--rb-bg); border: 2px solid var(--rb-violet); }
.hub-log > li:first-child::before { background: var(--rb-violet); box-shadow: 0 0 16px var(--p-glow); }
.hub-log time { font: 600 var(--rb-t-label)/1 var(--rb-font-mono); color: var(--rb-ink-3); font-variant-numeric: tabular-nums; }
.hub-log a { display: flex; align-items: center; gap: var(--rb-s3); min-height: 44px; color: var(--rb-ink-1); text-decoration: none; font-weight: 700; min-width: 0; }
.hub-log a:hover { text-decoration: underline; }
.hub-log__what { color: var(--rb-ink-2); font-size: var(--rb-t-small); min-width: 0; }
@media (max-width: 639px) { .hub-log > li { grid-template-columns: 1fr; gap: var(--rb-s1); } }
/* wide screens: the heading on the left (4/12), the log beside it (8/12); the heading stays in view while the log scrolls */
@media (min-width: 1024px) {
  .hub-split { display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); gap: var(--rb-s8); align-items: start; }
  .hub-split > .rb-head { position: sticky; top: calc(var(--rb-header) + var(--rb-s6)); margin-bottom: 0; }
}

/* the footer already keeps one section of space above it: the last home section adds none of its own */
main > .rb-section:last-of-type { padding-bottom: 0; }

/* principles: three columns with a top rule, no cards */
.hub-principles { display: grid; gap: var(--rb-s6); margin: 0; padding: 0; list-style: none; }
.hub-principles li { border-top: 1px solid var(--rb-line-strong); padding-top: var(--rb-s5); display: grid; gap: var(--rb-s3); align-content: start; }
@media (min-width: 768px) { .hub-principles { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

/* /products */
.hub-catalog-head { padding-bottom: var(--rb-s6); }
.hub-group { padding-top: var(--rb-s8); }
.hub-group .rb-head { margin-bottom: var(--rb-s5); }
.hub-rows > li { position: relative; display: flex; align-items: center; }
.hub-row { flex: 1; min-width: 0; display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; align-items: center; gap: var(--rb-s4); padding: var(--rb-s4) var(--rb-s5); min-height: 76px; color: inherit; text-decoration: none; }
.hub-row:hover { background: var(--rb-surface-2); }
.hub-row__text { display: grid; min-width: 0; }
.hub-row__name { font: 800 1.0625rem/1.3 var(--rb-font-display); color: var(--rb-ink-1); }
.hub-row__name .rb-no { margin-inline-start: var(--rb-s2); }
.hub-row__tag { font-size: var(--rb-t-small); color: var(--rb-ink-2); }
.hub-row__platforms { font-size: var(--rb-t-label); color: var(--rb-ink-3); white-space: nowrap; }
.hub-rows .rb-badge { margin-inline-end: var(--rb-s4); }
/* collections are sub-heads of the one page title, not rivals to it */
.hub-group .rb-head { gap: var(--rb-s2); }
.hub-group .rb-head h2 { font-size: clamp(1.5rem, 1.25rem + 0.9vw, 2rem); line-height: 1.15; }
.hub-group .rb-head p { font-size: var(--rb-t-body); }
/* the state sits in one column on every row, so the eye can run down it like a table */
@media (min-width: 768px) { .hub-row { grid-template-columns: auto minmax(0, 1fr) auto 12.5rem; } .hub-row .rb-ladder { justify-self: start; } .hub-row__platforms { justify-self: end; } }
@media (max-width: 767px) { .hub-row { grid-template-columns: auto minmax(0, 1fr); } .hub-row__platforms { display: none; } .hub-row .rb-ladder { grid-column: 2; justify-self: start; } }
/* the toolbar: one light row (search, then each choice as a segmented control: one outline, the chosen part tinted),
   no panel. From 768 px it stays under the header while the list scrolls, full-bleed bg and a hairline, so 100+ rows
   stay filterable; on phones it scrolls away and the list gets the screen. A segment that does not fit scrolls sideways
   instead of breaking the row. */
.hub-filter { display: flex; flex-wrap: wrap; align-items: center; gap: var(--rb-s3) var(--rb-s5); padding-block: var(--rb-s3); background: var(--rb-bg); }
.js .hub-filter[hidden] { display: flex; visibility: hidden; }
@media (min-width: 768px) {
  .hub-filter { position: sticky; top: var(--rb-header); z-index: 10; box-shadow: 0 0 0 100vmax var(--rb-bg), 0 1px 0 100vmax var(--rb-line); clip-path: inset(0 -100vmax -1px); }
}
.hub-filter__search { flex: 1 1 14rem; min-width: 0; max-width: 22rem; }
@media (max-width: 767px) { .hub-filter__search { flex-basis: 100%; max-width: none; } }
.hub-filter__search input { width: 100%; min-height: 44px; padding: 0 var(--rb-s4); border: 1px solid var(--rb-line-strong); border-radius: 999px; background: var(--rb-surface); color: var(--rb-ink-1); font: inherit; font-size: var(--rb-t-small); }
.hub-filter fieldset { display: flex; align-items: center; min-inline-size: 0; max-width: 100%; margin: 0; padding: 0; border: 0; }
.hub-filter legend { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.hub-seg { display: inline-flex; gap: 2px; max-width: 100%; overflow-x: auto; scrollbar-width: none; border: 1px solid var(--rb-line); border-radius: 999px; background: var(--rb-surface); padding: 2px; }
.hub-seg::-webkit-scrollbar { display: none; }
.hub-chip { flex: none; min-height: 44px; padding: 0 0.875rem; border: 0; border-radius: 999px; background: transparent; color: var(--rb-ink-2); font: 600 var(--rb-t-small)/1 var(--rb-font-body); white-space: nowrap; cursor: pointer; }
.hub-chip:hover { color: var(--rb-ink-1); background: var(--rb-surface-2); }
.hub-chip[aria-pressed="true"] { background: var(--rb-info-bg); color: var(--rb-info); font-weight: 800; }
.hub-filter__count { flex: none; margin: 0 0 0 auto; font-size: var(--rb-t-small); color: var(--rb-ink-3); white-space: nowrap; }
@media (max-width: 767px) { .hub-filter__count { flex-basis: 100%; margin: 0; } }
.hub-empty { padding: var(--rb-s7) 0; font-weight: 700; color: var(--rb-ink-1); }
.hub-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* legal pages and the 404 inside the site frame */
/* legal pages: a readable measure (42rem, about 70 characters), every section numbered in the catalogue-number style and
   set off by a hairline (the one signature here: no glow, no motion), a section index that is a plain list on phones and
   sits sticky beside the text from 1024 px */
.legal { max-width: 46rem; margin-inline: auto; padding: var(--rb-s8) var(--rb-gutter) var(--rb-s9); display: grid; gap: var(--rb-s7); }
.legal > * { min-width: 0; }
.legal h1 { font-size: var(--rb-t-h2); line-height: 1.1; margin-bottom: var(--rb-s3); }
.legal-updated { font: 600 var(--rb-t-label)/1.4 var(--rb-font-mono); color: var(--rb-ink-3); margin-bottom: var(--rb-s5); }
.legal-intro { font-size: var(--rb-t-lead); line-height: 1.6; color: var(--rb-ink-1); }
:lang(zh) .legal-updated { font: 600 var(--rb-t-label)/1.4 var(--rb-font-body); letter-spacing: 0.04em; }
.legal-apps { columns: 2; column-gap: var(--rb-s7); }
.legal-apps li { break-inside: avoid; }
@media (min-width: 640px) { .legal-apps { columns: 3; } }
.legal-text section { border-top: 1px solid var(--rb-line); padding-top: var(--rb-s6); margin-top: var(--rb-s7); scroll-margin-top: calc(var(--rb-header) + var(--rb-s4)); }
.legal-text section:first-child { margin-top: 0; }
.legal h2 { display: flex; align-items: baseline; gap: var(--rb-s3); font-size: 1.375rem; line-height: 1.25; margin: 0 0 var(--rb-s4); }
.legal-no { flex: none; color: var(--rb-link); }
.legal p, .legal li { margin-bottom: var(--rb-s3); }
.legal-toc { border: 1px solid var(--rb-line); border-radius: var(--rb-r2); background: var(--rb-surface); padding: var(--rb-s4) var(--rb-s5) var(--rb-s2); }
.legal-toc__h { font: 700 var(--rb-t-label)/1 var(--rb-font-body); letter-spacing: 0.06em; text-transform: uppercase; color: var(--rb-ink-3); margin-bottom: var(--rb-s2); }
:lang(zh) .legal-toc__h { text-transform: none; letter-spacing: 0.04em; }
.legal-toc ol { list-style: none; margin: 0; padding: 0; }
.legal-toc li { margin: 0; }
.legal-toc li + li { border-top: 1px solid var(--rb-line); }
.legal-toc a { display: flex; align-items: baseline; gap: var(--rb-s3); min-height: 44px; padding-block: var(--rb-s3); color: var(--rb-ink-2); font-size: var(--rb-t-small); line-height: 1.4; text-decoration: none; }
.legal-toc a:hover { color: var(--rb-ink-1); }
.legal-toc a:hover span:last-child { text-decoration: underline; }
@media (min-width: 1024px) {
  .legal--toc { max-width: var(--rb-max); grid-template-columns: 15rem minmax(0, 42rem); grid-template-areas: "toc head" "toc text"; justify-content: center; column-gap: var(--rb-s9); }
  .legal-head { grid-area: head; }
  .legal-text { grid-area: text; }
  .legal-toc { grid-area: toc; align-self: start; position: sticky; top: calc(var(--rb-header) + var(--rb-s6)); border: 0; background: none; padding: var(--rb-s2) 0 0; }
}
.not-found { max-width: 46rem; margin-inline: auto; padding: 0 var(--rb-gutter); display: grid; gap: var(--rb-s8); }
.not-found-block { display: grid; gap: var(--rb-s4); justify-items: start; }
.not-found-block h1, .not-found-block h2 { font-size: var(--rb-t-h2); line-height: 1.1; }
.not-found-code { margin-bottom: calc(-1 * var(--rb-s6)); color: var(--rb-link); font-size: var(--rb-t-small); }
.not-found-block + .not-found-block { border-top: 1px solid var(--rb-line); padding-top: var(--rb-s8); }
.cta-group { display: flex; flex-wrap: wrap; gap: var(--rb-s3); }
