/* Base ---------------------------------------------------------------------- */
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background: #000;
  color: #EDECE8;
  font-family: "DM Mono", ui-monospace, monospace;
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
}
a { color: inherit; text-decoration: none; }
::selection { background: #EDECE8; color: #0a0908; }

#app { position: fixed; inset: 0; background: #000; overflow: hidden; }
#stage { position: absolute; inset: 0; }

/* Keyframes used by the experience --------------------------------------------*/
@keyframes fadeIn { from { opacity: 0 } to { opacity: 1 } }
@keyframes rise { from { opacity: 0; transform: translateY(14px) } to { opacity: 1; transform: translateY(0) } }
@keyframes arrowLoop  { 0%,100% { transform: translateX(-3px) } 50% { transform: translateX(3px) } }
@keyframes arrowLoopL { 0%,100% { transform: translateX(3px)  } 50% { transform: translateX(-3px) } }
@keyframes menuReveal { 0% { opacity: 0; transform: translateY(55px) } 100% { opacity: 1; transform: translateY(0) } }
@keyframes tileRise { 0% { opacity: 0; transform: translateY(140px) } 100% { opacity: 1; transform: translateY(0) } }
@keyframes growReveal { 0% { transform: scale(0); opacity: 1 } 100% { transform: scale(1); opacity: 1 } }
@keyframes fadeUp { from { opacity: 0; transform: translateY(26px) } to { opacity: 1; transform: translateY(0) } }

/* About — contact buttons */
.about-contact {
  width: clamp(46px, 3.4vw, 52px);
  height: clamp(46px, 3.4vw, 52px);
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  box-shadow: 0 8px 22px rgba(0,0,0,.4);
  transition: transform .2s ease, box-shadow .2s ease;
  flex-shrink: 0;
}
.about-contact:hover {
  transform: scale(1.12);
  box-shadow: 0 0 0 3px rgba(237,236,232,.85), 0 12px 28px rgba(0,0,0,.55);
}
/* Nice scrollbar for the About panel */
#aboutRoot::-webkit-scrollbar { width: 10px; }
#aboutRoot::-webkit-scrollbar-thumb { background: rgba(237,236,232,.14); border-radius: 8px; }
@keyframes grainShift { 0% { transform: translate(0,0) } 10% { transform: translate(-4%,-4%) } 30% { transform: translate(3%,-2%) } 50% { transform: translate(-2%,3%) } 70% { transform: translate(4%,2%) } 100% { transform: translate(0,0) } }

/* Reduced-motion: keep it usable for people who ask for less animation.
   Core reveal fades stay; long infinite loops are calmed. */
@media (prefers-reduced-motion: reduce) {
  [style*="arrowLoop"] { animation: none !important; }
  .brand-track { animation-duration: 400s !important; }
}

/* ============================================================================
   ABOUT (agency) — the white RAFT logo on a card in place of the portrait,
   numbers under the contact buttons, "what we do" tags, and the brand strip:
   two rows of logos drifting in opposite directions (paused on hover). Each
   track holds its logos twice and slides by -50%, so the loop is seamless.
   ============================================================================ */
.about-logo-card {
  position: relative; aspect-ratio: 4 / 5; border-radius: 16px; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  background: radial-gradient(120% 90% at 50% 38%, #161616 0%, #060606 72%);
  border: 1px solid rgba(237,236,232,.12); box-shadow: 0 30px 70px rgba(0,0,0,.5);
}
.about-logo-card img { height: 44%; width: auto; display: block; }
.about-label {
  font-family: 'Archivo', sans-serif; font-weight: 600; font-size: 12px; letter-spacing: .18em;
  color: #6f6c66; margin-bottom: clamp(14px, 1.6vw, 20px);
}
.about-section {
  margin-top: clamp(28px, 3.2vw, 44px); padding-top: clamp(22px, 2.4vw, 32px);
  border-top: 1px solid rgba(237,236,232,.12);
}
.about-tags { display: flex; flex-wrap: wrap; gap: 10px; }
.about-tags span {
  font-family: 'Archivo', sans-serif; font-weight: 500; font-size: clamp(12px, .9vw, 14px); letter-spacing: .02em;
  color: rgba(237,236,232,.86); padding: 9px 15px; border-radius: 999px;
  border: 1px solid rgba(237,236,232,.18); background: rgba(237,236,232,.03);
  transition: background .25s ease, color .25s ease, border-color .25s ease;
}
.about-tags span:hover { background: #EDECE8; color: #0a0908; border-color: #EDECE8; }
.about-stats {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; text-align: center;
  margin-top: clamp(22px, 2.4vw, 32px); padding-top: clamp(18px, 2vw, 26px);
  border-top: 1px solid rgba(237,236,232,.12);
}
.about-stats b {
  display: block; font-family: 'Archivo', sans-serif; font-weight: 600; font-size: clamp(30px, 2.6vw, 40px);
  line-height: 1; letter-spacing: -.02em; color: #EDECE8;
}
.about-stats span {
  display: block; margin-top: 8px; font-family: 'Archivo', sans-serif; font-weight: 600;
  font-size: 10px; letter-spacing: .16em; color: #6f6c66;
}
.about-brands { --bk: 1; max-width: 1120px; width: 100%; margin: clamp(44px, 5.5vw, 80px) auto 0; }
.brand-row {
  overflow: hidden; padding: 4px 0;
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 9%, #000 91%, transparent 100%);
  mask-image: linear-gradient(to right, transparent 0, #000 9%, #000 91%, transparent 100%);
}
.brand-row + .brand-row { margin-top: clamp(4px, .8vw, 12px); }
.brand-track { display: flex; align-items: center; width: max-content; animation: brandDrift var(--dur, 80s) linear infinite; }
.brand-row--rev .brand-track { animation-direction: reverse; }
.about-brands:hover .brand-track { animation-play-state: paused; }
.brand-cell { flex: 0 0 auto; height: 72px; padding: 0 clamp(20px, 2.4vw, 36px); display: flex; align-items: center; justify-content: center; }
.brand-cell img { display: block; object-fit: contain; opacity: .8; transition: opacity .25s ease, transform .25s ease; }
.brand-cell:hover img { opacity: 1; transform: scale(1.08); }
@keyframes brandDrift { from { transform: translateX(0) } to { transform: translateX(-50%) } }

/* ============================================================================
   TEAM — portrait cards, 4 per row (2 on phones), photos in their own colours.
   Hover: a slight push-in and the white stroke, like the work tiles. The grid's
   width follows the viewport height so both rows fit.
   ============================================================================ */
#teamRoot::-webkit-scrollbar { width: 10px; }
#teamRoot::-webkit-scrollbar-thumb { background: rgba(237,236,232,.14); border-radius: 8px; }
#teamWrap { width: 100%; max-width: clamp(560px, calc((100vh - 300px) * 1.5 + 60px), 1120px); margin: 0 auto; }
.team-heading {
  font-family: 'Damion', cursive; font-weight: 400; font-size: clamp(40px, 4.4vw, 66px); line-height: 1.05;
  color: #EDECE8; text-transform: lowercase; text-align: center;
}
.team-intro {
  margin: clamp(4px, .6vw, 8px) 0 clamp(24px, 3.4vh, 40px); text-align: center;
  font-family: 'Manrope', sans-serif; font-weight: 400; font-size: clamp(14px, 1vw, 16px); line-height: 1.6; color: rgba(237,236,232,.62);
}
#teamGrid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: clamp(14px, 1.8vw, 26px); }
.team-card {
  position: relative; margin: 0; aspect-ratio: 3 / 4; border-radius: 16px; overflow: hidden; isolation: isolate;
  background: #0a0908; border: 1px solid rgba(237,236,232,.12); box-shadow: 0 24px 60px rgba(0,0,0,.5);
}
.team-card img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block;
  transform: scale(1.02); transition: transform .6s cubic-bezier(.16,1,.3,1);
}
.team-card::before {                                    /* bottom shade under the caption */
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(to top, rgba(0,0,0,.88) 0%, rgba(0,0,0,.42) 24%, transparent 50%);
}
.team-card::after {                                     /* white stroke on hover, like the tiles */
  content: ""; position: absolute; inset: 0; z-index: 3; border-radius: inherit; pointer-events: none;
  border: 1.5px solid #fff; opacity: 0; transition: opacity .3s ease;
}
.team-card figcaption {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  padding: clamp(12px, 1.3vw, 20px); display: flex; flex-direction: column; gap: 6px;
}
.team-name { font-family: 'Archivo', sans-serif; font-weight: 600; font-size: clamp(14px, 1.25vw, 19px); line-height: 1.15; color: #fff; }
.team-role { font-family: 'Archivo', sans-serif; font-weight: 600; font-size: clamp(9px, .72vw, 11px); letter-spacing: .16em; text-transform: uppercase; color: rgba(237,236,232,.62); }
.team-card:hover img { transform: scale(1.07); }
.team-card:hover::after { opacity: 1; }
@media (hover: none) { .team-card img { transform: none; } }

/* ============================================================================
   CATEGORY TILES — everything inside a tile is sized in container-query units
   (cqw = 1% of the TILE'S OWN width), so a tile looks the same proportionally
   on a 32" monitor or a 13" laptop. Values are calibrated to the 32" look.

   Default: poster heavily blurred + darkened; the brand logo sits in the
   centre with the project name centred just under it. Hover (.is-on, set in
   App._tileHover), all starting together with an After Effects "Easy Ease"
   curve: the blur and the veil go away in 0.5 s, while the logo + name slide
   to the bottom-left (left-aligned, stacked) faster, in 0.25 s. Mouse-out
   plays it in reverse with the same timings.
   Per-tile geometry comes from JS (tileLockup): --ly / --ny (centred offsets),
   --nl (name lines) and --k (line index); name metrics here must match TL.
   ============================================================================ */
[data-tile] { container-type: inline-size; --tt: .5s; --tm: .25s; --te: cubic-bezier(.33,0,.67,1); --ls: .6; }
[data-tile] > div,
[data-tile] [data-stroke] { border-radius: 3.6cqw !important; }

[data-tile] [data-media] {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block;
  background: #0a0908;
  filter: blur(2cqw); transform: scale(1.08);       /* the slight zoom keeps the blur's soft edge outside the frame */
  transition: filter var(--tt) var(--te), transform var(--tt) var(--te);
}
[data-tile] [data-veil] {
  position: absolute; inset: 0; background: rgba(0,0,0,.5); pointer-events: none;
  transition: opacity var(--tt) var(--te);
}
[data-tile] [data-logo],
[data-tile] [data-name] {
  position: absolute; left: 4.2cqw; pointer-events: none; transform-origin: left bottom;
  transition: transform var(--tm) var(--te);         /* the lockup slides faster than the blur/veil fade */
}
[data-tile] [data-logo] {
  bottom: calc(4.2cqw + var(--nl, 1) * 4.44cqw + 1.6cqw); height: auto; display: block;  /* above the name line(s) */
  transform: translate(calc(45.8cqw - 50%), var(--ly));
}
[data-tile] [data-wordmark] {
  font-family: 'Archivo', sans-serif; font-weight: 900; font-stretch: 125%;
  font-size: 5.2cqw; line-height: 1; letter-spacing: .01em; color: #fff; white-space: nowrap;
}
[data-tile] [data-name] {
  bottom: calc(4.2cqw + var(--k, 0) * 4.44cqw);        /* --k = line index from the bottom */
  font-family: 'Archivo', sans-serif; font-weight: 500; font-stretch: 125%;
  font-size: 3.7cqw; line-height: 1.2; letter-spacing: .01em; color: #fff; white-space: nowrap;
  transform: translate(calc(45.8cqw - 50%), var(--ny));
}
[data-tile].is-on [data-media] { filter: blur(0); transform: scale(1); }
[data-tile].is-on [data-veil] { opacity: 0; }
[data-tile].is-on [data-logo] { transform: translate(0, 0) scale(var(--ls)); }
[data-tile].is-on [data-name] { transform: translate(0, 0); }

/* Categories with few works (< content.js marqueeMinWorks): a still grid —
   vertically centred, an incomplete last row centred, no marquee. The edge
   fade shrinks to the outer 10% so the entrance still slides in softly but the
   settled grid is fully visible. Tile size matches the 4 / 2-column grid. */
#catViewport[data-static] {
  display: flex; flex-direction: column; justify-content: center;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 10%, #000 90%, transparent 100%) !important;
  mask-image: linear-gradient(to bottom, transparent 0, #000 10%, #000 90%, transparent 100%) !important;
}
#catViewport[data-static] #catGrid {
  --g: clamp(40px, 4.5vw, 72px);
  display: flex !important; flex-wrap: wrap; justify-content: center;
  gap: var(--g) !important; padding-top: 0 !important;
}
#catViewport[data-static] #catGrid > [data-tile] { flex: 0 0 calc((100% - 3 * var(--g)) / 4); }

/* Touch screens (no hover, e.g. phones and iPads): nothing to hover, so tiles
   always show the revealed state — sharp poster, logo + name at bottom-left. */
@media (hover: none) {
  [data-tile] [data-media] { filter: none !important; transform: none !important; }
  [data-tile] [data-veil] { opacity: 0 !important; }
  [data-tile] [data-logo] { transform: scale(var(--ls)) !important; }
  [data-tile] [data-name] { transform: none !important; }
}

/* ============================================================================
   MOBILE / SMALL SCREENS
   The design is desktop-first with many inline styles, so these overrides use
   !important to win over inline values. Behavioral touch fixes live in app.js.
   ============================================================================ */
@media (max-width: 768px) {
  /* --- Category grid: 4 columns is unusable on a phone → 2 wide, larger --- */
  #catGrid {
    grid-template-columns: repeat(2, 1fr) !important;
    width: 92% !important;
    gap: 16px !important;
    padding-top: 20px !important;
  }
  /* Category title reads far too small at the clamp() min on phones */
  #catTitle { font-size: 20px !important; }

  /* Phones: tiles always show the revealed state (sharp poster, logo + name
     at bottom-left) with a slightly bigger logo/name for the small tiles, and
     less rounding so they don't look over-rounded. */
  [data-tile] [data-media] { filter: none !important; transform: none !important; }
  [data-tile] [data-veil] { opacity: 0 !important; }
  [data-tile] [data-logo] { left: 5cqw; bottom: calc(5cqw + var(--nl, 1) * 6.24cqw + 1.6cqw); transform: scale(.75) !important; }
  [data-tile] [data-name] { left: 5cqw; bottom: calc(5cqw + var(--k, 0) * 6.24cqw); font-size: 5.2cqw; transform: none !important; }
  [data-tile] > div,
  [data-tile] [data-stroke] { border-radius: 5cqw !important; }

  /* Still grid (few works): 2 per row like the marquee grid */
  #catViewport[data-static] #catGrid { --g: 16px; }
  #catViewport[data-static] #catGrid > [data-tile] { flex-basis: calc((100% - var(--g)) / 2); }

  /* Gate: lift "ENTER MUTED" clear of the bottom-right sound toggle
     so they stop overlapping on narrow screens. */
  #mutedBtn { bottom: 78px !important; }

  /* Slightly tighten the big menu type so long labels never clip */
  #nav a [data-label] { letter-spacing: -.03em !important; }

  /* Enlarge the whole menu list on phones (scale 1.44) and lift it ~35px */
  #nav { transform: translateY(-35px) scale(1.44); transform-origin: center; }

  /* RAFT logo (symbol + lettering): a fixed size that keeps the lettering legible */
  #homeLink img { height: 50px !important; }

  /* Intro video larger on phones. Pivot at the bottom so it grows
     upward and never collides with the ENTER button below it. */
  #introScale { transform: scale(1.35); transform-origin: center bottom; }

  /* Move the whole intro group (video + ENTER button) down a bit */
  #gateStack { transform: translateY(-40px) !important; }

  /* About: stack to one column; photo + contacts on top, text below */
  #aboutGrid { grid-template-columns: 1fr !important; gap: clamp(22px,4vh,32px) !important; padding-top: clamp(22px,4vh,40px) !important; }
  #aboutLeft { position: static !important; max-width: 320px; }
  .about-logo-card { aspect-ratio: 16 / 10; }
  .about-logo-card img { height: 54%; }
  .about-brands { --bk: .72; }
  .brand-cell { height: 56px; padding: 0 18px; }

  /* Team: 2 per row */
  #teamWrap { max-width: 560px; }
  #teamGrid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
  .team-card { border-radius: 12px; }
  .team-card img { transform: none; }
  .team-name { font-size: 15px; }
  .team-role { font-size: 9.5px; }

  /* Comfortable tap target for the sound toggle */
  #soundToggle { padding: 6px 4px; }

  /* Video player on phones: show the whole frame (no crop) and drop the
     fullscreen button — the player is already made fullscreen-landscape below. */
  #workVid { object-fit: contain !important; }
  #fsBtn { display: none !important; }
}

/* Phone held PORTRAIT: the player is rotated 90° into landscape. The exact size
   is set from JS (App._layoutDetail) using the REAL visible viewport
   (visualViewport), so the browser's top/bottom bars never clip it. */

/* Phone actually turned to landscape (OS rotated): natural landscape, no crop. */
@media (orientation: landscape) and (max-height: 500px) {
  #workVid { object-fit: contain !important; }
  #fsBtn { display: none !important; }
}

/* Very narrow phones: give the grid a touch more room */
@media (max-width: 380px) {
  #catGrid { width: 96% !important; gap: 12px !important; }
  #catViewport[data-static] #catGrid { --g: 12px; }
}
