/* ============================================================
   ROBIOS BASE — reset, chrome (banner/nav/mascot), shared utils
   ============================================================ */

/* Display face, self-hosted. One variable file covers weight 600-900 and width
   100-125%, so every heading on the site costs a single 88KB request instead of
   four static cuts · and cdnfonts, which is slow and unofficial, is not in the
   path. font-display:swap so text paints in the fallback rather than vanishing. */
@font-face {
  font-family: Archivo;
  src: url("../assets/fonts/archivo-var.woff2") format("woff2-variations");
  font-weight: 600 900;
  font-stretch: 100% 125%;
  font-style: normal;
  font-display: swap;
}

/* The width axis is the whole point of the switch · without this the face falls
   back to its normal width and looks like any other grotesk. Applied to every
   element that uses the display font, in one place, so no section can forget. */
h1, h2, h3, h4,
.sec-head h2,
[class*="-title"],
.nav-logo,
.btn {
  font-stretch: var(--display-wdth);
}

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

/* The UA stylesheet hides [hidden] with `display: none`, but that is a plain
   element rule · ANY author class carrying a display (.badge-new{display:flex},
   .infra-tag, .ags-how, .article-loading, .ide-tree) outranks it and the thing
   stays on screen with the attribute set. This project has patched that locally
   three separate times after shipping the bug; state it once, globally, so the
   fourth time cannot happen. */
[hidden] { display: none !important; }
html { scroll-behavior: smooth; }
body {
  background: var(--bg-base);
  color: var(--text-primary);
  font-family: var(--font-ui);
  font-size: var(--fs-base);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
img, svg, video, canvas { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
input { font: inherit; color: inherit; }
::selection { background: var(--accent); color: var(--accent-text-on); }

/* Slick scrollbars, everywhere (page + every inner scroller).
   `scrollbar-color` inherits from the root; modern Chrome prefers the
   standard props over ::-webkit-* — keep both in sync. */
html { scrollbar-color: #2E3238 transparent; }
* { scrollbar-width: thin; }
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: #26292E;
  border-radius: var(--radius-pill);
  border: 2px solid transparent;
  background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover { background-color: #3A3F46; background-clip: padding-box; }
::-webkit-scrollbar-corner { background: transparent; }

/* ---------- Layout helpers ---------- */
.wrap { max-width: var(--content-max); margin-inline: auto; padding-inline: 16px; }
.sec { padding-block: 28px; }

/* Section header: small display title left + optional link right */
.sec-head {
  display: flex; align-items: baseline; justify-content: space-between;
  margin-bottom: 14px;
}
.sec-head h2 {
  font-family: var(--font-display);
  font-size: 18px; font-weight: 700;
  text-transform: uppercase; letter-spacing: var(--ls-display);
}
.sec-head .sec-link {
  font-size: 13px; color: var(--text-muted);
  transition: color var(--dur-fast) var(--ease-ui);
}
.sec-head .sec-link:hover { color: var(--accent); }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: 36px; padding: 0 12px;
  border-radius: var(--radius-btn);
  font-size: 14px; font-weight: 500; white-space: nowrap;
  transition: background-color var(--dur-fast) var(--ease-ui),
              color var(--dur-fast) var(--ease-ui),
              filter var(--dur-fast) var(--ease-ui),
              transform var(--dur-fast) var(--ease-pop);
}
.btn-primary { background: var(--accent); color: var(--accent-text-on); }
.btn-primary:hover { filter: brightness(1.06); }
.btn-primary:active { transform: scale(0.97); }
.btn-ghost { background: var(--accent-08); color: var(--accent); }
.btn-ghost:hover { background: var(--accent-20); }
.btn-dark { background: var(--bg-elevated); color: var(--text-primary); }
.btn-dark:hover { background: #2B2F34; }

/* ---------- Badges ---------- */
.badge-new {
  display: inline-flex; align-items: center;
  background: var(--accent); color: var(--accent-text-on);
  border-radius: var(--radius-badge);
  font-size: var(--fs-badge); font-weight: var(--fw-badge);
  padding: 2px 6px; line-height: 1.3; letter-spacing: 0.01em;
}
.badge-soft {
  display: inline-flex; align-items: center;
  background: var(--accent-20); color: var(--accent);
  border-radius: var(--radius-badge);
  font-size: var(--fs-badge); font-weight: var(--fw-badge);
  padding: 2px 6px; line-height: 1.3;
}
.badge-hot {
  display: inline-flex; align-items: center;
  background: var(--hot-pink); color: #fff;
  border-radius: var(--radius-badge);
  font-size: var(--fs-badge); font-weight: var(--fw-badge);
  padding: 2px 6px; line-height: 1.3; font-style: italic;
}

/* ---------- Filter pills ---------- */
.pill {
  display: inline-flex; align-items: center; gap: 6px;
  height: 32px; padding: 4px 12px;
  border-radius: var(--radius-pill);
  font-size: 12px; font-weight: 500; color: var(--text-muted);
  transition: color var(--dur-fast) var(--ease-ui), background-color var(--dur-fast) var(--ease-ui);
}
.pill:hover { color: var(--text-primary); }
.pill.active { background: #fff; color: #1A1A1A; }

/* ---------- Cards ---------- */
.card {
  background: var(--bg-card);
  border-radius: var(--radius-card);
  box-shadow: var(--inset-highlight);
}
.card-lg { border-radius: var(--radius-card-lg); overflow: hidden; }

/* ---------- Scroll reveal (auto-wired by js/main.js) ---------- */
.reveal { opacity: 0; transform: translateY(12px); }
.reveal.in {
  opacity: 1; transform: none;
  transition: opacity 0.5s var(--ease-pop), transform 0.5s var(--ease-pop);
}
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; }
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* ---------- Terminal typewriter (used with Robi.helpers.typewriter) ---------- */
.tw { font-family: var(--font-mono); }
.tw-caret {
  display: inline-block; width: 8px; height: 1.1em;
  background: var(--accent); vertical-align: text-bottom; margin-left: 2px;
  animation: tw-blink 1s steps(1) infinite;
}
@keyframes tw-blink { 50% { opacity: 0; } }

/* ============================================================
   CHROME: promo banner + nav (built in index.html, not a section)
   ============================================================ */
.promo-banner {
  height: var(--promo-banner-h);
  background: var(--accent); color: var(--accent-text-on);
  display: flex; align-items: center; justify-content: center; gap: 8px;
  font-size: 14px; font-weight: 500; position: relative; z-index: 60;
}
.promo-banner b { font-weight: 700; }
.promo-banner .promo-close {
  position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
  width: 28px; height: 28px; display: grid; place-items: center;
  border-radius: 8px; opacity: 0.7;
  transition: opacity var(--dur-fast) var(--ease-ui), background-color var(--dur-fast) var(--ease-ui);
}
.promo-banner .promo-close:hover { opacity: 1; background: rgba(0,0,0,0.08); }

.nav {
  position: sticky; top: 0; z-index: 50;
  height: var(--nav-h);
  background: var(--bg-base);
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  display: flex; align-items: center;
}
.nav-inner {
  width: 100%; max-width: var(--content-max); margin-inline: auto;
  padding-inline: 16px;
  display: flex; align-items: center; gap: 20px;
}
.nav-logo { display: flex; align-items: center; gap: 8px; font-family: var(--font-display); font-weight: 700; font-size: 15px; letter-spacing: var(--ls-display); }
.nav-logo svg { width: 20px; height: 20px; }
.nav-links { display: flex; align-items: center; gap: 4px; flex: 1; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.nav-links::-webkit-scrollbar { display: none; }
.nav-links a {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 8px; border-radius: var(--radius-sm);
  font-size: var(--fs-nav); font-weight: var(--fw-nav); color: var(--text-muted);
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease-ui);
}
.nav-links a:hover { color: var(--text-primary); }
.nav-actions { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.nav-burger { display: none; }

/* Download sits third in the hierarchy: dark, not lime · Launch Robi stays the
   only loud CTA. Icon only, and not for looks: .nav-inner is capped at 1440,
   so the row never gets wider than it is at 1440 · where the links already eat
   1009 of 1108px. A labelled button (106px) pushed them into overflow; the
   glyph alone (34px) fits with room to spare. The label lives on the tooltip. */
.nav-download {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; padding: 0; height: 32px;
}
.nav-download svg { width: 15px; height: 15px; }
.nav-download span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }

/* 11 links + logo + actions inside .nav-inner (capped at 1440px):
   roomier tabs so the row fills the bar without dead space on the right */
.nav-inner { gap: 18px; }
.nav-links { gap: 6px; }
.nav-links a { padding: 6px 13px; font-size: 13.5px; }
.nav-links a .badge-new,
.nav-links a .badge-hot { font-size: 9px; padding: 1px 4px; }
@media (max-width: 1400px) {
  .nav-links { gap: 2px; }
  .nav-links a { padding: 5px 7px; font-size: 12.5px; }
}
/* nav still overflowing (~1101-1300px): fade the clipped edge so it reads
   as scrollable, not broken; main.js drops the class at scroll end */
.nav-links.is-scroll {
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 30px), transparent);
  mask-image: linear-gradient(to right, #000 calc(100% - 30px), transparent);
}

@media (max-width: 1100px) {
  .nav-links { display: none; }
  .nav-burger { display: grid; place-items: center; width: 36px; height: 36px; border-radius: 8px; color: var(--text-muted); }
  .nav-burger:hover { color: var(--text-primary); background: var(--bg-white-5); }
}

/* ============================================================
   CHROME: Robi assistant widget (built by js/main.js)
   ============================================================ */
.robi-assist {
  position: fixed; right: 16px; bottom: 16px; z-index: 80;
  display: flex; flex-direction: column; align-items: flex-end; gap: 8px;
  pointer-events: none;
}
.robi-assist * { pointer-events: auto; }
/* Phones: do not sit on the hero composer's Send button. js/main.js sets
   .is-away while that composer is on screen; wider layouts have room for both. */
.robi-assist { transition: opacity var(--dur-med) var(--ease-ui), transform var(--dur-med) var(--ease-ui); }
@media (max-width: 760px) {
  .robi-assist.is-away { opacity: 0; transform: translateY(10px); visibility: hidden; }
  .robi-assist.is-away * { pointer-events: none; }
}
.robi-bubble {
  max-width: 260px;
  background: var(--bg-card); color: var(--text-primary);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 12px; border-bottom-right-radius: 4px;
  box-shadow: var(--shadow-card-xl);
  padding: 10px 12px; font-size: 13px; line-height: 1.45;
  opacity: 0; transform: translateY(6px) scale(0.98);
  transition: opacity var(--dur-med) var(--ease-pop), transform var(--dur-med) var(--ease-pop);
}
.robi-bubble.show { opacity: 1; transform: none; }
.robi-bubble .robi-bubble-close {
  float: right; margin-left: 8px; color: var(--text-faint); font-size: 11px;
}
.robi-bubble .robi-bubble-close:hover { color: var(--text-primary); }
.robi-face {
  width: 56px; height: 56px; border-radius: 50%;
  overflow: hidden; border: 2px solid var(--accent);
  box-shadow: 0 0 0 3px rgba(52, 183, 221,0.15), var(--shadow-card-xl);
  cursor: pointer;
  transition: transform var(--dur-med) var(--ease-pop);
  animation: robi-breathe 4s ease-in-out infinite;
}
.robi-face:hover { transform: scale(1.08); }
.robi-face.bounce { animation: robi-bounce 0.3s var(--ease-pop); }
.robi-face img { width: 100%; height: 100%; object-fit: cover; }

/* ---------- Robi FM radio toggle (sits on the mascot's corner) ---------- */
/* wrapper keeps the radio pinned to the FACE, not the whole column · and it must
   NOT reset .robi-assist, which stays position:fixed so the mascot rides the
   scroll and never sinks to the bottom of the page (that regression was exactly
   this rule setting position:relative on .robi-assist). */
.robi-face-wrap { position: relative; pointer-events: auto; }
.robi-radio {
  position: absolute;
  right: -4px; bottom: -4px;
  width: 24px; height: 24px;
  display: grid; place-items: center;
  padding: 0;
  border: 2px solid var(--bg-base);
  border-radius: 50%;
  background: var(--bg-elevated);
  color: var(--text-secondary);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease-ui), background var(--dur-fast) var(--ease-ui), transform var(--dur-fast) var(--ease-pop);
}
.robi-radio:hover { transform: scale(1.12); color: var(--text-primary); }
.robi-radio svg { width: 13px; height: 13px; }
.robi-radio .robi-radio-on { display: none; }
/* playing: lime badge, equaliser icon, and the mascot gets a soft lime pulse */
.robi-assist.radio-on .robi-radio {
  background: var(--accent);
  color: var(--accent-text-on);
}
.robi-assist.radio-on .robi-radio .robi-radio-off { display: none; }
.robi-assist.radio-on .robi-radio .robi-radio-on { display: block; animation: robi-eq 1.1s ease-in-out infinite; }
.robi-assist.radio-on .robi-face {
  box-shadow: 0 0 0 3px rgba(52, 183, 221,0.35), 0 0 18px rgba(52, 183, 221,0.35), var(--shadow-card-xl);
}
@keyframes robi-eq { 0%, 100% { opacity: 0.75; } 50% { opacity: 1; } }

/* "врубите музончик" tag · own element beside the mascot, so section hints in
   the speech bubble can never overwrite it. Hidden until armed, gently bobs. */
.robi-radio-hint {
  position: absolute;
  right: calc(100% + 10px);
  bottom: 2px;
  white-space: nowrap;
  padding: 6px 11px;
  border-radius: var(--radius-pill);
  background: var(--accent);
  color: var(--accent-text-on);
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 600;
  box-shadow: var(--shadow-card-xl);
  opacity: 0;
  transform: translateX(6px);
  pointer-events: none;
  transition: opacity var(--dur-med) var(--ease-ui), transform var(--dur-med) var(--ease-pop);
}
.robi-assist.show-radio-hint .robi-radio-hint {
  opacity: 1;
  transform: translateX(0);
  animation: robi-hint-bob 1.6s ease-in-out infinite;
}
.robi-radio-hint::after {
  content: "";
  position: absolute;
  right: -5px; bottom: 8px;
  width: 9px; height: 9px;
  background: var(--accent);
  transform: rotate(45deg);
}
@keyframes robi-hint-bob { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(-3px); } }
@media (prefers-reduced-motion: reduce) {
  .robi-assist.show-radio-hint .robi-radio-hint { animation: none; }
}
@media (prefers-reduced-motion: reduce) {
  .robi-assist.radio-on .robi-radio .robi-radio-on { animation: none; }
}
@keyframes robi-breathe { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-2px); } }
@keyframes robi-bounce { 0% { transform: scale(1); } 40% { transform: scale(0.88); } 100% { transform: scale(1); } }

/* ============================================================
   A11Y + MOBILE NAV (added 2026-07-16)
   Keyboard focus rings for shared chrome, skip-to-content link,
   and the working mobile burger dropdown. Purely additive — no
   existing rule above is modified.
   ============================================================ */

/* Keyboard focus ring for shared chrome. Only shows for keyboard users
   (:focus-visible); reuses the --ring-accent pattern already used in
   ~17 component files, so it reads as part of the same system. */
.btn:focus-visible,
.nav-logo:focus-visible,
.nav-links a:focus-visible,
.nav-burger:focus-visible,
.pill:focus-visible {
  outline: none;
  box-shadow: var(--ring-accent);
}
/* promo-close sits on the lime banner, where a lime ring would vanish. */
.promo-banner .promo-close:focus-visible {
  outline: 2px solid rgba(0, 0, 0, 0.55);
  outline-offset: 1px;
}

/* Skip to content: the first tab stop on every page, off-screen until
   focused, then it slides in. Jumps focus to <main id="main-content">. */
.skip-link {
  position: fixed;
  top: 8px; left: 8px;
  z-index: 100;
  padding: 8px 14px;
  border-radius: var(--radius-btn);
  background: var(--accent);
  color: var(--accent-text-on);
  font-size: 14px; font-weight: 600;
  box-shadow: var(--shadow-card-xl);
  transform: translateY(calc(-100% - 12px));
  transition: transform var(--dur-fast) var(--ease-ui);
}
.skip-link:focus { outline: none; transform: none; }

/* Mobile nav dropdown — js/main.js toggles .nav-open on the sticky <header class="nav">.
   Higher specificity than the .nav-links { display:none } rule above, so it wins. */
@media (max-width: 1100px) {
  .nav-open .nav-links {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    position: absolute;
    top: 100%; left: 0; right: 0;
    max-height: calc(100vh - var(--nav-h));
    padding: 8px;
    overflow-x: hidden;
    overflow-y: auto;
    background: var(--bg-base);
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    box-shadow: var(--shadow-card-xl);
    -webkit-mask-image: none;
    mask-image: none;
    z-index: 55;
  }
  .nav-open .nav-links a {
    padding: 11px 12px;
    font-size: 15px;
    border-radius: var(--radius-sm);
  }
  .nav-open .nav-links a:hover { background: var(--bg-white-5); }
  .nav-burger[aria-expanded="true"] {
    color: var(--text-primary);
    background: var(--bg-white-5);
  }
}

/* Mobile overflow guard (2026-11-10): sections whose inner scrollers (pipeline
   track, marketplace pills) are wider than a phone widened the whole page to
   ~500px at 390px, which also pushed fixed workspace dialogs off-screen.
   Grid/flex children must be allowed to shrink so those scrollers scroll. */
@media (max-width: 760px) {
  main, section, .sec-pipeline *, .sec-marketplace * { min-width: 0; }
  .sec-pipeline .pipeline-track { min-width: 880px; }
  .nav-actions { gap: 6px; }
  .nav-actions .btn { padding-left: 10px; padding-right: 10px; }
  .sec-marketplace .marketplace-toolbar, .sec-marketplace .marketplace-pills, .sec-marketplace .marketplace-tools { max-width: 100%; width: 100%; }
  html, body { overflow-x: clip; }
}
