/* NOTE: .page-header-section / .app-author-credit live in core.css. */

#robotCanvas {
  touch-action: pan-y;
}

/* ══════════════════════════════════════════════════════════════════
   ІЗБАСАР РОБОТЫ GUIDE PAGE — page-specific layout
   (moved out of index.html's inline <style> block so this page's CSS
   lives in one file, cacheable and diffable like every other stylesheet
   instead of re-shipped inline on every request)
══════════════════════════════════════════════════════════════════ */

/* ---------------------------------------------------------------- */
/* Shared layout tokens                                             */
/* ---------------------------------------------------------------- */
/* One fluid horizontal inset used by the breadcrumb bar, the shell,
   and every card-like section below (intro, parts summary, gate
   teaser). Using a single clamp() instead of separate vw values per
   section is what keeps everything's left/right edge lined up at
   every viewport width instead of jumping independently at
   different breakpoints. Mobile-first: increased minimums for better spacing. */
:root {
  --guide-pad-x: clamp(1.75rem, 6vw, 4rem);
  --card-pad: clamp(2.25rem, 7vw, 3.25rem);
  --hero-pad: clamp(2.5rem, 8vw, 4.25rem);
  --hero-pad-y: clamp(2.75rem, 9vw, 4.5rem);
}
.guide-shell {
  display: flex;
  flex-direction: column;
  gap: 0;
  padding: 0 var(--guide-pad-x) 4rem;
}
.guide-nav {
  display: flex;
  gap: clamp(0.3rem, 1vw, 0.4rem);
  overflow-x: auto;
  overflow-y: hidden;
  touch-action: pan-x pan-y;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: clamp(0.65rem, 1.5vw, 0.75rem) clamp(0.15rem, 1vw, 0.25rem);
  margin-bottom: clamp(1.2rem, 3vw, 1.5rem);
  position: sticky;
  top: var(--nav-h, 72px);
  z-index: 20;
  background: var(--bg);
  border-bottom: 0.5px solid var(--border);
}
.guide-nav::-webkit-scrollbar {
  display: none;
}
@media (min-width: 640px) {
  .guide-shell {
    padding-bottom: 6rem;
  }
  .guide-nav {
    margin-bottom: 2rem;
  }
}
/* Only meaningful on desktop (see the 1040px block below, where it
   becomes position:absolute). Below that, .guide-nav is a row of
   horizontally-scrolling pills and this rail has no layout rules of
   its own — left visible it sits as an empty first flex child,
   adding a stray gap before the first pill and nudging the whole
   scroller over. */
.guide-nav-rail {
  display: none;
}
.guide-nav-link {
  flex-shrink: 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
  text-decoration: none;
  padding: clamp(0.45rem, 1vw, 0.5rem) clamp(0.75rem, 1.5vw, 0.9rem);
  border-radius: 999px;
  border: 0.5px solid var(--border);
  white-space: nowrap;
  transition: all 0.2s;
}
.guide-nav-link.active {
  color: var(--accent-foreground);
  background: var(--accent);
  border-color: transparent;
}
.guide-content {
  max-width: 980px;
  margin: 0 auto;
  width: 100%;
}
.guide-content > section,
.guide-content #gatedContent > section {
  padding: 0;
}

/* Desktop: real sidebar with vertical progress rail */
@media (min-width: 1040px) {
  .guide-shell {
    flex-direction: row;
    align-items: flex-start;
    justify-content: flex-start;
    gap: 3rem;
  }
  .guide-nav {
    flex-direction: column;
    overflow: visible;
    width: 230px;
    flex-shrink: 0;
    margin-bottom: 0;
    padding: 0 0 0 1.1rem;
    background: none;
    border-bottom: none;
    top: calc(var(--nav-h, 96px) + 2rem);
    gap: 0.15rem;
  }
  .guide-nav-rail {
    display: block;
    position: absolute;
    left: 0;
    top: 0.3rem;
    bottom: 0.3rem;
    width: 2px;
    background: var(--border);
    border-radius: 2px;
  }
  .guide-nav-rail-fill {
    position: absolute;
    left: 0;
    top: 0;
    width: 2px;
    background: var(--accent);
    border-radius: 2px;
    transition: height 0.15s ease-out;
  }
  .guide-nav-link {
    border: none;
    border-radius: 8px;
    padding: 0.55rem 0.9rem;
    text-align: left;
  }
  .guide-nav-link.active {
    background: rgba(45, 106, 79, 0.14);
    color: var(--accent2);
  }
  .guide-content {
    margin: 0;
  }
}

/* ---------------------------------------------------------------- */
/* Intro                                                             */
/* ---------------------------------------------------------------- */
/* Mobile-first card: centered text stack + centered 3D stage. */
#intro,
.intro-section {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  background: var(--bg2);
  border: 0.5px solid var(--border);
  border-radius: 8px;
  padding: clamp(1.75rem, 5vw, 2.5rem) clamp(1.25rem, 4vw, 2.5rem);
  margin-top: clamp(1.25rem, 3vw, 2rem);
  margin-bottom: clamp(1.5rem, 4vw, 2.5rem);
  scroll-margin-top: 6.5rem;
  text-align: center;
  box-shadow: none;
  box-sizing: border-box;
  width: 100%;
}
.intro-section .guide-section-head {
  width: 100%;
  text-align: center;
  margin-bottom: 0.85rem;
}
.intro-section .sec-title {
  font-size: clamp(26px, 3.4vw, 34px);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--accent2);
  margin: 0;
}
.intro-section p {
  position: relative;
  font-size: 14px;
  color: var(--muted);
  line-height: 1.7;
  max-width: 36rem;
  margin: 0 auto;
  text-align: center;
}
.intro-section p + p {
  margin-top: 0.75rem;
}
.intro-section a {
  color: var(--accent2);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.intro-section a:hover {
  color: var(--accent);
}

/* 3D model stage — mobile-first, no extra gap below model */
.intro-section .intro-visual,
.intro-section .hero-visual {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  width: 100%;
  max-width: 100%;
  margin-top: 1.25rem;
  margin-left: auto;
  margin-right: auto;
  margin-bottom: 0;
  padding-bottom: 0;
  box-sizing: border-box;
  /* Override core.css .hero-visual so no empty band appears */
  aspect-ratio: auto;
  height: auto;
  min-height: 0;
  background: transparent;
  border: none;
  overflow: visible;
}
.intro-section .intro-visual .hero-stage {
  position: relative;
  width: 100%;
  /* Slightly taller on mobile so the model fills the frame */
  aspect-ratio: 1 / 0.92;
  border-radius: 6px;
  overflow: hidden;
  background: var(--bg);
  border: 0.5px solid var(--border);
  box-sizing: border-box;
}
.intro-section .intro-visual .hero-stage model-viewer,
.intro-section .intro-visual .hero-stage #robotCanvas {
  display: block;
  width: 100%;
  height: 100%;
  touch-action: pan-y;
}
.intro-section .intro-visual .hero-stage-glow {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
}

/* Zoom controls on model-viewer (bottom-right corner) */
.mv-zoom-controls {
  position: absolute;
  right: 0.55rem;
  bottom: 0.55rem;
  z-index: 10;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}
.mv-zoom-btn {
  width: 36px;
  height: 36px;
  min-width: 36px;
  min-height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--hero-ctrl-bg, rgba(255, 255, 255, 0.92));
  color: var(--accent2);
  cursor: pointer;
  padding: 0;
  appearance: none;
  -webkit-appearance: none;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.mv-zoom-btn:hover,
.mv-zoom-btn:focus-visible {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-foreground);
  outline: none;
}
[data-theme="dark"] .mv-zoom-btn {
  background: var(--hero-ctrl-bg, rgba(22, 35, 28, 0.9));
}

/* Shared control buttons (used by bottom demo animation) */
.intro-section .intro-visual .ctrl-wrap,
.demo-anim-controls {
  position: static;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.85rem;
  z-index: auto;
}
.intro-section .intro-visual .ctrl-btn,
.demo-anim-controls .ctrl-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 600;
  line-height: 1;
  padding: 0.6rem 0.9rem;
  border-radius: 4px;
  border: 1px solid var(--accent);
  background: transparent;
  color: var(--accent2);
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s, box-shadow 0.15s;
  box-shadow: none;
  appearance: none;
  -webkit-appearance: none;
}
.intro-section .intro-visual .ctrl-btn svg,
.demo-anim-controls .ctrl-btn svg {
  flex-shrink: 0;
  display: block;
  width: 14px;
  height: 14px;
}
.intro-section .intro-visual .ctrl-btn:hover,
.demo-anim-controls .ctrl-btn:hover {
  background: rgba(45, 106, 79, 0.14);
  box-shadow: 0 4px 14px rgba(45, 106, 79, 0.15);
}
.intro-section .intro-visual .ctrl-btn.active,
.demo-anim-controls .ctrl-btn.active {
  background: var(--accent);
  border-color: transparent;
  color: var(--accent-foreground);
  box-shadow: none;
}
.intro-section .intro-visual .ctrl-btn.active:hover,
.demo-anim-controls .ctrl-btn.active:hover {
  box-shadow: 0 4px 14px rgba(45, 106, 79, 0.15);
}

@media (min-width: 480px) {
  .intro-section {
    padding: clamp(2rem, 5vw, 2.75rem) clamp(1.5rem, 5vw, 3rem);
  }
  .intro-section p {
    font-size: 14.5px;
    line-height: 1.75;
  }
  .intro-section .intro-visual,
  .intro-section .hero-visual {
    max-width: 480px;
    margin-top: 1.5rem;
  }
  .intro-section .intro-visual .hero-stage {
    aspect-ratio: 1 / 0.88;
  }
  .mv-zoom-btn {
    width: 38px;
    height: 38px;
  }
}
@media (min-width: 640px) {
  .intro-section {
    padding: clamp(2.25rem, 5vw, 3.25rem) clamp(2rem, 6vw, 3.5rem);
  }
  .intro-section p {
    font-size: 15.5px;
    line-height: 1.8;
    max-width: 38rem;
  }
  .intro-section p + p {
    margin-top: 0.9rem;
  }
  .intro-section .intro-visual,
  .intro-section .hero-visual {
    max-width: 560px;
    margin-top: 1.75rem;
  }
  .intro-section .intro-visual .hero-stage {
    aspect-ratio: 1 / 0.82;
  }
  .intro-section .intro-visual .ctrl-wrap,
  .demo-anim-controls {
    margin-top: 1rem;
    gap: 0.6rem;
  }
  .intro-section .intro-visual .ctrl-btn,
  .demo-anim-controls .ctrl-btn {
    font-size: 13px;
    padding: 0.65rem 1rem;
  }
}
@media (min-width: 900px) {
  .intro-section .intro-visual,
  .intro-section .hero-visual {
    max-width: 620px;
  }
}

/* ---------------------------------------------------------------- */
/* Bottom interactive car demo (old Three.js animation)              */
/* ---------------------------------------------------------------- */
.demo-anim-section {
  margin-top: 2rem;
  margin-bottom: 1.5rem;
  scroll-margin-top: 6.5rem;
  text-align: center;
}
.demo-anim-section .guide-section-head {
  margin-bottom: 0.65rem;
}
.demo-anim-section .sec-title {
  font-size: clamp(22px, 3.2vw, 30px);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--accent2);
  margin: 0;
}
.demo-anim-desc {
  font-size: 13.5px;
  color: var(--muted);
  line-height: 1.65;
  max-width: 36rem;
  margin: 0 auto 1.15rem;
}
.demo-anim-visual {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  width: 100%;
  max-width: 100%;
  margin: 0 auto;
}
.demo-anim-stage {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 0.92;
  border-radius: 6px;
  overflow: hidden;
  background: var(--bg);
  border: 0.5px solid var(--border);
  box-sizing: border-box;
}
.demo-anim-stage #robotCanvas {
  display: block;
  width: 100%;
  height: 100%;
  touch-action: pan-y;
}
.demo-anim-stage .hero-stage-glow {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
}
@media (min-width: 480px) {
  .demo-anim-visual {
    max-width: 480px;
  }
  .demo-anim-stage {
    aspect-ratio: 1 / 0.88;
  }
  .demo-anim-desc {
    font-size: 14px;
  }
}
@media (min-width: 640px) {
  .demo-anim-section {
    margin-top: 2.5rem;
    margin-bottom: 2rem;
  }
  .demo-anim-visual {
    max-width: 560px;
  }
  .demo-anim-stage {
    aspect-ratio: 1 / 0.82;
  }
  .demo-anim-desc {
    font-size: 14.5px;
    margin-bottom: 1.35rem;
  }
}
@media (min-width: 900px) {
  .demo-anim-visual {
    max-width: 620px;
  }
}

/* ---------------------------------------------------------------- */
/* Parts grid                                                        */
/* ---------------------------------------------------------------- */
#parts {
  scroll-margin-top: 6.5rem;
  margin-bottom: 2rem;
}
#build-log {
  scroll-margin-top: 6.5rem;
  margin-bottom: 2rem;
}
@media (min-width: 640px) {
  #parts {
    margin-bottom: 2.75rem;
  }
  #build-log {
    margin-bottom: 2.75rem;
  }
}
.parts-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.1rem;
  margin-top: 1.5rem;
}
.part-card {
  perspective: 1400px;
  cursor: pointer;
  outline: none;
}
.part-card:focus-visible .part-card-front,
.part-card:focus-visible .part-card-back {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(45, 106, 79, 0.25);
}
.part-card-inner {
  position: relative;
  height: 100%;
  min-height: 240px;
  transition: transform 0.7s cubic-bezier(0.4, 0.15, 0.15, 1);
  transform-style: preserve-3d;
}
.part-card.is-flipped .part-card-inner {
  transform: rotateY(180deg);
}
.part-card-face {
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  border-radius: 8px;
  border: 0.5px solid var(--border);
  background: var(--bg2);
  transition:
    border-color 0.2s,
    transform 0.2s,
    box-shadow 0.2s;
}
.part-card-front {
  position: relative;
  height: 100%;
  padding: 1.5rem;
  border-left: 3px solid var(--accent);
}
.part-card:not(.is-flipped):hover .part-card-front {
  border-color: var(--accent);
  transform: translateY(-2px);
  box-shadow: 0 4px 14px rgba(45, 106, 79, 0.15);
}
.part-card-back {
  position: absolute;
  inset: 0;
  transform: rotateY(180deg);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.part-card-back img {
  flex: 1;
  min-height: 0;
  width: 100%;
  object-fit: cover;
  display: block;
}
.part-back-label {
  flex-shrink: 0;
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 700;
  color: var(--accent2);
  background: var(--bg2);
  border-top: 0.5px solid var(--border);
  padding: 0.65rem 1rem;
}
.part-flip-hint {
  position: absolute;
  top: 0.9rem;
  right: 0.9rem;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--accent);
  background: rgba(45, 106, 79, 0.1);
  opacity: 0.55;
  transition:
    opacity 0.2s,
    transform 0.2s;
}
.part-card:hover .part-flip-hint {
  opacity: 1;
  transform: rotate(35deg);
}
.part-card-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.75rem;
}
.part-icon {
  width: 40px;
  height: 40px;
  border-radius: 6px;
  background: rgba(45, 106, 79, 0.12);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.part-tag {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--accent2);
  background: rgba(45, 106, 79, 0.12);
  border-radius: 999px;
  padding: 0.32rem 0.7rem;
  white-space: nowrap;
}
.part-card--wide .part-intro {
  max-width: 62ch;
  font-size: 14px;
  line-height: 1.7;
  color: var(--text);
  margin-bottom: 0;
}
@media (min-width: 760px) {
  .part-card--wide .part-card-front {
    padding: 1.75rem 1.9rem;
  }
}
.part-card h3 {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 700;
  margin-bottom: 0.5rem;
  color: var(--accent2);
}
.part-card--wide h3 {
  font-size: 18px;
  margin-bottom: 0.55rem;
}
.part-card p {
  font-size: 13px;
  color: var(--muted);
  line-height: 1.6;
}
.part-card h4 {
  font-family: var(--font-body);
  font-size: 11.5px;
  font-weight: 700;
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-top: 0.9rem;
  margin-bottom: 0.35rem;
}
@media (min-width: 640px) {
  .parts-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 1.5rem;
    margin-top: 2rem;
  }
  .part-icon {
    width: 44px;
    height: 44px;
  }
  .part-card h4 {
    font-size: 12.5px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .part-card-inner {
    transition: none;
  }
  .part-card:not(.is-flipped):hover .part-card-front {
    transform: none;
  }
}

/* ---------------------------------------------------------------- */
/* Steps                                                             */
/* ---------------------------------------------------------------- */
.step-container {
  margin: 0 0 2rem;
  scroll-margin-top: 6.5rem;
}
@media (min-width: 640px) {
  .step-container {
    margin-bottom: 2.75rem;
  }
}
.step-header {
  background: var(--accent);
  color: var(--accent-foreground);
  padding: 1.1rem 1.3rem;
  border-radius: 8px 8px 0 0;
  display: flex;
  align-items: center;
  gap: 0.8rem;
}
.step-number {
  font-family: var(--font-body);
  font-size: 24px;
  font-weight: 800;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  background: rgba(255, 255, 255, 0.2);
  border-radius: 6px;
  flex-shrink: 0;
}
@media (min-width: 640px) {
  .step-header {
    padding: 1.6rem 2rem;
    gap: 1.2rem;
  }
  .step-number {
    font-size: 36px;
    width: 60px;
    height: 60px;
  }
}
.step-title h2 {
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: 800;
  margin-bottom: 0.3rem;
}
.step-title p {
  font-size: 12px;
  opacity: 0.9;
}
.step-content {
  background: var(--bg2);
  border: 0.5px solid var(--border);
  border-radius: 0 0 8px 8px;
  padding: 1.4rem;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.6rem;
  align-items: start;
}
@media (min-width: 760px) {
  .step-title h2 {
    font-size: 24px;
  }
  .step-title p {
    font-size: 13px;
  }
  /* Asymmetric columns: text stays readable, code gets remaining space.
     Sticky left + align-items:start stops a tall code column from
     leaving a large empty gap beside the shorter text column. */
  .step-content {
    grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.15fr);
    padding: 2.2rem;
    gap: 2rem;
  }
  .step-content > .step-page:first-child {
    position: sticky;
    top: calc(var(--nav-h, 96px) + 5.5rem);
    align-self: start;
  }
}
/* min-width: 0 overrides the grid item's default content-based minimum
   size — without it, a wide <pre class="code-block"> (long unwrapped
   code lines) forces its whole column past its 1fr share and the
   column overflows the card instead of the code block scrolling. */
.step-page {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.step-page h3 {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 700;
  color: var(--accent2);
  margin-bottom: 1.1rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.step-text {
  font-size: 14px;
  color: var(--muted);
  line-height: 1.75;
  margin-bottom: 1.2rem;
}
.step-highlight {
  background: rgba(45, 106, 79, 0.1);
  border-left: 3px solid var(--accent);
  padding: 1rem 1.1rem;
  border-radius: 8px;
  margin: 1.2rem 0;
  font-size: 14px;
  color: var(--text);
  line-height: 1.7;
}
.step-bullet {
  display: flex;
  gap: 0.7rem;
  margin-bottom: 0.8rem;
  font-size: 14px;
  color: var(--muted);
  line-height: 1.6;
}
.step-bullet::before {
  content: "";
  width: 0.45rem;
  height: 0.45rem;
  margin-top: 0.4em;
  background: var(--accent);
  transform: rotate(45deg);
  flex-shrink: 0;
}
.teaser {
  background: rgba(45, 106, 79, 0.15);
  border: 0.5px solid rgba(45, 106, 79, 0.3);
  border-radius: 8px;
  padding: 1.2rem;
  margin-top: 1.5rem;
  font-size: 13px;
  color: var(--accent2);
  font-weight: 600;
  line-height: 1.6;
}
.checklist {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}
@media (min-width: 480px) {
  .checklist {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.6rem 1.2rem;
  }
}
/* Checklist items are real <label><input type="checkbox">…</label> pairs now
   (previously plain <div>s with a decorative ::before box — looked like a
   checkbox but did nothing when clicked). The native input is visually
   replaced but kept in the a11y tree, so it's tabbable and readable by
   screen readers as an actual checkbox, not a fake one drawn in CSS. */
.checklist-item {
  display: flex;
  gap: 0.7rem;
  font-size: 13px;
  color: var(--muted);
  align-items: flex-start;
  cursor: pointer;
  user-select: none;
}
.checklist-check {
  appearance: none;
  -webkit-appearance: none;
  width: 0.95rem;
  height: 0.95rem;
  margin: 0.1em 0 0;
  border: 1.5px solid var(--accent);
  border-radius: 3px;
  flex-shrink: 0;
  box-sizing: border-box;
  position: relative;
  cursor: pointer;
  transition:
    background 0.15s,
    border-color 0.15s;
}
.checklist-item:hover .checklist-check {
  border-color: var(--accent2);
}
.checklist-check:checked {
  background: var(--accent);
  border-color: var(--accent);
}
.checklist-check:checked::after {
  content: "";
  position: absolute;
  left: 2px;
  top: -1px;
  width: 5px;
  height: 9px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.checklist-check:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.checklist-check:checked ~ span {
  color: var(--text);
  text-decoration: line-through;
  text-decoration-color: var(--muted);
  opacity: 0.75;
}

/* ---------------------------------------------------------------- */
/* Code block + "test in IDE" button                                */
/* ---------------------------------------------------------------- */
.code-block {
  background: #0b0a14;
  border: 0.5px solid rgba(45, 106, 79, 0.35);
  border-radius: 8px;
  padding: 2.6rem 0.9rem 0.9rem;
  margin: 1.1rem 0 0.9rem;
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 11.5px;
  line-height: 1.6;
  color: #d7d2f7;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  white-space: pre;
  max-width: 100%;
  box-sizing: border-box;
}
.ide-test-btn {
  display: flex;
  width: 100%;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  background: transparent;
  border: 1px solid var(--accent);
  color: var(--accent2);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 13px;
  padding: 0.75rem 1.1rem;
  border-radius: 4px;
  cursor: pointer;
  transition: background 0.15s;
  margin-bottom: 0.5rem;
}
.ide-test-btn:hover {
  background: rgba(45, 106, 79, 0.14);
}
@media (min-width: 640px) {
  .code-block {
    padding: 2.9rem 1.2rem 1.2rem;
    font-size: 12.5px;
    line-height: 1.65;
  }
  .ide-test-btn {
    display: inline-flex;
    width: auto;
    justify-content: flex-start;
  }
}

/* ---------------------------------------------------------------- */
/* "Only on desktop" inline notice for the IDE test button          */
/* ---------------------------------------------------------------- */
.ide-mobile-notice {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.6rem;
  background: rgba(255, 159, 67, 0.12);
  border-left: 3px solid #ff9f43;
  border-radius: 8px;
  padding: 0.85rem 1rem;
  margin: 0.6rem 0 1.2rem;
  font-size: 13px;
  line-height: 1.6;
  color: var(--text);
}
.ide-mobile-notice[hidden] {
  display: none;
}
.ide-force-btn {
  align-self: stretch;
  background: transparent;
  border: 1px solid #ff9f43;
  color: #ff9f43;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 12.5px;
  padding: 0.55rem 0.9rem;
  border-radius: 4px;
  cursor: pointer;
  transition: background 0.15s;
}
.ide-force-btn:hover {
  background: rgba(255, 159, 67, 0.16);
}
@media (min-width: 640px) {
  .ide-force-btn {
    align-self: flex-start;
  }
}

/* ---------------------------------------------------------------- */
/* Section eyebrow/title (site-wide convention)                     */
/* ---------------------------------------------------------------- */
.guide-section-head {
  margin-bottom: 0.9rem;
}

/* This h2 was relying on the sitewide .sec-title rule's font-weight:800,
   which only exists as a static font file added to dodge a Safari
   interpolation bug (see fonts.css). If that weight doesn't resolve, the
   heading renders thin and reads smaller than the bold body text below
   it — bad hierarchy. Pinning weight 700 keeps it inside the variable
   font's guaranteed range, and the explicit size makes it reliably
   larger than any of the card text instead of depending on a vw clamp
   that can land close to body size at in-between viewports. */
#parts .sec-title {
  font-size: clamp(26px, 3.4vw, 34px);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--accent2);
}

/* ---------------------------------------------------------------- */
/* Registration gate (client-side only — see note in the script)    */
/* ---------------------------------------------------------------- */
/* #gatedContent sits inside the same 980px .guide-content column as
   every other section (intro, parts, step-1) and takes no padding
   of its own, so whatever markup lands here via fetch() renders at
   exactly the same width as the content that was already on the
   page — it can't drift even if the fetched fragment brings stray
   width/margin rules with it, because those are overridden below. */
#gatedContent {
  width: 100%;
  box-sizing: border-box;
}
#gatedContent > * {
  max-width: 100% !important;
  margin-left: 0 !important;
  margin-right: 0 !important;
}
.gated-content.is-locked {
  display: none !important;
}

.gate-teaser {
  display: none;
  background: var(--bg2);
  border: 0.5px solid rgba(45, 106, 79, 0.3);
  border-radius: 8px;
  padding: var(--card-pad);
  text-align: center;
  margin-bottom: 3rem;
}
.gate-teaser.is-visible {
  display: block;
}
.gate-teaser h3 {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 800;
  margin-bottom: 0.6rem;
  color: var(--accent2);
}
.gate-teaser p {
  font-size: 13.5px;
  color: var(--muted);
  line-height: 1.7;
  max-width: 480px;
  margin: 0 auto 1.4rem;
}
.gate-form {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  max-width: 320px;
  margin: 0 auto;
}
.gate-form input {
  font-family: var(--font-body);
  font-size: 14px;
  padding: 0.7rem 0.9rem;
  border-radius: 4px;
  border: 0.5px solid var(--border);
  background: var(--bg);
  color: var(--text);
}
.gate-form button {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 14px;
  padding: 0.75rem 1.1rem;
  border-radius: 4px;
  border: none;
  cursor: pointer;
  color: var(--accent-foreground);
  background: var(--accent);
}
.gate-error {
  display: none;
  font-size: 12.5px;
  color: #ff6b6b;
  margin-top: 0.8rem;
}
.gate-error.is-visible {
  display: block;
}
.gate-methods {
  display: flex;
  gap: 0.6rem;
  justify-content: center;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}
.gate-method-btn {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 15px;
  padding: 0.8rem 1.4rem;
  border-radius: 4px;
  border: none;
  background: var(--accent);
  color: var(--accent-foreground);
  text-decoration: none;
  display: inline-block;
  cursor: pointer;
  transition: opacity 0.2s;
}
.gate-method-btn:hover {
  opacity: 0.9;
}
.gate-status {
  font-size: 13px;
  color: var(--muted);
  line-height: 1.7;
  max-width: 420px;
  margin: 0 auto;
}

/* ── Section title semantics fix ──
   .sec-title was a plain <div> sitewide (no real heading tag between the
   page's one <h1> and the <h3>s inside cards). Promoted to <h2> on this
   page; browsers give h2 a default margin that the div never had, so it's
   zeroed here to keep the existing spacing. If this gets rolled out
   sitewide, move this rule into the shared stylesheet instead. */
.sec-title {
  margin: 0;
}

.code-wrapper {
  position: relative;
}

.copy-btn {
  position: absolute;
  z-index: 1;
  top: 10px;
  right: 10px;
  /* Fixed via min-width (not just max-width) so the box doesn't reflow
     between the idle "Көшіру" and the ~35% wider "Көшірілді!" copied
     label — right-anchored + no min-width meant the button visibly
     jumped size on every tap, which read as broken/half-rendered on
     phones. Sized to fit the longest label at the mobile font-size. */
  min-width: 84px;
  max-width: calc(100% - 20px);
  box-sizing: border-box;
  padding: 6px 12px;
  background-color: var(--accent);
  color: var(--accent-foreground);
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
  font-family: var(--font-body);
  font-weight: 600;
  text-align: center;
  white-space: nowrap;
  box-shadow: none;
  transition:
    background 0.15s,
    box-shadow 0.15s;
}

.copy-btn:hover {
  background-color: var(--accent2);
  box-shadow: 0 4px 14px rgba(45, 106, 79, 0.15);
}

.copy-btn.copied {
  background-color: var(--accent2);
}

@media (max-width: 768px) {
  /* Previously "display: none" on mobile — that left phone/tablet users
     with no way to get the code at all except manually selecting
     unwrapped text inside a horizontally-scrolling <pre>. Shrinking the
     button instead keeps the affordance without crowding the corner.
     min-height keeps the tap target close to the 44px touch-target
     guideline even though the visual pill itself stays compact. */
  .copy-btn {
    top: 8px;
    right: 8px;
    min-width: 78px;
    min-height: 30px;
    padding: 5px 9px;
    font-size: 11px;
  }
}

/* ---------------------------------------------------------------- */
/* Keyboard focus (site-wide focus ring was easy to lose track of    */
/* inside these custom controls — quiz options, copy/IDE buttons,    */
/* gate CTA — so give every interactive element in this page its own */
/* visible :focus-visible state instead of relying on the browser    */
/* default, which several of these override via `outline:none`-ish   */
/* resets elsewhere in the site stylesheet).                         */
/* ---------------------------------------------------------------- */
.quiz-opt:focus-visible,
.copy-btn:focus-visible,
.ide-test-btn:focus-visible,
.ide-force-btn:focus-visible,
.gate-method-btn:focus-visible,
.guide-nav-link:focus-visible,
.tg-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ---------------------------------------------------------------- */
/* Step progress indicator (build-log header)                        */
/* Gives the learner a persistent sense of "how much is left" instead */
/* of the old all-or-nothing reveal, where a locked step simply didn't */
/* exist in the DOM until unlocked and nothing signalled how many more */
/* quizzes stood between them and the finish.                         */
/* ---------------------------------------------------------------- */
.step-progress {
  margin: 1.1rem 0 0.4rem;
}
.step-progress-track {
  height: 6px;
  border-radius: 999px;
  background: var(--bg3, rgba(45, 106, 79, 0.15));
  overflow: hidden;
}
.step-progress-fill {
  height: 100%;
  width: 0%;
  border-radius: 999px;
  background: var(--accent);
  transition: width 0.35s ease;
}
.step-progress-label {
  margin-top: 0.5rem;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--muted);
  min-height: 1.2em;
}

/* ---------------------------------------------------------------- */
/* "Next step" locked preview                                        */
/* Replaces the previous behaviour where every not-yet-reached step   */
/* was `hidden` outright (i.e. invisible, no trace it existed). This   */
/* small locked card previews the *next* step's title so the learner  */
/* can see there's a concrete, named destination — a well-established */
/* progress-disclosure pattern (course platforms, game level-select   */
/* screens) that reduces drop-off versus a hard dead-end after a quiz. */
/* ---------------------------------------------------------------- */
.step-locked-preview {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  background: var(--bg2);
  border: 0.5px dashed var(--border);
  border-radius: 8px;
  padding: 1.1rem 1.3rem;
  margin: 0 0 2rem;
  color: var(--muted);
}
/* Author CSS always wins over the UA stylesheet's [hidden]{display:none},
   regardless of specificity — so setting el.hidden = true in JS was not
   enough to actually hide this card while `display: flex` above still
   matched it. This is what caused a step to still show its "gated" lock
   preview banner even after its quiz was passed and the step opened. */
.step-locked-preview[hidden] {
  display: none;
}
.step-locked-preview .lock-icon {
  flex-shrink: 0;
  width: 34px;
  height: 34px;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(45, 106, 79, 0.12);
  color: var(--accent2);
}
.step-locked-preview .lock-text-num {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--accent2);
}
.step-locked-preview .lock-text-title {
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
  margin-top: 0.15rem;
}
.step-locked-preview .lock-text-sub {
  font-size: 12.5px;
  margin-top: 0.15rem;
}

/* ---------------------------------------------------------------- */
/* Quiz block                                                        */
/* Moved here from an inline <style> tag at the bottom of             */
/* gated-fragment.html. That fragment is fetched dynamically and      */
/* injected via innerHTML — shipping CSS inside it meant it was        */
/* invisible to caching/linting like the rest of the site's styles     */
/* and only existed in the DOM after the fetch resolved (a flash of     */
/* unstyled quiz buttons on slow connections). Belongs in the           */
/* stylesheet with everything else this page uses.                     */
/* ---------------------------------------------------------------- */
.quiz-block {
  margin: 1.5rem 0 0;
  background: var(--bg2);
  border: 0.5px solid var(--border);
  border-radius: 0 0 8px 8px;
  border-top: none;
  padding: 1.4rem 1.3rem 1.6rem;
  box-shadow: none;
}
.quiz-q {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 700;
  color: var(--accent2);
  margin-bottom: 1rem;
  line-height: 1.45;
}
.quiz-options {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}
.quiz-opt {
  font-family: var(--font-body);
  font-size: 13.5px;
  text-align: left;
  padding: 0.7rem 1rem;
  border-radius: 4px;
  border: 0.5px solid var(--border);
  background: var(--bg);
  color: var(--text);
  cursor: pointer;
  transition:
    background 0.15s,
    border-color 0.15s;
  box-shadow: none;
}
.quiz-opt:hover:not(:disabled) {
  border-color: var(--accent);
  background: rgba(45, 106, 79, 0.08);
}
.quiz-opt.correct {
  background: rgba(45, 106, 79, 0.18);
  border-color: var(--accent);
  color: var(--accent2);
  font-weight: 600;
}
/* #ff6b6b swapped for a slightly deeper red (still same hue) — the
   original had ~2.9:1 contrast against .bg2 for 13.5px regular text,
   under the WCAG AA 4.5:1 text minimum. #e5484d clears it while
   staying visually "the same red" as the rest of the site's error
   color used elsewhere (gate-error, ide-mobile-notice). */
.quiz-opt.wrong {
  background: rgba(229, 72, 77, 0.12);
  border-color: #e5484d;
  color: #c53438;
}
.quiz-opt:disabled {
  cursor: default;
  opacity: 0.85;
}
.quiz-feedback {
  margin-top: 0.9rem;
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.5;
}
.quiz-feedback.ok {
  color: var(--accent2);
}
.quiz-feedback.err {
  color: #c53438;
}
.step-locked {
  display: none !important;
}
.final-cta {
  margin: 2.5rem 0 1rem;
  padding: 0;
}
.final-cta-inner {
  background: var(--accent);
  border-radius: 8px;
  padding: var(--card-pad, clamp(1.5rem, 4.5vw, 3rem));
  text-align: center;
  color: var(--accent-foreground);
}
.celebrate-badge {
  width: 56px;
  height: 56px;
  margin: 0 auto 1rem;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.2);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 28px;
  font-weight: 800;
  animation: popIn 0.45s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}
@media (prefers-reduced-motion: reduce) {
  .celebrate-badge {
    animation: none;
  }
}
@keyframes popIn {
  from {
    transform: scale(0);
    opacity: 0;
  }
  to {
    transform: scale(1);
    opacity: 1;
  }
}
.final-cta-inner h2 {
  font-family: var(--font-display);
  font-size: clamp(22px, 4vw, 28px);
  font-weight: 800;
  margin: 0 0 0.9rem;
}
.final-cta-inner p {
  font-size: 14.5px;
  line-height: 1.75;
  opacity: 0.92;
  max-width: 36rem;
  margin: 0 auto 1.4rem;
}
.learned-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
  justify-content: center;
  margin-bottom: 1.6rem;
}
.learned-tags span {
  font-size: 12px;
  font-weight: 600;
  padding: 0.35rem 0.75rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.16);
}
.tg-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  background: rgba(255, 255, 255, 0.16);
  color: var(--accent-foreground);
  text-decoration: none;
  font-weight: 700;
  font-size: 14px;
  padding: 0.8rem 1.5rem;
  border-radius: 999px;
  transition: background 0.2s;
}
.tg-btn:hover {
  background: rgba(255, 255, 255, 0.28);
}

/* ---------------------------------------------------------------- */
/* "Buy a kit" CTA (moved from the old catalog page)                  */
/* ---------------------------------------------------------------- */
/* Prefixed with .guide-content > so it beats the
   ".guide-content > section { padding: 0 }" reset above. */
.guide-content > .buy-cta {
  margin: 3rem 0 0;
  background: var(--bg2);
  border: 0.5px solid rgba(45, 106, 79, 0.3);
  border-radius: 8px;
  padding: var(--card-pad, 1.5rem);
  text-align: center;
}

.buy-cta-title {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 800;
  color: var(--accent2);
  margin-bottom: 0.6rem;
}

.buy-cta-desc {
  font-size: 13.5px;
  color: var(--muted);
  line-height: 1.7;
  max-width: 480px;
  margin: 0 auto 1.4rem;
}