/* ==========================================================================
   Responsive — progressively simplifies the grids down to a single column
   Breakpoints: 1439 / 1240 / 1024 / 860 / 640 / 420
   ========================================================================== */

/* The horizontal nav has to collapse before the header runs out of room.
   English labels are the longer set, so these thresholds are driven by /en/. */
@media (max-width: 1439px) {
  .nav__cta { display: none; }
}

@media (max-width: 1240px) {
  .nav { display: none; }
  .burger { display: flex; }
  .header__actions { margin-left: auto; }

  .bento { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .bento > *:nth-child(1) { grid-column: span 2; grid-row: auto; }
  .bento > *:nth-child(1).bento__cell { min-height: 320px; }
  .bento > *:nth-child(6) { grid-column: span 2; }
  .catalog__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .footer__top { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .footer__col:first-child { grid-column: 1 / -1; }
}

@media (max-width: 1024px) {
  :root { --header-h: 72px; --header-h-sm: 62px; }

  .hero { min-height: auto; }
  .hero__inner { grid-template-columns: minmax(0, 1fr); gap: var(--s-8); }
  .hero__copy { max-width: 100%; }

  .grid--3, .grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid--media, .grid--sidebar { grid-template-columns: minmax(0, 1fr); }
  .section-head--split { grid-template-columns: minmax(0, 1fr); align-items: start; }

  .pd { grid-template-columns: minmax(0, 1fr); }
  .pd__gallery { position: static; }

  .qc-cols { grid-template-columns: minmax(0, 1fr); }

  .pillar { grid-template-columns: minmax(0, 1fr); gap: var(--s-5); }
  .pillar__head { position: static; }

  .contact-grid { grid-template-columns: minmax(0, 1fr); }
  .contact-card { position: static; }

  .cta__inner { grid-template-columns: minmax(0, 1fr); }
  .cta__actions { justify-content: flex-start; }

  .gallery { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .gallery__item:nth-child(1), .gallery__item:nth-child(6) { grid-column: span 2; }
}

@media (max-width: 860px) {
  .capband { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .form__grid, .form__grid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* Both of these set their own fixed label column at desktop width; without
     re-collapsing them here the label eats the row and the value is squeezed
     into a few dozen pixels. */
  .specs__row,
  .cert__meta .specs__row,
  .reginfo .specs__row { grid-template-columns: minmax(0, 1fr); gap: .2rem; padding: .85rem 0; }
  .specs__row dt { font-size: var(--fs-xs); }
  /* Below this width the bar scrolls with the page, so the pinned treatment
     must not leak in — otherwise it bleeds edge-to-edge mid-page. */
  .filters { position: static; }
  .filters.is-pinned {
    margin-inline: 0;
    padding: var(--s-4);
    gap: var(--s-4);
    border-radius: var(--r-lg);
    border-color: var(--line);
    box-shadow: none;
  }
}

@media (max-width: 640px) {
  .grid--2, .grid--3, .grid--4 { grid-template-columns: minmax(0, 1fr); }
  .catalog__grid { grid-template-columns: minmax(0, 1fr); }
  .bento { grid-template-columns: minmax(0, 1fr); }
  .bento > *:nth-child(1), .bento > *:nth-child(6) { grid-column: span 1; }
  .bento > *:nth-child(1).bento__cell { min-height: 260px; }
  .capband { grid-template-columns: minmax(0, 1fr); }
  .gallery { grid-template-columns: minmax(0, 1fr); }
  .gallery__item:nth-child(1), .gallery__item:nth-child(6) { grid-column: span 1; aspect-ratio: 4/3; }
  .form__grid, .form__grid--3 { grid-template-columns: minmax(0, 1fr); }
  .pd__thumbs { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .footer__top { grid-template-columns: minmax(0, 1fr); gap: var(--s-6); }
  .footer__bottom { flex-direction: column; align-items: flex-start; }
  .hero__actions .btn, .cta__actions .btn { flex: 1 1 auto; }
  .tl-item { padding-left: 2.4rem; }
  .timeline::before { left: 8px; }
  .tl-item::before { width: 14px; height: 14px; left: 2px; }
  .lightbox__nav--prev { left: .5rem; }
  .lightbox__nav--next { right: .5rem; }

  /* dock collapses behind a single toggle so it never covers content */
  .dock__toggle { display: grid; }
  .dock__items {
    position: absolute; bottom: calc(100% + .65rem); right: 0;
    opacity: 0; visibility: hidden; transform: translateY(10px) scale(.94);
    transform-origin: bottom right;
    transition: opacity var(--t-base) var(--ease), transform var(--t-base) var(--ease), visibility var(--t-base);
  }
  .dock.is-open .dock__items { opacity: 1; visibility: visible; transform: none; }
  .dock.is-open .dock__toggle { background: var(--g-700); }
  .dock.is-open .dock__toggle .icon-open { display: none; }
  .dock__toggle .icon-close { display: none; }
  .dock.is-open .dock__toggle .icon-close { display: block; }
  .dock__label { display: none; }
  .dock__btn { width: 46px; height: 46px; }
  .dock__btn svg { width: 20px; height: 20px; }
}

@media (max-width: 640px) {
  .header__actions { gap: var(--s-2); }
}

/* The language label is the first thing to go. It was dropped only below
   420px, but an iPhone Pro Max is 430 and a Plus is 428: those sat just above
   the breakpoint, got the full-width pill, and the menu button was pushed off
   the right edge - clipped rather than scrollable, because base.css sets
   overflow-x: clip. The globe icon alone still reads as a language control. */
@media (max-width: 600px) {
  .lang-toggle span { display: none; }
  .lang-toggle { padding: .5rem; }
}

@media (max-width: 420px) {
  .logo__text { display: none; }
  .filters__label { width: 100%; }
  .btn { padding: .85rem 1.35rem; }
}

/* ---- print -------------------------------------------------------------- */
@media print {
  .header, .dock, .drawer, .page-veil, .hero__cue, .filters, .cta { display: none !important; }
  .page { padding-top: 0; }
  body { color: #000; }
  a { color: #000; text-decoration: underline; }
  .section { padding-block: 1.5rem; break-inside: avoid; }
  [data-reveal], [data-stagger] > * { opacity: 1 !important; transform: none !important; }
}

/* The serpentine needs real width: four columns share the stage with a 300px
   detail panel, so at 1024 each step title was down to ~138px and wrapping to
   three lines. Below this it becomes a plain vertical run instead, which covers
   iPad landscape and the smaller laptops. */
@media (max-width: 1180px) {
  .flow { grid-template-columns: minmax(0, 1fr); }
  .flow__svg { display: none; }
  .flow__stage { gap: clamp(1.25rem, 1rem + 1.6vw, 2rem); }
  .flow__lane { display: grid; gap: clamp(1.25rem, 1rem + 1.6vw, 2rem); }
  .flow__row,
  .flow__lane--bottom .flow__row { grid-template-columns: minmax(0, 1fr); }
  /* The return lane is reversed in the DOM so it reads right-to-left along the
     line. Stacked vertically that would read 07, 06, 05 — flip it back. */
  .flow__row--end {
    display: flex;
    flex-direction: column-reverse;
    gap: clamp(1.25rem, 1rem + 1.6vw, 2rem);
  }
  .flow__row--end > :first-child { grid-column-start: auto; }
  .flow__lane--top .flow__step,
  .flow__lane--bottom .flow__step {
    padding: 0 0 0 1.5rem;
    border-left: 2px solid var(--g-100);
    opacity: 1;
  }
  .flow__step .flow__dot,
  .flow__lane--bottom .flow__step .flow__dot { left: -7px; top: .35rem; bottom: auto; transform: scale(1); }
  .flow__detail { position: static; opacity: 1; transform: none; }

  /* One continuous line down the whole column, rather than a border per step */
  .flow__lane--top .flow__step,
  .flow__lane--bottom .flow__step { border-left: 0; }
  .flow__stage { position: relative; }
  .flow__stage::before {
    content: ""; position: absolute; left: 0; top: .6rem; bottom: .6rem;
    width: 2px; background: var(--g-100); border-radius: 2px;
  }
  /* Full height, scaled from the top — scaleY is a compositor property, where
     animating `height` relaid out the column on every scroll frame. */
  .flow__stage::after {
    content: ""; position: absolute; left: 0; top: .6rem; bottom: .6rem;
    width: 2px; background: var(--g-500); border-radius: 2px;
    transform: scaleY(var(--flow-p, 0));
    transform-origin: top;
    transition: transform .25s linear;
  }
  .flow__step { opacity: .4; transition: opacity .6s var(--ease); }
  .flow__step.is-on { opacity: 1; }
  /* the detail panel is redundant when every step shows its own title */
  .flow__detail { display: none; }
}

/* ---- tap targets -------------------------------------------------------- */
@media (max-width: 640px) {
  /* Footer links were only as tall as their text (19px). Give every one a
     proper touch area rather than relying on precise aim. */
  .footer__col ul { gap: .1rem; }
  .footer__col a {
    display: inline-flex; align-items: center;
    min-height: 44px;
  }
  .footer__col li { line-height: 1.3; }

  /* Small buttons sat at ~37px and card "details" links at 25px; lift both to
     a usable target on touch. */
  .btn--sm { min-height: 44px; }
  .chip { min-height: 40px; }
  .card__foot .link-arrow,
  .catalog__meta .link-arrow { min-height: 44px; }

  /* the closing call to action reads better in two lines than three here */
  .cta h2 { font-size: clamp(1.35rem, 1.05rem + 1.6vw, 1.85rem); }
}

/* ---- imagery on phones -------------------------------------------------- */
@media (max-width: 640px) {
  /* Filmstrip frames are sized by height, so a landscape shot was coming out
     wider than the screen. Shorter frames bring every width inside the viewport
     while keeping each photo uncropped. */
  .strip__item { height: clamp(190px, 26vh, 230px); }

  /* Collage cards were stuck at their 240px floor, leaving a wide dead gutter.
     Let them use most of the screen instead. */
  .collage__track { grid-auto-columns: min(80vw, 380px); }
  .collage__track > .collage__item:nth-child(even) { margin-top: 1rem; }

  /* Certificate scans read better one at a time at this width */
  .cert__scans { grid-template-columns: minmax(0, 1fr); }
  .cert__scan img { max-height: 62vh; width: auto; margin-inline: auto; }
}
