/* ==========================================================================
   custom.css — loaded AFTER the generated Webflow CSS. All overrides live here.
   Seeded from the patches written while the site was still in Webflow.
   Verify each block visually before trusting it.
   ========================================================================== */

/* --- Case studies: the info table stacks on mobile ----------------------------
   Summary / Services / Year sat in one row at every width, which made the page
   555px wide on a 390px screen.                                               */
@media screen and (max-width: 767px) {
  .info_container {
    flex-flow: column;
  }

  .info_block,
  .info_block.year {
    width: 100%;
    height: auto;
    padding: 1.5em var(--container-padding);
    border-right: 0;
    border-bottom: 1px solid var(--light-stone);
  }

  .info_block:last-child {
    border-bottom: 0;
  }
}

/* --- Motion tokens for CSS hovers ----------------------------------------------
   Two-state hovers are browser transitions (docs/motion.md). Shared by the menu
   and the About page.                                                          */
:root {
  /* Springs sampled into linear(), with their settling time (docs/motion.md). For hover states only: the
     browser runs them, and a hover left half-way turns back in proportion, exactly like the About wireframe. */
  --e-smooth: linear(
    0,
    0.0191,
    0.0667,
    0.1313,
    0.2048,
    0.2816,
    0.3577,
    0.4308,
    0.4991,
    0.562,
    0.6189,
    0.67,
    0.7154,
    0.7554,
    0.7905,
    0.821,
    0.8475,
    0.8704,
    0.89,
    0.9069,
    0.9213,
    0.9336,
    0.9441,
    0.9529,
    0.9605,
    0.9668,
    0.9722,
    0.9767,
    0.9805,
    0.9837,
    0.9864,
    0.9887,
    0.9905,
    0.9921,
    0.9934,
    0.9945,
    0.9955,
    0.9962,
    0.9969,
    0.9974,
    0.9978,
    0.9982,
    0.9985,
    0.9988,
    0.999,
    0.9992,
    0.9993,
    0.9994,
    1
  ); /* 0.5s, bounce 0 */
  --d-smooth: 0.8s;
}

/* --- Intro section: pin removed (temporary) ---------------------------------
   The "It's not easy…" section used to stay fixed (position: sticky inside a
   300vh trigger, plus 100vh of padding) while the page scrolled underneath. It
   read as scroll being stuck, so for now it scrolls like any other section.
   To bring the pin back, delete this block: the original rules live in the
   generated Webflow CSS (.sticky_wrap / .sticky_trigger / .sticky_track /
   .sticky_element). The image trail still works while the section is on screen
   (its ScrollTrigger uses .sticky_wrap). */
.sticky_wrap {
  padding-bottom: 0;
}

.sticky_trigger,
.sticky_track {
  height: auto;
}

.sticky_element {
  position: relative;
}

/* ==========================================================================
   Phase 3, small fixes (A1, A5, A6, A7)
   ========================================================================== */

/* --- A1: case-study text on small screens ----------------------------------
   Webflow pins the text to 4 of 12 columns with an id selector (#w-node-…), so
   !important is the only way to override it from here. On phones that column
   was about 109px wide: one word per line.                                    */
@media screen and (max-width: 991px) {
  .div-block-9 > .work_text_content {
    grid-column: 1 / span 8 !important;
  }
}

@media screen and (max-width: 767px) {
  .div-block-9 > .work_text_content {
    grid-column: 1 / -1 !important;
    padding-right: var(--container-padding);
    font-size: 1.25rem;
  }
}

/* --- A5: keyboard focus and skip link --------------------------------------
   Orange ring on the light and dark pages, ink ring on the orange menu panel. */
:where(a, button, [tabindex]):focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 3px;
}

/* <main> takes programmatic focus from the skip link; it is not a control */
#main:focus {
  outline: none;
}

.skip-link {
  position: fixed;
  top: 0.75em;
  left: 0.75em;
  z-index: 100000;
  padding: 0.75em 1em;
  background-color: var(--dark-brown);
  color: var(--color-neutral-200);
  font-family: "Office Code Pro", monospace;
  font-size: 0.875rem;
  text-transform: uppercase;
  transform: translateY(-200%);
}

.skip-link:focus-visible {
  transform: none;
}

/* Project titles sit on photos of any brightness: a soft scrim behind the header text */
.work-card-header::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: linear-gradient(rgba(0, 0, 0, 0.45), rgba(0, 0, 0, 0));
  pointer-events: none;
}

/* --- A7: tap targets and type floor ------------------------------------------
   The hit area grows with a pseudo-element, so nothing moves on the page.       */
.underlay-nav__container .brand-2,
.demo-footer__a {
  position: relative;
}

.underlay-nav__container .brand-2::after,
.demo-footer__a::after {
  content: "";
  position: absolute;
  inset: -16px -12px;
}

.underlay-nav__toggle {
  min-width: 44px;
  min-height: 44px;
}

/* Mono labels never below 12px (they were 8.5px at 1024 and 11px at 768) */
.badge_text {
  font-size: max(12px, 1em);
}

.stacking-card__top-span {
  font-size: max(12px, 1.2em);
}

/* Leftover Webflow mobile nav: same logo and a second hamburger under the real toggle.
   Hidden so it is not a tap target or a duplicate for screen readers (full removal is B3). */
.navbar > .menu-button,
.navbar > .nav-menu.w-nav-menu,
.navbar > .brand.mobile {
  display: none !important;
}

/* --- A8: hero image ---------------------------------------------------------
   Reserves its space before it loads (no layout shift). width/height attributes
   would stretch it, because the Webflow CSS never sets height: auto.            */
.div-block-3 > img {
  aspect-ratio: 1920 / 1082;
}

/* ==========================================================================
   Phase 4: performance and reduced motion
   ========================================================================== */

/* --- Work card backgrounds: right-sized images ------------------------------
   The generated CSS points every screen to the full-size photo (Tribu 776 KB,
   Footy 153 KB), also on phones. The Webflow export already has resized copies.
   The cards are not above the fold, but CSS backgrounds load at once.           */
.stacking-cards__item {
  /* the generated rule also references a Webflow CDN placeholder; the modifiers below replace it anyway */
  background-image: linear-gradient(#1c191740, #1c191700);
}

@media screen and (max-width: 991px) {
  .stacking-cards__item.is--tribu {
    background-image:
      linear-gradient(#1c191740, #1c191700),
      url("../images/Tribu-1-p-1600.webp");
  }

  .stacking-cards__item.is--footy {
    background-image:
      linear-gradient(#1c191740, #1c191700),
      url("../images/footy-02-p-1600.webp");
  }
}

@media screen and (max-width: 479px) {
  .stacking-cards__item.is--tribu {
    background-image:
      linear-gradient(#1c191740, #1c191700),
      url("../images/Tribu-1-p-1080.webp");
  }

  .stacking-cards__item.is--footy {
    background-image:
      linear-gradient(#1c191740, #1c191700),
      url("../images/footy-02-p-1080.webp");
  }
}

/* --- Reduced motion ------------------------------------------------------------
   The JS side (menu, transition, Lenis, trail, shapes, parallax, marquee, header,
   flick autoplay) reads MZ.reducedMotion. These are the CSS-only animations.   */
@media (prefers-reduced-motion: reduce) {
  .grain[data-grain-animate="true"],
  .led,
  .led::after,
  [data-css-marquee-list] {
    animation: none !important;
  }

  html {
    scroll-behavior: auto;
  }
}

/* --- Image trail: nothing to load below 992px ------------------------------
   The trail only runs on wide screens with a mouse (js/image-trail.js MIN_WIDTH).
   The 10 items are transparent but rendered, so the lazy images were downloaded
   anyway (about 330 KB) on phones and tablets.                                  */
@media screen and (max-width: 991px) {
  .trail-item {
    display: none;
  }
}

/* --- Grid lines: twelve equal columns ------------------------------------------------------
   The generated CSS gives the first line a 1px border-left, which takes room inside the flex
   row: the first column grew by 1px and the other eleven shrank, so the visible lines drifted
   up to 0.86px from the real grid (content, header, column numbers). Every line now grows from
   zero (equal shares of the row), and the first one is pulled back by its own border's width,
   so each right border ends exactly on a column edge. Colours stay with the existing rules.   */
.transition__line {
  flex: 1 1 0;
  min-width: 0;
}

.transition__line.is--first {
  margin-left: -1px;
}

/* ...and the whole layer moves right by that pixel, so each line paints the first pixel of its column, the same
   pixel as the column numbers' rules and the dark band's lines (a border-left convention) */
.transition__lines {
  translate: 1px 0;
}

/* Below 992 the Webflow CSS paints the fixed .navbar itself in paper (60px). The bar inside it carries its own
   background and hides on scroll (js/header.js); the navbar's paper stayed behind as an empty strip. */
@media screen and (max-width: 991px) {
  .navbar {
    background-color: transparent;
  }
}

/* The Osmo column wipe's panels: orange, full height, parked just above the viewport and never used since the
   transition moved to [data-transition-cols] (js/transition.js). Fixed and orange at the edge, they tinted iOS
   Safari's bars. */
.transition__panels {
  display: none;
}
