/* site.css — cross-device fixes that Tailwind utilities in the markup cannot
 * express, linked into every page by build.js.
 *
 * WHY THIS EXISTS
 * The layouts were built desktop-first with `grid-cols-12 gap-12`. On a phone
 * that is fatal arithmetic: twelve columns with eleven 48px gaps needs 528px of
 * gap alone, inside a ~316px container. The tracks collapsed to 0px and the
 * gaps pushed the page 188px wider than the screen, so every page scrolled
 * sideways on mobile. Measured on a 412px viewport before the fix.
 *
 * The rules below are scoped to small screens so the desktop layout is
 * untouched.
 */

/* --- 1. stacked layout on phones ---------------------------------------- */

@media (max-width: 767px) {
  /* Any multi-column grid becomes a single column. Children are forced to span
     the full row, because `col-span-*` in a one-column grid would otherwise
     create implicit columns and reintroduce the overflow. */
  [class*="grid-cols-"] {
    grid-template-columns: minmax(0, 1fr) !important;
  }

  [class*="grid-cols-"] > * {
    grid-column: 1 / -1 !important;
    min-width: 0;
  }

  /* Gaps sized for a 1440px canvas are enormous on a phone. */
  [class*="gap-12"],
  [class*="gap-16"],
  [class*="gap-10"] {
    gap: 2rem !important;
  }

  /* Flex rows must be allowed to wrap and to shrink. */
  [class*="flex"] > * {
    min-width: 0;
  }

  /* The footer's social row is `flex gap-5` with no flex-wrap: five links on
     one unbreakable line, 393px inside a 348px content box. That single row was
     the last 13px of horizontal overflow on every page — a non-wrapping flex
     container cannot shrink below its min-content, so min-width:0 above does
     not help it. Adding a fifth link (Upwork) is what tipped it over. */
  nav [class*="flex"],
  footer [class*="flex"] {
    flex-wrap: wrap;
  }
}

/* --- 2. nothing may exceed the viewport --------------------------------- */

img,
svg,
video,
canvas,
iframe {
  max-width: 100%;
  height: auto;
}

/* Long unbroken strings — URLs, slugs — must not force a scrollbar. Headings
   are excluded: breaking a display word mid-letter looks worse than the
   overflow it prevents, and the rule below keeps them small enough to fit. */
@media (max-width: 767px) {
  p, li, blockquote, address {
    overflow-wrap: break-word;
  }
}

/* --- display type must fit the screen ------------------------------------
 *
 * The hero sizes are set for a 1440px canvas: text-7xl is 72px, and at that
 * size the single word "INSIGHTS" measures 320px inside a 316px column. Four
 * pixels of overflow was enough to drop a lone "S" onto its own line.
 *
 * Scaled fluidly instead of by fixed breakpoint, so it holds on a 360px phone
 * as well as a 412px one. Line height tightens to match.
 */
@media (max-width: 767px) {
  .text-7xl,
  .text-8xl,
  .text-9xl {
    font-size: clamp(2.5rem, 14vw, 4.5rem) !important;
    line-height: 0.95 !important;
  }

  .text-5xl,
  .text-6xl {
    font-size: clamp(2rem, 10vw, 3.25rem) !important;
    line-height: 1 !important;
  }
}

/* --- 3. touch targets ---------------------------------------------------- */

@media (max-width: 767px) {
  /* WCAG 2.5.8 asks for 24px minimum; 44px is the comfortable target.
     Centred with flex rather than `line-height: 44px`, because Tailwind's own
     `.text-sm { line-height: 1.25rem }` outranks a `nav a` selector — the box
     grew to 44px while the text stayed pinned to its top, which is what made
     Contact sit higher than the hamburger. */
  nav a,
  footer a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
}

/* --- 4. mobile navigation ----------------------------------------------- */
/* The desktop nav is `hidden md:flex`, which left phones with no menu at all —
   only the logo and Contact were reachable. The markup for the toggle lives in
   _partials/header.html; this is its presentation. */

.nav-toggle {
  display: none;
}

@media (max-width: 767px) {
  /* Bar layout: logo hard left, then Contact and the toggle together on the
     right. The bar is `justify-between`, so with three visible children the
     middle one floated to the centre and the row read as misaligned. Giving the
     logo `margin-right:auto` collapses that gap and groups the other two. */
  nav > div > a:first-child {
    margin-right: auto;
  }

  nav > div > a[data-nav="contact"] {
    order: 8;
  }

  nav > div {
    gap: 0.75rem;
  }

  .nav-toggle {
    /* Last in the visual order, hard against the right edge. */
    order: 9;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    background: none;
    border: 0;
    cursor: pointer;
    color: #2f2f2f;
  }

  .nav-panel {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: #f6f6f6;
    border-top: 1px solid #e8e8e8;
    padding: 0.5rem 2rem 2rem;
    max-height: calc(100vh - 100%);
    overflow-y: auto;
  }

  .nav-panel[data-open="true"] {
    display: block;
  }

  /* Inside the panel every link is a full-width row, including the ones that
     are hover-revealed dropdowns on desktop. */
  .nav-panel a {
    display: block;
    padding: 0.25rem 0;
    line-height: 1.6;
    min-height: 44px;
  }

  /* Neutralise the desktop dropdown positioning so the sub-links simply stack. */
  .nav-panel .group > div {
    position: static !important;
    transform: none !important;
    opacity: 1 !important;
    visibility: visible !important;
    width: auto !important;
    margin: 0 !important;
    box-shadow: none !important;
    border: 0 !important;
    background: transparent !important;
    padding-left: 1rem;
  }

  .nav-panel .material-symbols-outlined {
    display: none;
  }
}

/* Desktop keeps its own nav; the panel must never appear there. */
@media (min-width: 768px) {
  .nav-panel {
    display: contents;
  }
}
