/* ===========================================================================
   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; }
/* The title's visible top must line up with the top of the media on the right.

   Two separate offsets were in the way:
   1. The sticky `top` was calc(nav + 40px), which pushed the whole column
      120px below the media. The scroll container already pads by the nav
      height, so `top: 0` pins it just under the nav — measured, it does not
      slide beneath it when scrolling.
   2. Even then only the h1's BOX aligned. Line-height leading puts the cap
      of the first letter 0.15em lower, so the text still read as sitting low.
      The negative margin lifts the glyph, not the box.

   Both values are measured, not guessed: 0.1501em at every size, so em keeps
   it correct as the heading steps down through the breakpoints. */
.project-details-info-wrapper { top: 0; padding-top: 40px; }
.project-overlay h1 { margin-top: -0.15em; }
.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;
  /* 9vw matches the ink height of SELECTED / WORK exactly.
     Measured, not guessed: those headings are font-size 12vw, and Inter's
     cap height renders at 9.00vw of that (103.1px at a 1146px viewport).
     Because the logo SVG's viewBox is cropped to the artwork bounds, the
     element's height IS its ink height — so the two read as the same size. */
  height: 9vw;
  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; }
  /* About hero 480-767 (ticket #247): the 60vw portrait set here earlier left
     no room beside it for the logo halves (9vw tall = ~31vw / ~29vw wide), so
     they overlapped the photo exactly as on phones. 40vw + 6.5vw halves clear
     it with a gap on both sides inside 100vw - 3rem. */
  .about-hero { padding-left: 1.5rem; padding-right: 1.5rem; }
  .about-hero-image { width: 40vw; }
  .absolute-text-wrapper { justify-content: center; }
  .absolute-text-wrapper .heading-left,
  .absolute-text-wrapper .heading-right { height: 6.5vw; }

  /* --- 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%; }

  /* --- About hero on phones (ticket #247) ---------------------------------
     The halves are pinned to the section's content edges (inset:0). With the
     photo at 80vw and the halves 12vw tall (~42vw / ~39vw wide) there is no
     room beside it, so they were drawn ACROSS the photo — and base.css
     sinks them to the bottom with justify-content:flex-end. The client wants
     the desktop composition: "color" left of the photo, "blind" right of it.
     Photo 34vw + halves 7vw (~24vw / ~23vw) fit inside 100vw - 2rem with a
     gap on each side down to a 320px screen; the 767px block below handles
     480-767 the same way. The reveal animation is untouched. */
  .about-hero { padding-left: 1rem; padding-right: 1rem; }
  .about-hero-image { width: 34vw; }
  .absolute-text-wrapper { justify-content: center; }
  .absolute-text-wrapper .heading-left,
  .absolute-text-wrapper .heading-right { height: 7vw; }
}

/* ---------------------------------------------------------------------------
   12. Kamerik fonts
   Client request (ticket #240): replace Inter with Kamerik 205 on specific
   elements across all pages. Sizes and colours are untouched.
   --------------------------------------------------------------------------- */

/* Homepage — hero and marquees */
.scroll-down-text                        { font-family: 'Kamerik 205 Light', sans-serif; }
.large-heading,
.large-heading-right                     { font-family: 'Kamerik 205 Light', sans-serif; }
.text-animation                          { font-family: 'Kamerik 205 Light', sans-serif; }

/* Homepage — project card names + years (inherits to future cards via this selector) */
.works-title                             { font-family: 'Kamerik 205 Light', sans-serif; }

/* Footer (appears on Homepage and About) */
.footer-text                             { font-family: 'Kamerik 205 Light', sans-serif; }
.cta-text                                { font-family: 'Kamerik 205 Light', sans-serif; }

/* Burger menu — all elements */
.nav-menu-block                          { font-family: 'Kamerik 205 Bold', sans-serif; }
/* The numbered labels use an explicit Chivo Mono override; must defeat it here */
.nav-link-number-block .paragraph-text-mono { font-family: 'Kamerik 205 Bold', sans-serif; }

/* About page */
.about-paragraph,
.about-paragraph-home                    { font-family: 'Kamerik 205 Light', sans-serif; }
.small-title-heading                     { font-family: 'Kamerik 205 Light', sans-serif; }
.cb-client-list                          { font-family: 'Kamerik 205 Light', sans-serif; }

/* Contact page */
/* .large-heading.smaller is more specific than .large-heading, so Bold wins here
   over the Light set above — covers "hi" on Contact and "NOT HERE" on 404 */
.large-heading.smaller                   { font-family: 'Kamerik 205 Bold', sans-serif; }
/* Cancel the uppercase transform for the contact heading only — 404's "NOT HERE"
   is unaffected because it sits outside <section class="contact"> */
.contact .large-heading.smaller          { text-transform: none; }
.contact-text                            { font-family: 'Kamerik 205 Light', sans-serif; }
.contact-link                            { font-family: 'Kamerik 205 Light', sans-serif; }

/* ---------------------------------------------------------------------------
   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;
  }
}

/* ---------------------------------------------------------------------------
   13. karimproducer.com — About hero halves (KARIM / BEKDACHE)
   The colorblind halves are ~3.5:1 each; KARIM is 4.17:1 and BEKDACHE 7.14:1,
   so at the inherited 9vw height BEKDACHE ran ~64vw wide straight across the
   portrait. Sized down so the pair keeps the colorblind composition (one word
   each side of the photo, slight overlap inverted by the wrapper's
   mix-blend-mode: difference). RETUNE when the real logo replaces the
   stand-in wordmark — these numbers follow the artwork's aspect ratios.
   --------------------------------------------------------------------------- */
.absolute-text-wrapper .heading-left,
.absolute-text-wrapper .heading-right { height: 5.5vw; }
@media screen and (max-width: 767px) {
  .absolute-text-wrapper .heading-left,
  .absolute-text-wrapper .heading-right { height: 4.5vw; }
}
@media screen and (max-width: 479px) {
  .absolute-text-wrapper .heading-left,
  .absolute-text-wrapper .heading-right { height: 4.5vw; }
}
/* ---------------------------------------------------------------------------
   14. "Powered by Above The Fold" (same as colorblind.paris) — the signature
   A small byline centred under "Say Hi": the footer's one strong axis on
   every screen size (on phones the contact rows stack left but "Say Hi"
   stays centred, so a centred byline never adds a competing alignment).
   Muted at rest; on hover it comes up to full white and lifts 2px.
   The mark is the ATF capsule from the brand files (vector) with its
   letters KNOCKED OUT, so the footer's own texture shows through "ATF".
   --------------------------------------------------------------------------- */
.cb-credit-row {
  display: flex;
  justify-content: center;
  margin-top: 1.5rem;
}
.cb-credit {
  display: inline-flex;
  /* align-items:center centres the LINE BOXES, not the ink: a line box's
     descender space (for the "y" in "By") sits below the cap height, so
     centring the boxes leaves the capsule looking low against the glyphs.
     The translateY on .cb-credit-mark below corrects for that. */
  align-items: center;
  gap: 11px;
  color: var(--white);
  text-decoration: none;
  opacity: .5;
  transition: opacity .45s var(--cb-ease, ease), transform .45s var(--cb-ease, ease);
}
.cb-credit:hover,
.cb-credit:focus-visible { opacity: 1; transform: translateY(-2px); }
.cb-credit:focus-visible { outline: 1px solid currentColor; outline-offset: 6px; }
.cb-credit-label {
  font-family: 'Kamerik 205 Bold', sans-serif;
  font-size: 13px;
  line-height: 1;
  white-space: nowrap;
  letter-spacing: .02em;
}
.cb-credit-mark {
  display: block;
  height: 15px;
  width: auto;
  transform: translateY(-1.5px);
}
@media screen and (max-width: 767px) {
  .cb-credit-row { margin-top: 1.25rem; }
  .cb-credit { gap: 9px; }
  .cb-credit-label { font-size: 12px; }
  .cb-credit-mark { height: 13px; transform: translateY(-1px); }
}
@media (hover: none) { .cb-credit { opacity: .65; } }
@media (prefers-reduced-motion: reduce) { .cb-credit { transition: opacity .2s linear; } .cb-credit:hover { transform: none; } }

/* Contact page has no dark .footer-cta band like the other three pages —
   the credit needs light-background contrast instead of white-on-black. */
.contact .cb-credit-row { margin-top: 3rem; }
.contact .cb-credit { color: var(--cb-ink); }
.contact .cb-credit-mark { filter: invert(1); }
