/* iPhones draw a play button over a muted clip that has not started yet (or was
   paused by being moved in the page): the clips play on their own, so never show it */
video::-webkit-media-controls-start-playback-button { display: none !important; -webkit-appearance: none; }
video::-webkit-media-controls-overlay-play-button { display: none !important; }
video::-webkit-media-controls-panel { display: none !important; }
/* the whole native control layer, not just its parts: newer iPhones draw their play
   button from it even when the parts above are hidden */
video::-webkit-media-controls { display: none !important; }
video::-webkit-media-controls-enclosure { display: none !important; }
video::-webkit-media-controls-play-button { display: none !important; }

/* Card -> project-page transition (cross-document view transitions; browsers
   without them simply navigate as before). The clicked card and its twin on the
   project page share the name "hero", so the picture glides up into place. */
@view-transition { navigation: auto; }

/* the header is the same on both pages: keep it still while the rest fades */
.navigation { view-transition-name: site-nav; }

/* "hero-2" is the other half of a pair shown side by side: the two travel as a block */
::view-transition-group(hero),
::view-transition-group(hero-2) {
  animation-duration: .65s;
  animation-timing-function: cubic-bezier(.4, 0, .2, 1);
  overflow: hidden;
  border-radius: 16px;
}
/* the card and the first slot can differ in shape: crop instead of stretching */
::view-transition-old(hero),
::view-transition-new(hero),
::view-transition-old(hero-2),
::view-transition-new(hero-2) {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Same picture at both ends (html.vt-same, set on arrival): carry the one that was
   already on screen all the way, rather than cross-fading into a copy that may
   still be loading. The live picture takes over when the glide ends. The partner
   of a pair is always found by its own file, so it is always the same picture. */
:root.vt-same::view-transition-old(hero),
::view-transition-old(hero-2) { animation: none; opacity: 1; }
:root.vt-same::view-transition-new(hero),
::view-transition-new(hero-2) { animation: none; opacity: 0; }

::view-transition-old(root),
::view-transition-new(root) { animation-duration: .35s; animation-timing-function: ease-out; }

/* Back on the grid from a project page (html.grid-return): Webflow's scroll-in
   reveals would make the cards around the landing spot fade in late */
html.grid-return [data-w-id] { opacity: 1 !important; transform: none !important; }

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
}

/* Case sidebar entrance (js/text-in.js): hidden until the script has split the
   text, so nothing flashes in its final place first. Layout is kept for measuring. */
html.text-wait .case-side .case-title,
html.text-wait .case-side .case-sub,
html.text-wait .case-side .case-ext,
html.text-wait .case-side .case-arrow,
html.text-wait .case-side .case-facts { visibility: hidden; }
/* each letter sits at its measured place (js/text-in.js); the mask reaches past the
   letter on every side so accents, descenders and overhangs are not clipped */
.ti-mask { position: absolute; overflow: hidden; padding: .14em .3em .2em; margin: -.14em 0 0 -.3em; white-space: pre; }
.ti-char { display: inline-block; vertical-align: top; }
.ti-line { display: block; }

/* Serif: Source Serif 4 on the project titles and the home intro */
.case-wrap .case-side h1 { font-family: "Source Serif 4", Georgia, serif; font-weight: 400; letter-spacing: -.015em; }
.div-block-9 > p.paragraph, .div-block-9 > p.paragraph strong { font-family: "Source Serif 4", Georgia, serif; letter-spacing: -.01em; }

/* Phones: every project page in one column — title, the text, cover, facts, carousel.
   js/case-mobile.js rearranges the page and marks it .m-built. */
/* desktop: in the sidebar, under the link; each label above its value */
.case-side .case-facts { display: grid; gap: 14px; margin: 28px 0 0; padding: 0; max-width: 250px; }
.case-side .case-facts > div { display: grid; gap: 3px; }
.case-side .case-facts dt { color: #9a9a94; font-size: 12px; line-height: 1.3; margin: 0; }
.case-side .case-facts dd { font-family: "Source Serif 4", Georgia, serif; color: #111; font-size: 14px; line-height: 1.4; margin: 0; }
@media screen and (max-width: 860px) {
  html.case-m-wait .case-wrap { visibility: hidden; }
  .case-wrap.m-built { display: flex; flex-direction: column; align-items: stretch; gap: 0; }
  .m-built .case-title { align-self: flex-start; }
  .case-wrap.m-built > .case-side,
  .case-wrap.m-built > .case-media { display: contents; }
  .m-built .case-media > * { order: 6; }
  .m-built .case-title { order: 1; }
  .m-built .case-side .case-sub,
  .m-built .case-side .case-ext { order: 2; }
  .m-built .case-m-cover { order: 3; margin-top: 40px; }
  .m-built .case-m-cover { cursor: pointer; }   /* it opens in the viewer (js/case-mobile.js) */
  .m-built .case-facts { order: 4; }
  .m-built .case-m-carousel { order: 5; }
  .m-built .case-nav { order: 8; margin-top: 40px; }
  .case-m-empty { display: none !important; }
  /* the back arrow's stroke lines up with the "Caio Jacintho" brand above it */
  .m-built .case-side .case-arrow { left: -6px; }

  /* about: every paragraph under the title, one after the other, in the small grey sans */
  .m-built .case-side .case-sub { font-family: "DM Sans", sans-serif; font-size: 15px; line-height: 1.5; color: #9a9a94; max-width: none; margin: 10px 0 0; }
  .m-built .case-side .case-ext { align-self: flex-start; margin-top: 24px; font-size: 15px; }

  /* the pictures stack, one under the other, down the page */
  .m-built .case-m-carousel { display: flex; flex-direction: column; align-items: center; gap: 12px; margin: 104px 0 0; }
  /* the cover and every picture under it: the page's full width, as tall as its own
     proportions make it (--r, set by js/case-mobile.js; 16:9 until it has loaded).
     For a phone mockup — a phone standing on a plain background — js/case-mobile.js
     puts a taller shape in --r instead, the one that blows the picture up until the
     phone is half the card wide, the same in every mockup on the site, and shifts it
     sideways (--ph-x) so the phone lands in the middle. */
  .m-built .case-m-cover,
  .m-built .case-m-slide { width: 100%; height: auto; aspect-ratio: var(--r, 16 / 9); }
  /* the cover is a square, the same box the featured grid's card is
     (js/cover-shape.js: COVER_R), so the picture does not resize between the pages.
     Its picture spans the square's full width, centred on the grey, the way a clip
     already does here — nothing is cropped, and every browser-window mockup comes
     out the same size. */
  .m-built .case-m-cover { aspect-ratio: 1 / 1; }
  .m-built .case-m-cover img,
  .m-built .case-m-cover video.case-video { width: calc(100% * var(--cover-zoom, 1)) !important; height: auto !important; object-fit: cover !important; }
  .m-built .case-m-cover > img,
  .m-built .case-m-cover > video.case-video { top: 50%; left: 50%; right: auto; bottom: auto; transform: translate(-50%, -50%); }
  /* except where the artwork floats in a lot of empty space — a logo, a slide, a
     drawing with wide margins. Marked data-cover-fill in the page's markup, it
     grows until its height matches the square's and is cropped at the sides;
     --cover-zoom trims that back, 1 being the square's full height. The featured
     grid reads the same two marks, so the card still matches. */
  .m-built .case-m-cover [data-cover-fill] > video,
  .m-built .case-m-cover video[data-cover-fill],
  .m-built .case-m-cover img[data-cover-fill] {
    position: absolute !important;
    top: 50% !important; left: 50% !important; right: auto !important; bottom: auto !important;
    width: auto !important; height: calc(100% * var(--cover-zoom, 1)) !important;
    max-width: none !important;   /* Webflow clamps every picture to its box */
    transform: translate(-50%, -50%) !important;
    object-fit: cover !important; clip-path: none;
  }
  .case-m-frame[data-sorted="phone"] img,
  .case-m-frame[data-sorted="phone"] video { object-position: var(--ph-x, 50%) 50%; }

  /* cover and slides: a grey card the picture fills. Isolated, so Webflow's
     background videos (parked at z-index:-100) still paint over the grey. */
  .case-m-frame { position: relative; isolation: isolate; border-radius: 16px; overflow: hidden; background: #F2F2F2; }
  .case-m-frame > * { position: absolute !important; inset: 0; }
  .case-m-frame .div-block, .case-m-frame a, .case-m-frame .sec { display: flex !important; align-items: center; justify-content: center; width: 100%; height: 100% !important; margin: 0 !important; padding: 0 !important; aspect-ratio: auto !important; background: transparent !important; border-radius: 0 !important; overflow: visible !important; }
  .case-m-frame img { display: block; width: 100% !important; height: 100% !important; object-fit: cover !important; border-radius: 0 !important; }
  .case-m-frame .w-background-video { width: 100% !important; height: 100% !important; aspect-ratio: auto !important; border-radius: 0 !important; }
  .case-m-frame .w-background-video > video { object-fit: cover !important; border-radius: 0 !important; }
  /* site mockup clips stay whole at their own ratio, centred on the grey (not
     object-fit:contain: iOS paints a hairline where a letterboxed clip meets it) */
  .case-m-frame video.case-video { width: 100% !important; height: auto !important; aspect-ratio: auto !important; border-radius: 0 !important; clip-path: inset(1px); background: transparent !important; }
  .case-m-frame > video.case-video { top: 50%; bottom: auto; transform: translateY(-50%); }
  /* phone recordings stand whole, as tall as the card */
  .case-m-frame video.case-phone { width: auto !important; max-width: 100%; height: 100% !important; object-fit: contain; border-radius: 0 !important; }
  .case-m-frame > video.case-phone { left: 50%; right: auto; transform: translateX(-50%); }

  /* facts: industry, contribution, year, skills — under the cover */
  /* each label above its value, as on desktop */
  .m-built .case-facts { display: grid; grid-template-columns: 1fr; gap: 14px; margin: 0; padding: 96px 0 0; max-width: none; }
  .m-built .case-facts > div { display: grid; grid-template-columns: 1fr; gap: 3px; }
  .m-built .case-facts dt { color: #9a9a94; font-size: 13px; line-height: 1.3; margin: 0; }
  .m-built .case-facts dd { font-family: "Source Serif 4", Georgia, serif; color: #111; font-size: 15px; line-height: 1.45; margin: 0; }
}

/* "Next project": the same pill as "Let's talk" on the home. On hover the label rolls
   up out of the pill while its copy (::after, from data-label, kept in step with
   EN/PT by js/case-mobile.js) rolls in from underneath. */
.case-nav { justify-content: flex-start; }
@media screen and (min-width: 861px) { .case-nav { justify-content: flex-end; } }   /* desktop: at the right */
.case-nav .case-nav-link { background: transparent; color: #111; border: 1px solid #e3e3df; border-radius: 999px; padding: 13px 21px; overflow: hidden; transition: background-color .2s ease, color .2s ease; }
.case-nav .case-nav-link:hover { background: #111; border-color: #111; color: #fff; }
.case-nav .case-nav-name { position: relative; display: inline-block; overflow: visible; font-family: "DM Sans", sans-serif; font-size: 15px; font-weight: 500; line-height: 1; text-transform: none; transition: transform .5s cubic-bezier(.65, 0, .35, 1); }
.case-nav .case-nav-name::after { content: attr(data-label); position: absolute; left: 0; top: 2em; white-space: nowrap; }
.case-nav .case-nav-link:hover .case-nav-name,
.case-nav .case-nav-link:focus-visible .case-nav-name { transform: translateY(-2em); }

/* the back arrow only on phones (above the title); desktop goes back through the nav */
@media screen and (min-width: 861px) {
  .case-side .case-arrow { display: none !important; }
}


/* the picture viewer (js/case-mobile.js): a tap on a carousel picture shows it whole */
html.case-viewer-open, html.case-viewer-open body { overflow: hidden; }
.case-viewer { position: fixed; inset: 0; z-index: 2000; background: #fff; opacity: 0; visibility: hidden; transition: opacity .25s ease, visibility 0s linear .25s; }
.case-viewer.is-open { opacity: 1; visibility: visible; transition: opacity .25s ease; }
.case-viewer-stage { position: absolute; inset: 64px 12px 104px; }
.case-viewer-stage img, .case-viewer-stage video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; display: block; }
/* a clip is not letterboxed (contain draws a hairline where its frame meets the empty
   area, on phones): it sits at its own shape across the width, centred, its 1px rim
   trimmed. A clip taller than the stage still fits by height (max-height). */
.case-viewer-stage video:not(.is-phone) { inset: auto; left: 50%; top: 50%; width: auto; height: auto; max-width: 100%; max-height: 100%; transform: translate(-50%, -50%); object-fit: fill; clip-path: inset(1px); }
/* a phone mockup fills the stage (its plain background trimmed at the sides), so the
   phone itself shows large */
.case-viewer-stage .is-phone { object-fit: cover; border-radius: 16px; }
.case-viewer-btn { position: absolute; width: 44px; height: 44px; border-radius: 999px; border: 1px solid #e3e3df; background: #fff; color: #111; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; padding: 0; text-decoration: none; }
.case-viewer-btn[hidden] { display: none; }
.case-viewer-close { top: 12px; right: 12px; border-color: transparent; }
/* the arrows side by side in the middle, a little above the bottom */
.case-viewer-prev { bottom: 40px; left: calc(50% - 48px); }
.case-viewer-next { bottom: 40px; left: calc(50% + 4px); }
.case-viewer-out { bottom: 40px; right: 12px; }
.case-viewer-btn:hover { background: #111; border-color: #111; color: #fff; }
/* the carousel's pictures show they open */
.m-built .case-m-slide { cursor: zoom-in; }
/* the facts' link: the address itself, clickable */
.case-facts dd a { display: block; width: fit-content; color: inherit; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; overflow-wrap: anywhere; }
.case-facts dd a:hover { color: #6b6b66; }
/* Rivio's two screens sit small on a wide grey field: in the viewer they are zoomed so
   the screen fills the width */
.case-viewer-stage { overflow: hidden; }
.case-viewer-stage img[src*="68ade5a3c3123ce060052a1d_2102"],
.case-viewer-stage img[src*="68ade3b1e60beed1c7076be2_2099"] { transform: scale(1.9); }
/* phones: on the page too, these two pictures (a small screen in a lot of grey)
   are blown up inside their card, so the screen runs wider */
.m-built .case-m-slide img[src*="68ade5a3c3123ce060052a1d_2102"],
.m-built .case-m-slide img[src*="68ade3b1e60beed1c7076be2_2099"] { transform: scale(1.3); }
/* both stand in the same taller card, the screen blown up a little less so it still fits the width */
.m-built .case-m-slide:has(img[src*="68ade5a3c3123ce060052a1d_2102"]),
.m-built .case-m-slide:has(img[src*="68ade3b1e60beed1c7076be2_2099"]) { aspect-ratio: 4 / 3; }

/* project pages: a Webflow background video has no height of its own (its clip is laid
   over it), so it takes the clip's 16:9 shape unless a rule gives it a height */
.case-media .w-background-video { aspect-ratio: var(--ratio, 16 / 9); }

/* Storytelling and Data visualization: a piece that opens a live story or chart
   carries a small button in its bottom-right corner (added by js/case-mobile.js) */
.case-ext-link { position: relative; display: block; }
.case-go { position: absolute; right: 16px; bottom: 16px; z-index: 3; width: 40px; height: 40px;
  display: inline-flex; align-items: center; justify-content: center; border-radius: 999px;
  background: #fff; border: 1px solid #e3e3e3; color: #111; pointer-events: none;
  box-shadow: 0 1px 2px rgba(0,0,0,.04); transition: background-color .2s, border-color .2s; }
.case-go { overflow: hidden; }
/* on hover the button fills in and its arrow flies out to the top right while a twin
   comes in from the bottom left */
.case-go svg { position: absolute; display: block; transition: transform .38s cubic-bezier(.22,.7,.2,1), opacity .3s ease; }
.case-go svg + svg { transform: translate(-150%, 150%); opacity: 0; }
.case-ext-link:hover .case-go { background: #111; border-color: #111; color: #fff; transform: scale(1.06); }
.case-ext-link:hover .case-go svg:first-child { transform: translate(150%, -150%); opacity: 0; }
.case-ext-link:hover .case-go svg + svg { transform: none; opacity: 1; }
.case-go { transition: background-color .25s ease, border-color .25s ease, color .25s ease, transform .3s cubic-bezier(.22,.7,.2,1); }
@media (prefers-reduced-motion: reduce) { .case-go, .case-go svg { transition: none; } }
@media screen and (max-width: 860px) { .case-go { right: 12px; bottom: 12px; width: 34px; height: 34px; } }
/* Storytelling: the transport and housing clip has a thin white rim of its own;
   a touch larger inside its card, so the card is all picture */
.case-media .w-background-video:has(source[data-src*="transportehabitacao"]) { overflow: hidden; }
.case-media .w-background-video:has(source[data-src*="transportehabitacao"]) > video { transform: scale(1.04); }

/* Arriving from a card: the clicked picture glides into place first; the other
   pictures of the page wait out of sight, then rise in one after another
   (js/hero-transition.js sets media-wait, then media-in with a stagger) */
html.media-wait .case-media > :not(:first-child),
html.media-wait .case-media .case-m-carousel > * { opacity: 0; transform: translateY(32px); }
html.media-in .case-media > :not(:first-child),
html.media-in .case-media .case-m-carousel > * {
  transition: opacity .7s ease var(--in-d, 0s), transform .9s cubic-bezier(.2, .7, .2, 1) var(--in-d, 0s);
}
@media (prefers-reduced-motion: reduce) {
  html.media-wait .case-media > :not(:first-child), html.media-wait .case-media .case-m-carousel > * { opacity: 1; transform: none; }
}
