/* ================================================================
   RESPONSIVE.CSS — all responsive / mobile-only rules
   Loaded LAST, so it wins ties against main.css at equal
   specificity. Breakpoints: 1280 → 1024 → 768 → 600 → 480

   The hero stage is shown at every width; it only changes size. chatbot.js
   decides where the robot lives by measuring whether #stageSlot is actually
   laid out, so hiding the stage in CSS is all it takes to keep the robot
   docked at a given breakpoint — no JS change needed.
   ================================================================ */

/* ============ ≤1280px ============ */
@media (max-width: 1280px) {
  .how-grid   { gap: var(--sp-12); }
  .faq-grid,
  .start-grid { gap: var(--sp-12); }
  .svc        { padding: var(--sp-6) var(--sp-5); }
}

/* ============ ≤1024px ============ */
@media (max-width: 1024px) {
  /* ---- Nav: the desktop links stay visible down to 769px, where the
     full row only just fits. Tighter gaps, a slightly smaller logo, and
     no wrapping inside a link ("How we work" was breaking in two). ---- */
  .nav-links { gap: var(--sp-5); }
  .nav-links a { white-space: nowrap; }
  .nav-logo-img { height: 38px; }
  .nav-links a.nav-cta { padding: 11px 20px; }

  /* ---- Hero: one column, no stage ---- */
  .hero { padding-top: calc(88px + var(--sp-10)); }
  /* One column, and the stage moves UP between the buttons and the trust
     row, so the robot is already in view on a phone instead of sitting a
     screen below the fold. `display: contents` promotes the copy's own
     children to grid items so they can be ordered around the stage; the
     wrapper carries no styling of its own at this width. Row gap goes to
     0 because each of those children brings its own margins. */
  .hero-inner { grid-template-columns: 1fr; min-height: 0; gap: 0; }
  .hero-copy { display: contents; }
  .hero-copy > .display    { order: 1; }
  .hero-copy > .hero-sub   { order: 2; }
  .hero-copy > .hero-buttons { order: 3; }
  .hero-stage              { order: 4; }
  .hero-copy > .hero-trust { order: 5; }
  .hero .display { font-size: clamp(2.75rem, 8.4vw, 5rem); max-width: 14ch; }
  /* The stage is NOT hidden here any more — the robot stands in the hero at
     every width, just smaller. It follows .hero-copy in the DOM, so on one
     column it lands under the CTAs and the offer still owns the fold. */
  .hero-stage {
    --stage-robot: clamp(200px, 54vw, 300px);
    --plinth-y: 48px;
    min-height: clamp(290px, 74vw, 400px);
    margin-top: var(--sp-8);
  }

  /* ---- Section heads stack ---- */
  .section-head { grid-template-columns: 1fr; gap: var(--sp-5); }

  /* ---- Proof bar: stats full width, platforms beneath ---- */
  .proof-inner { grid-template-columns: 1fr; }
  .proof-platforms {
    padding: var(--sp-6) 0;
    border-top: 1px solid var(--rule);
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-start;
    gap: var(--sp-3) var(--sp-6);
  }
  .proof .stat-cell:last-child { border-right: 0; }
  .proof-platforms-list { display: flex; flex-wrap: wrap; }

  /* ---- Work ---- */
  .case-grid { grid-template-columns: 1fr; }
  .case--feature { grid-row: auto; }
  .case--feature .case-media { min-height: 300px; }

  /* ---- Services ---- */
  .svc-grid { grid-template-columns: repeat(2, 1fr); }

  /* ---- How we work ---- */
  .how-grid { grid-template-columns: 1fr; }
  .how-visual { max-width: 640px; }
  .how-facts { grid-template-columns: repeat(2, 1fr); }
  .how-facts > div:nth-child(2) { border-right: 0; }
  .how-facts > div:nth-child(n+3) { border-top: 1px solid var(--rule); }
  .how-facts > div:nth-child(3) { padding-left: 0; }

  /* ---- Stories / FAQ / Start ---- */
  .stories-grid { grid-template-columns: repeat(2, 1fr); }
  .stories-grid .story:last-child { grid-column: 1 / -1; }
  .faq-grid   { grid-template-columns: 1fr; }
  .faq-intro  { position: static; }
  .start-grid { grid-template-columns: 1fr; }

  .footer-top { grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: var(--sp-8); }
}

/* ============ ≤768px ============ */
@media (max-width: 768px) {
  /* ---- Hero: robot beside the headline ----
     The headline only uses the left of its line box on a phone, so the
     robot stands in that empty right-hand strip, level with it. Below the
     robot the stage reserves a slot for its label. The copy's children
     are already grid items here (display: contents in the ≤1024 block),
     so this is placement only. */
  .hero-inner {
    grid-template-columns: minmax(0, 1fr) minmax(96px, 38%);
    column-gap: var(--sp-4);
  }
  .hero-copy > .display      { grid-column: 1; grid-row: 1; }
  .hero-stage                { grid-column: 2; grid-row: 1; }
  .hero-copy > .hero-sub     { grid-column: 1 / -1; grid-row: 2; }
  .hero-copy > .hero-buttons { grid-column: 1 / -1; grid-row: 3; }
  .hero-copy > .hero-trust   { grid-column: 1 / -1; grid-row: 4; }

  /* "eCommerce" is the binding word: it renders at ~5.7x the font size,
     and at 320px the text column is ~160px. At 8.5vw it touched the robot
     column at 320 and 360 — measured, not guessed. */
  .hero .display { font-size: clamp(1.6rem, 8.1vw, 2.75rem); max-width: none; }

  /* ---- Hero height ----
     The spacing below was inherited from desktop and made the hero 806px
     on a 740px screen, cutting the trust lines off. These trims take ~83px
     out of the block without touching the type sizes. */
  .hero { padding-top: calc(88px + var(--sp-4)); }
  .hero-sub { line-height: 1.5; }
  .hero-buttons { margin-top: var(--sp-5); }
  .hero-buttons .btn { padding-top: 13px; padding-bottom: 13px; }
  .hero-trust {
    margin-top: var(--sp-6);
    padding-top: var(--sp-4);
    gap: var(--sp-2) var(--sp-8);
  }

  /* Width is what limits the robot, since .stage-slot is a square. Two
     things buy it: a wider column, and reaching into the right gutter —
     empty space that costs the headline nothing, and still leaves the
     page margin. 39vw tracks the resulting box at every phone width.
     min-height reserves the label slot under the robot, so a line
     appearing never shifts the layout. */
  .hero-stage {
    --stage-robot: clamp(120px, 39vw, 200px);
    /* The slot below the robot must hold the longest speech card, which
       wraps to two lines (~58px) plus its 12px gap — not just the chip.
       Both values are derived from --stage-robot so the gap stays a
       constant 72px as the robot scales: the feet sit 0.1325 of the box
       above its bottom edge, which is the term that cancels out. */
    --plinth-y: calc(78px + var(--stage-robot) * 0.1325);
    min-height: calc(var(--stage-robot) + 94px);
    margin-right: calc(-1 * var(--sp-5));
    margin-top: 0;
  }
  /* The tick ring flares 8% past the plinth, which in this column would
     push it past the screen edge. */
  .plinth-ticks { inset: -14% 0; }

  /* ---- Navigation ---- */
  .nav-links { display: none; }
  .nav-links.mobile-open {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    position: fixed;
    /* Starts at the bottom edge of the nav and fills the rest of the
       viewport. The nav shrinks to 68px once scrolled, hence the second
       rule below. Requires .nav to have no backdrop-filter — see main.css. */
    top: 88px;
    right: 0;
    bottom: 0;
    left: 0;
    background: var(--paper);
    padding: var(--sp-8) var(--sp-8) var(--sp-16);
    gap: 0;
    overflow-y: auto;
  }
  .nav-links.mobile-open a {
    font-family: var(--font-display);
    font-size: 1.5rem;
    font-weight: 700;
    letter-spacing: -0.03em;
    padding: var(--sp-5) 0;
    border-bottom: 1px solid var(--rule);
  }
  .nav-links.mobile-open a::after { display: none; }
  .nav-links.mobile-open .nav-cta {
    text-align: center;
    margin-top: var(--sp-8);
    padding: 15px var(--sp-6);
    border-bottom: 0;
    font-size: 1rem;
  }
  .nav.scrolled .nav-links.mobile-open { top: 68px; }
  .nav-toggle { display: flex; }

  /* ---- Proof ---- */
  .proof-stats { grid-template-columns: repeat(2, 1fr); }
  .proof .stat-cell { padding: var(--sp-6) var(--sp-5) var(--sp-6) 0; }
  .proof .stat-cell:nth-child(2n) { border-right: 0; }
  .proof .stat-cell:nth-child(odd) { padding-left: 0; }
  .proof .stat-cell:nth-child(even) { padding-left: var(--sp-5); }
  .proof .stat-cell:nth-child(n+3) { border-top: 1px solid var(--rule); }

  /* ---- Work: the stacked cards go vertical too ---- */
  .case:not(.case--feature) { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
  .case-body { padding: var(--sp-6); }

  /* ---- Stories / steps ---- */
  .stories-grid { grid-template-columns: 1fr; }
  .stories-grid .story:last-child { grid-column: auto; }
  .how-steps { grid-template-columns: 1fr; }

  .form-row   { grid-template-columns: 1fr; gap: 0; }
  .footer-top { grid-template-columns: 1fr 1fr; gap: var(--sp-8); }
  .footer-brand { grid-column: 1 / -1; }
}

/* ============ ≤600px ============ */
@media (max-width: 600px) {
  .container { padding: 0 var(--sp-5); }

  .svc-grid { grid-template-columns: 1fr; }
  .how-facts { grid-template-columns: 1fr; }
  .how-facts > div { border-right: 0; padding-left: 0; }
  .how-facts > div:not(:first-child) { border-top: 1px solid var(--rule); padding-left: 0; }

  /* Short label here, right-aligned under the robot: the full one is
     ~226px against a ~140px robot, which reads as a floating bar rather
     than its label. Right-aligned matches the speech card — same slot. */
  .stage-caption {
    left: auto;
    right: 0;
    transform: none;
    padding: 9px 12px;
    font-size: 11px;
    letter-spacing: .1em;
    border-color: var(--rule);
  }
  .stage-caption .cap-long  { display: none; }
  .stage-caption .cap-short { display: inline; }
  /* The chip stays compact, but the thing you tap does not: this extends
     the hit area to ~48px tall without changing how it looks. */
  .stage-caption::before {
    content: '';
    position: absolute;
    inset: -8px -12px;
  }
  .contact-form { padding: var(--sp-6); }
  .faq-item p { padding-right: 0; }
  .case-media--compact .case-chart { padding: 40px 10% 32px; }
  .case-units,
  .case-hours { padding: var(--sp-5) var(--sp-4); gap: var(--sp-4); }

  /* ---- Schematic ----
     The SVG scales with its container, so at ~380px wide the 560-unit
     viewBox renders every label at ~0.68x. Rather than let the type
     shrink to 6px, drop the secondary detail and size the remaining
     labels UP in viewBox units, which cancels the scale-down.
     14 keeps "WOOCOMMERCE" (the longest string) inside its 116-unit
     box: 11 chars at ~0.6em plus .09em tracking ≈ 106 units. */
  .schema-body { padding: var(--sp-4) var(--sp-2) var(--sp-3); }
  .schema-sub { display: none; }
  .schema-ruler { display: none; }
  .schema-label text { font-size: 14px; }
  /* Labels were set high to leave room for the sub-line; with that
     gone they need to drop back to the middle of the node. */
  .schema-label { transform: translateY(6px); }
  .schema-core-sub { font-size: 9px; }
  .schema-dim text { font-size: 11px; }

  .footer-bottom { flex-direction: column; gap: var(--sp-2); text-align: center; }
}

/* ============ short phones ============
   83px of trimming is not enough when the visible area is only ~690px, so
   short screens give up a little robot size to keep the whole hero — trust
   lines included — on screen. Taller phones keep the bigger robot. */
@media (max-width: 768px) and (max-height: 720px) {
  .hero { padding-top: calc(88px + var(--sp-3)); }
  .hero-stage { --stage-robot: clamp(110px, 33vw, 160px); }
}

/* ============ ≤480px ============ */
@media (max-width: 480px) {
  .hero-buttons { flex-direction: column; align-items: stretch; }
  .hero-buttons .btn { width: 100%; }
  .hero-trust { gap: var(--sp-3); }

  .footer-top { grid-template-columns: 1fr; }

  /* ---- Chatbot window: fullscreen ---- */
  #cb-container {
    top: 0; left: 0; bottom: 0; right: 0;
    width: 100vw; height: 100dvh;
    max-width: 100vw; max-height: 100dvh;
    border-radius: 0;
  }
}
