/* ===========================================================================
   COLORBLIND — overrides
   ---------------------------------------------------------------------------
   Loads LAST. Everything here is either:
     (a) a brand decision,
     (b) a fix for a bug inherited from one of the two templates, or
     (c) motion we had to hand-write because Webflow's IX2 data for it lives in
         the Bungee bundle, which we do not ship.
   =========================================================================== */

/* ---------------------------------------------------------------------------
   1. Brand tokens
   --------------------------------------------------------------------------- */

:root {
  /* Swap this one line when the real brand font arrives. */
  --cb-font-primary: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif;
  --cb-font-mono: "Chivo Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --cb-ink: #01050a;
  --cb-paper: #faf6f6;
  --cb-muted: #5b5b5b;
  --cb-hairline: #d8d2d2;

  --cb-nav-h: 80px;
  --cb-ease: cubic-bezier(0.22, 1, 0.36, 1);
}

/* Bungee's type tokens were built on Interdisplay. Rebind them to the site
   font so the project overlay matches the rest of the site. */
:root {
  --_typography---font-families--primary-font-family: var(--cb-font-primary);
  --_typography---font-families--secondary-font-family: var(--cb-font-mono);
  --colors--black: var(--cb-ink);
  --colors--text: var(--cb-muted);
  --colors--border: var(--cb-hairline);
}

body {
  font-family: var(--cb-font-primary);
  background-color: var(--cb-paper);
}

/* ---------------------------------------------------------------------------
   2. Navbar + burger
   Hand-written: the open/close and the +/✕ morph were IX2 in Bungee.
   --------------------------------------------------------------------------- */

.navbar {
  z-index: 1000;
  height: var(--cb-nav-h);
  background-color: rgba(250, 246, 246, 0.7);
}

.nav-container { overflow: visible; }

.nav-brand {
  display: flex;
  align-items: center;
  transition: opacity 0.4s var(--cb-ease);
}

/* The logo is a wordmark, not Bungee's 24px square mark. */
.nav-logo {
  width: auto;
  height: 15px;
  display: block;
}

.nav-menu-button {
  appearance: none;
  border: 0;
  background: none;
  cursor: pointer;
  width: 32px;
  height: 32px;
  padding: 0;
  position: relative;
  z-index: 5;
}
.nav-menu-button:focus-visible { outline: 2px solid var(--cb-ink); outline-offset: 6px; }

.nav-menu-open-button,
.nav-menu-close-button {
  position: absolute;
  inset: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  transition: opacity 0.3s var(--cb-ease), transform 0.4s var(--cb-ease);
}

.nav-menu-close-button { display: flex; opacity: 0; transform: rotate(-45deg); }
.nav-menu-open-button  { opacity: 1; transform: rotate(0deg); }

.cb-nav-open .nav-menu-open-button  { opacity: 0; transform: rotate(45deg); }
.cb-nav-open .nav-menu-close-button { opacity: 1; transform: rotate(0deg); }

.nav-open-button-line-v1,
.nav-open-button-line-v2,
.nav-close-button-line-v1,
.nav-close-button-line-v2 { display: block; }

/* The menu panel. Sibling of .navbar so no containing-block clipping — this
   replaces the template's hardcoded height:810px / 640px hack. */
.nav-menu-block {
  position: fixed;
  inset: 0;
  z-index: 990;
  width: 100%;
  height: 100dvh;
  background-color: rgba(250, 246, 246, 0.7);
  overflow: hidden;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.5s var(--cb-ease), visibility 0.5s var(--cb-ease);
}

.cb-nav-open .nav-menu-block {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

.nav-menu-block-inner {
  height: 100%;
  padding-top: calc(var(--cb-nav-h) + 80px);
  justify-content: flex-start;
  grid-row-gap: 0;
}

.nav-link {
  text-decoration: none;
  display: block;
  width: -moz-fit-content;
  width: fit-content;
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.5s var(--cb-ease), transform 0.5s var(--cb-ease);
}
.cb-nav-open .nav-link { opacity: 1; transform: translateY(0); }
.cb-nav-open .nav-link:nth-child(1) { transition-delay: 0.10s; }
.cb-nav-open .nav-link:nth-child(2) { transition-delay: 0.16s; }
.cb-nav-open .nav-link:nth-child(3) { transition-delay: 0.22s; }

.nav-link-number-block .paragraph-text-mono {
  color: var(--cb-muted);
  font-family: var(--cb-font-mono);
}

/* Underline sweep — was an IX2 width animation in Bungee. */
.nav-hover-line {
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.45s var(--cb-ease);
}
.nav-link:hover .nav-hover-line,
.nav-link[aria-current="page"] .nav-hover-line { transform: scaleX(1); }

/* ---------------------------------------------------------------------------
   3. Project overlay
   --------------------------------------------------------------------------- */

.project-overlay {
  position: fixed;
  inset: 0;
  z-index: 900;
  background-color: var(--cb-paper);
  opacity: 0;
  transition: opacity 0.45s var(--cb-ease);
}
.project-overlay.is-open { opacity: 1; }
.project-overlay[hidden] { display: none; }

.project-overlay-scroll {
  position: absolute;
  inset: 0;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  padding-top: var(--cb-nav-h);
  padding-bottom: 8vh;
}

/* The logo stays visible over a project and IS the way back: clicking it
   closes the project and returns to the grid (colorblind.js intercepts it, so
   the page never reloads and the scroll position is kept). This replaced the
   close X, which the client asked to remove in the second feedback round. */
.cb-overlay-open .nav-brand { opacity: 1; pointer-events: auto; cursor: pointer; }

/* The close X was removed at the client's request (Sept feedback round 2).
   A project now closes with Escape, or the browser's Back button/gesture —
   colorblind.js routes all three through the same history path, so scroll
   position is still restored exactly. Its CSS is gone with it. */

.project-overlay h1 {
  font-size: 3.4rem;
  line-height: 1.02;
  letter-spacing: -0.03em;
  font-weight: 500;
  margin: 0;
  color: var(--cb-ink);
}

.project-details { padding-bottom: 0; }
.project-details-info-wrapper { top: calc(var(--cb-nav-h) + 40px); padding-top: 40px; }
.project-details-content-block { padding-top: 40px; }

/* Both columns ship as width:100% flex items, so below ~1600px they shrink
   proportionally and the credits column collapses to an unreadable ribbon.
   Pin the text column and let the media column absorb the remainder.

   UPDATE (Sept feedback — "picture is too big"): the original fix here set
   `flex: 0 1 452px`, which replaced the text column's flex BASIS and changed
   how the shrink resolves. The media column came out 982px at 1440 against
   the template's 852px — 15% too wide, text:media 1:3.05 instead of 1:1.88.

   Bungee reaches the right answer unaided: both columns start from a 100%
   basis, the text column's own max-width:452px clamps it, and flexbox's
   min/max re-run hands the whole remainder to the media column — 452 / 72 /
   852 at 1440. So guard the collapse only, and let the template do the maths.
   min-width binds below ~776px, just above where the columns stack anyway. */
@media screen and (min-width: 768px) {
  .project-details-info-wrapper { min-width: 320px; }
  .project-details-content-block { min-width: 0; }
}

/* Bungee gives these blocks a DEFINITE height — 995px, and 300/420 at the two
   breakpoints — so whatever you put inside is cropped to a box that has nothing
   to do with the artwork. Measured across the six projects, not one of the 21
   images fitted: 8 left a band of #ece7e7, 13 were cropped by up to 403px.

   The client's rule is simple: whatever he uploads must be fully visible at
   every screen size, never cropped. So the frame takes the MEDIA's shape
   instead of imposing one — no fixed height, no aspect-ratio, no object-fit
   crop. A portrait renders portrait, a 16:9 film renders 16:9, and he does not
   have to think about aspect ratios at all when preparing a file.

   max-height keeps a very tall asset from running past the screen: it is then
   scaled down whole rather than cropped, still fully in view. */
.project-details-image-block {
  width: 100%;               /* the renderer overrides this per asset, inline */
  height: auto;
  overflow: visible;
  background-color: transparent;
  margin-inline: auto;
}
/* The frame already matches the asset's ratio exactly, so `cover` crops
   nothing — it is here only to guarantee no distortion if a file is ever
   swapped without its dimensions being updated. */
.project-details-image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ---------------------------------------------------------------------------
   4. Video
   --------------------------------------------------------------------------- */

/* Card hover preview sits exactly where the still would. */
.works-image.cb-card-video {
  object-fit: cover;
  width: 100%;
  height: 100%;
  background-color: #ece7e7;
}

/* Overlay player. Same rule as the stills: the frame is the film's own shape,
   so nothing is ever cropped and nothing is ever letterboxed — before play or
   during it. colorblind.js writes the real dimensions into --cb-play-aspect as
   soon as the metadata lands; the 16/9 default only covers that first moment,
   and preload="metadata" keeps it brief. */
.cb-media-video {
  position: relative;        /* ratio + width come from the renderer, inline */
}

.cb-media-video .cb-player {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  background-color: transparent;
}

.cb-play {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 96px;
  height: 96px;
  border: 0;
  border-radius: 50%;
  background-color: rgba(250, 246, 246, 0.92);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity 0.35s var(--cb-ease), transform 0.35s var(--cb-ease);
}
.cb-play:hover { transform: scale(1.06); }
.cb-media-video.is-playing .cb-play { opacity: 0; pointer-events: none; }

.cb-play-icon {
  width: 0;
  height: 0;
  margin-left: 5px;
  border-left: 17px solid var(--cb-ink);
  border-top: 11px solid transparent;
  border-bottom: 11px solid transparent;
}

/* ---------------------------------------------------------------------------
   5. Selected Work
   --------------------------------------------------------------------------- */

.works-link-block { text-decoration: none; }
.works-title { color: var(--cb-ink); }

/* The template hardcodes this section's height in vh (425/350/270/255 across
   breakpoints) because its demo had exactly four projects — and pairs it with
   overflow:clip, so a fifth or sixth project is silently cut off rather than
   pushing the page down. Height must follow the content, not a magic number,
   or every project added from now on disappears.
   `overflow: clip` stays: it is what lets the oversized SELECTED / WORK type
   bleed past the edges without creating a horizontal scrollbar. */
.selected-works.overflow {
  height: auto;
  padding-bottom: 12vh;
}

/* ---------------------------------------------------------------------------
   6. About — Services / Clients
   --------------------------------------------------------------------------- */

/* Clients: label on the right, list on the left — a deliberate mirror of the
   Services block above it. The column itself must align its child to the end,
   otherwise the label shrink-wraps at the column's left edge. */
.cb-grid-flip > .w-layout-vflex { align-items: flex-end; }
.cb-grid-flip .flex-left-center { justify-content: flex-end; }
.cb-grid-flip .cb-client-list { align-self: flex-start; }

/* Sized to match .about-paragraph-home at every breakpoint, so Services and
   Clients read as one system rather than two. */
.cb-client-list {
  list-style: none;
  margin: 0;
  padding: 0;
  columns: 2;
  column-gap: 3rem;
  font-size: 20px;
  line-height: 2;
  color: var(--cb-ink);
}
.cb-client-list li { break-inside: avoid; }

@media screen and (min-width: 1440px) {
  .cb-client-list { font-size: 24px; }
}

/* ---------------------------------------------------------------------------
   7. Contact — form removed, so the info column carries the layout
   --------------------------------------------------------------------------- */

.cb-contact-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  justify-items: start;
}
.cb-contact-grid .contact-right-column { width: 100%; max-width: 720px; }

/* ---------------------------------------------------------------------------
   8. 404
   --------------------------------------------------------------------------- */

.cb-404-body { max-width: 560px; margin-top: 2rem; }
.cb-404-link {
  display: inline-block;
  margin-top: 1.5rem;
  color: var(--cb-ink);
  font-size: 1.1rem;
  text-decoration: none;
  border-bottom: 1px solid var(--cb-ink);
  padding-bottom: 2px;
}

/* ---------------------------------------------------------------------------
   9. Utilities
   --------------------------------------------------------------------------- */

.cb-scroll-locked { overflow: hidden; }

/* Cube removed via config — reclaim the hero height. */
.cb-no-cube .hero-section { min-height: 60vh; }

/* ---------------------------------------------------------------------------
   9b. September client feedback
   --------------------------------------------------------------------------- */

/* The template fills its display type with a photograph showing through the
   letterforms (background-clip:text). The client asked for flat colour --
   "black or dark grey, you choose". Near-black: at 10-12vw the mid grey reads
   washed out. Three separate vendored rules carry the same recipe, so all
   three have to be answered.

   This also flattens 404's "NOT HERE", which shares .large-heading.smaller
   with BONJOUR. That is consistent rather than accidental.

   No !important needed: base.css restates the fill inside a max-width:991
   block, but media queries add no specificity and this sheet loads last. */
.large-heading,
.large-heading-right,
.text-animation-2 {
  background-image: none;
  -webkit-text-fill-color: currentColor;
  color: var(--cb-ink);
}

/* The hero band behind the cube now scrolls the logo instead of the wordmark
   set in the template's font. Sized by height so it keeps the optical weight
   the 10vw type had; flex-shrink is off because the three marquee groups must
   stay exactly equal in width or the loop seam shows. */
.cb-marquee-logo {
  display: block;
  flex: 0 0 auto;
  height: 7vw;
  width: auto;
}

/* The marquee groups were previously held open by the nowrap TEXT inside
   them: a flex item cannot shrink below its min-content, and a long
   unbreakable string has a wide min-content. Images have no such floor, so
   swapping the text for logos let each group collapse to a single logo's
   width and the seven inside it piled up on top of each other. Size the
   groups to their content explicitly. */
.animation-content-2 { flex: 0 0 auto; }

/* About hero: COLOR / BLIND are now the two halves of the real logo, cut at
   the gap between the "r" and the "b". They sit inside a mix-blend-mode:
   difference wrapper, which is why the artwork is white.
   Sized by HEIGHT, not width -- the halves are 752px and 705px wide, so
   matching widths would render them at visibly different scales. */
.absolute-text-wrapper .heading-left,
.absolute-text-wrapper .heading-right {
  display: block;
  height: 9vw;
  width: auto;
}

/* Contact rows: the client asked for the label to sit closer to its value.
   The template's gap is grid-row-gap:15px on .flex-block-3, loosened further
   by the 1.4/1.5 line-heights. Note the Phone row alone wraps both label and
   value in an extra .wrap (overflow:hidden), so the tightening has to leave
   enough room for descenders there. */
.contact-right-column .flex-block-3 {
  grid-row-gap: 2px;
  row-gap: 2px;
}
.contact-right-column .contact-text {
  color: var(--cb-muted);
  line-height: 1.3;
}
.contact-right-column .wrap { overflow: visible; }

/* The footer-cta is gone from Contact -- it repeated the details already on
   the page. Without it the section is the last thing on the page, so it has
   to carry the bottom margin itself. */
.contact { padding-bottom: 14vh; }

/* Client asked for the dot to lead the word on the right-hand Clients label.
   The dot is a real element after the text, so reverse the row rather than
   touching the markup. Services, which is not flipped, is unaffected. */
.cb-grid-flip .flex-left-center {
  flex-direction: row-reverse;
}

/* ---------------------------------------------------------------------------
   10. Responsive
   --------------------------------------------------------------------------- */

@media screen and (max-width: 991px) {
  .cb-overlay-close { right: 24px; }
  .project-overlay h1 { font-size: 2.6rem; }
  .cb-client-list { font-size: 18px; }
}

@media screen and (max-width: 767px) {
  :root { --cb-nav-h: 64px; }
  .cb-overlay-close { right: 16px; }
  .nav-menu-block-inner { padding-top: calc(var(--cb-nav-h) + 56px); }
  /* Bungee's 60px nav type runs "Selected Work" off a phone screen. */
  .nav-link { font-size: 2.25rem; }
  .project-overlay h1 { font-size: 2.1rem; }
  .project-details-info-wrapper { top: auto; padding-top: 24px; }
  /* Lucaso steps this from 28vw straight to 80vw at 479px, so between 480 and
     767 the About portrait renders far too small. */
  .about-hero-image { width: 60vw; }

  /* --- Clients on mobile (Sept feedback) -------------------------------
     Client asked for the label on the LEFT, ABOVE the list, keeping two
     columns. The grid collapses to one column here and the source order is
     list-then-label, so the label was landing underneath it.

     The previous rule here only set justify-content on a shrink-wrapped
     flex row while the parent still carried align-items:flex-end from the
     desktop mirror — so it did nothing at all. Undo that alignment, pull
     the label ahead with order, and restore the second column. */
  .cb-grid-flip > .w-layout-vflex { align-items: flex-start; }
  /* Both grid cells are .w-layout-vflex, so the label has to be picked out by
     position — ordering both would simply cancel out. */
  .cb-grid-flip > .w-layout-vflex:last-child { order: -1; }
  .cb-client-list { columns: 2; column-gap: 1.5rem; font-size: 16px; }

  /* --- Selected Work on mobile (Sept feedback) -------------------------
     "The selected work doesn't scroll like on the computer version."
     On desktop the giant type is pinned beside cards that alternate left
     and right. On a phone the cards go full-width, so the pinned heading
     ends up behind them and reads as broken. Below 768 it becomes an
     ordinary heading that scrolls away, and WORK stacks under SELECTED
     instead of being absolutely positioned over it. */
  .sticky-block { position: static; }
  .flex-right-horizontal { position: static; }
  .large-heading,
  .large-heading-right { font-size: 15vw; line-height: 0.95; }

  /* --- View Work bubble (Sept feedback) --------------------------------
     Webflow's own pre-hide <style> in index.html covers >=992 and 768-991
     but has no phone branch, and its hover interactions are registered for
     desktop and tablet only -- so below 768 nothing ever sets the initial
     opacity:0 and the bubble sits at full opacity over every card. There is
     no hover on touch for it to respond to either. */
  .view-work-wrapper { display: none; }
}

@media screen and (max-width: 479px) {
  .nav-logo { height: 13px; }
  .nav-link { font-size: 1.85rem; }
  .project-overlay h1 { font-size: 1.9rem; }

  /* Lucaso sets the card to 100vw while the section keeps 5% side padding,
     so the card is wider than the space it sits in and overflow:clip quietly
     shaves the right-hand edge off every image. */
  .collection-item { width: 100%; }

  /* The About halves need more height once the photo is 80vw. */
  .absolute-text-wrapper .heading-left,
  .absolute-text-wrapper .heading-right { height: 12vw; }
}

/* ---------------------------------------------------------------------------
   11. Reduced motion
   --------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}
