.fbs-mosaic{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--fbs-mosaic-min,260px),1fr));grid-auto-rows:170px;grid-auto-flow:dense;gap:14px}
.fbs-vtile{position:relative;display:block;padding:0;margin:0;border:0;border-radius:0;overflow:hidden;background:#eceae3;cursor:pointer;grid-column:span 1;grid-row:span 1;transition:transform .26s cubic-bezier(.2,.7,.3,1),box-shadow .26s ease}
.fbs-vtile--wide{grid-column:span 2}
.fbs-vtile--tall{grid-row:span 2}
.fbs-vtile--big{grid-column:span 2;grid-row:span 2}
.fbs-vtile:hover{transform:translateY(-2px);box-shadow:0 14px 30px -14px rgba(20,21,26,.4)}
.fbs-vtile__img{width:100%;height:100%;object-fit:cover;display:block}
.fbs-vtile__blank{display:block;width:100%;height:100%;background:#eceae3}
.fbs-vtile__play{position:absolute;top:50%;left:50%;width:54px;height:54px;transform:translate(-50%,-50%);border-radius:50%;background:rgba(20,119,219,.92);transition:transform .22s ease}
.fbs-vtile__play::after{content:"";position:absolute;top:50%;left:54%;transform:translate(-50%,-50%);border-style:solid;border-width:9px 0 9px 15px;border-color:transparent transparent transparent #ffffff}
.fbs-vtile:hover .fbs-vtile__play{transform:translate(-50%,-50%) scale(1.08)}
.fbs-vtile__meta{position:absolute;left:0;right:0;bottom:0;display:flex;flex-direction:column;gap:3px;padding:28px 14px 12px;text-align:left;background:linear-gradient(to top,rgba(20,21,26,.85),rgba(20,21,26,0))}
.fbs-vtile__title{font-family:"Space Grotesk",sans-serif;font-size:16px;font-weight:600;letter-spacing:-0.02em;color:#faf8f2;line-height:1.2}
.fbs-vtile__client{font-family:"Press Start 2P",monospace;font-size:8px;color:#9ea1aa;line-height:1.6}
.fbs-mosaic-empty{font-family:"IBM Plex Sans",sans-serif;font-size:16px;color:#6b6e78;padding:26px 0}
.fbs-lb{position:fixed;inset:0;z-index:100000;display:flex;align-items:center;justify-content:center;background:rgba(13,14,18,.93);padding:24px}
.fbs-lb[hidden]{display:none}
.fbs-lb__stage{width:min(1100px,92vw);aspect-ratio:16/9;background:#000000;border-radius:14px;overflow:hidden}
.fbs-lb__stage iframe,.fbs-lb__stage video{width:100%;height:100%;border:0;display:block}
.fbs-lb__close{position:absolute;top:22px;right:24px;font-family:"IBM Plex Sans",sans-serif;font-size:13px;font-weight:600;color:#14151a;background:#faf8f2;border:0;border-radius:999px;padding:9px 18px;cursor:pointer}
@media (max-width:640px){.fbs-mosaic{grid-auto-rows:150px}.fbs-vtile--wide,.fbs-vtile--big{grid-column:span 1}.fbs-vtile--big{grid-row:span 1}}
@media (prefers-reduced-motion:reduce){.fbs-vtile,.fbs-vtile__play{transition:none !important}.fbs-vtile:hover{transform:none}.fbs-vtile:hover .fbs-vtile__play{transform:translate(-50%,-50%)}}

/* --- image mosaics on the discipline pages ---
   Masonry columns rather than a fixed grid, so every image keeps its own
   proportions. Nothing is cropped, only scaled to the column width.
   The video mosaic keeps the fixed grid above, since its thumbnails are
   uniformly 16:9. --- */
.fbs-mosaic--fit{display:block;columns:var(--fbs-mosaic-min,260px);column-gap:14px;grid-template-columns:none;grid-auto-rows:auto}
.fbs-mosaic--fit .fbs-vtile{display:block;width:100%;margin:0 0 14px;break-inside:avoid;-webkit-column-break-inside:avoid;page-break-inside:avoid;border:0;border-radius:0;background:transparent;overflow:visible;grid-column:auto;grid-row:auto;box-shadow:none}
.fbs-mosaic--fit .fbs-vtile__img{width:100%;height:auto;display:block;object-fit:fill;border-radius:0}
.fbs-mosaic--fit .fbs-vtile:hover{transform:translateY(-2px);box-shadow:none}
.fbs-vtile--photo .fbs-vtile__play{display:none}
.fbs-vtile--photo .fbs-vtile__meta{opacity:0;transition:opacity .24s ease;border-radius:0}
.fbs-vtile--photo:hover .fbs-vtile__meta,.fbs-vtile--photo:focus-visible .fbs-vtile__meta{opacity:1}
.fbs-mosaic--fit .fbs-vtile--big,.fbs-mosaic--fit .fbs-vtile--wide{column-span:all}
.fbs-lb__stage.is-photo{aspect-ratio:auto;width:auto;max-width:92vw;max-height:86vh;background:transparent;border-radius:0}
.fbs-lb__stage.is-photo img{display:block;width:auto;height:auto;max-width:92vw;max-height:86vh;object-fit:contain;border-radius:0}
@media (max-width:640px){.fbs-mosaic--fit{columns:1}}
/* --- discipline mosaics lock to three columns on desktop and laptop landscape --- */
@media (min-width:1025px){.fbs-mosaic--fit{column-count:3;column-width:auto}}
@media (prefers-reduced-motion:reduce){.fbs-mosaic--fit .fbs-vtile{transition:none!important}.fbs-mosaic--fit .fbs-vtile:hover{transform:none}.fbs-vtile--photo .fbs-vtile__meta{transition:none!important}}

/* --- overlay layering ---
   The lightbox is reparented to <body> by the script, so these sit in the
   root stacking context and clear Divi's sticky header. --- */
.fbs-lb{z-index:100000 !important}
.fbs-cursor-layer{z-index:100001 !important}
.fbs-cur-dot{z-index:100001}

/* --- tall images scroll instead of shrinking ---
   Anything more than 1.6x taller than it is wide gets shown at full column
   width inside a scrolling frame, so long screenshots stay readable. --- */
.fbs-lb__stage.is-tall{width:min(900px,92vw);max-width:92vw;height:86vh;max-height:86vh;overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;background:#14151a;border-radius:0;outline:none}
.fbs-lb__stage.is-tall img{width:100%;height:auto;max-width:none;max-height:none;display:block;object-fit:fill;border-radius:0}
.fbs-lb__stage.is-tall:focus-visible{outline:2px solid #1477db;outline-offset:3px}
.fbs-lb__stage.is-tall::-webkit-scrollbar{width:10px}
.fbs-lb__stage.is-tall::-webkit-scrollbar-track{background:rgba(250,248,242,.12)}
.fbs-lb__stage.is-tall::-webkit-scrollbar-thumb{background:rgba(250,248,242,.45);border-radius:999px}
.fbs-lb__stage.is-tall::-webkit-scrollbar-thumb:hover{background:rgba(250,248,242,.7)}
.fbs-lb__stage.is-tall{scrollbar-width:thin;scrollbar-color:rgba(250,248,242,.45) rgba(250,248,242,.12)}

/* --- looping tile previews ---
   Muted, looping playback inside the tile. The media is inert so clicks
   still reach the tile button and open the lightbox with sound. --- */
.fbs-vtile__live{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);border:0;pointer-events:none;background:#0d0e12;opacity:0;transition:opacity .35s ease}
.fbs-vtile__live.is-on{opacity:1}
video.fbs-vtile__live{width:100%;height:100%;object-fit:cover;transform:none;top:0;left:0}
.fbs-vtile.is-live .fbs-vtile__img{opacity:0;transition:opacity .35s ease}
.fbs-vtile.is-live .fbs-vtile__play{opacity:.75;transition:opacity .25s ease}
.fbs-vtile.is-live:hover .fbs-vtile__play{opacity:1}
@media (prefers-reduced-motion:reduce){.fbs-vtile__live{display:none !important}.fbs-vtile.is-live .fbs-vtile__img{opacity:1}}

/* --- video tiles keep their own shape ---
   The tile carries an inline aspect-ratio taken from the file itself, so a
   vertical reel stays vertical and nothing is cropped to fit a grid cell. --- */
.fbs-mosaic--fit .fbs-vtile{height:auto}
.fbs-mosaic--fit .fbs-vtile__blank{position:absolute;inset:0;width:100%;height:100%}
.fbs-mosaic--fit video.fbs-vtile__live{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;background:#0d0e12}
.fbs-vtile--photo .fbs-vtile__meta{opacity:0}
.fbs-vtile--photo:hover .fbs-vtile__meta,.fbs-vtile--photo:focus-visible .fbs-vtile__meta{opacity:1}

/* --- video tile ground ---
   Photo tiles are the image itself, so they sit on nothing. Video tiles may
   have no poster frame yet, so they keep a panel to sit on. --- */
.fbs-mosaic--fit .fbs-vtile:not(.fbs-vtile--photo){background:#eceae3}
.fbs-mosaic--fit .fbs-vtile:not(.fbs-vtile--photo) .fbs-vtile__img{width:100%;height:100%;object-fit:cover}
.fbs-mosaic--fit video.fbs-vtile__img{width:100%;height:100%;object-fit:cover}

/* --- video tiles inside a discipline mosaic ---
   Sitting among photos, a video tile hides its caption until hover so the
   wall reads evenly. The play button stays, since it is the only cue that
   the tile is playable. --- */
.fbs-vtile--mixed .fbs-vtile__meta{opacity:0;transition:opacity .24s ease}
.fbs-vtile--mixed:hover .fbs-vtile__meta,.fbs-vtile--mixed:focus-visible .fbs-vtile__meta{opacity:1}
@media (prefers-reduced-motion:reduce){.fbs-vtile--mixed .fbs-vtile__meta{transition:none!important}}

/* --- very tall images are cropped to their top half ---
   Anything past 3x taller than wide would read as an unusable sliver in a
   masonry column. The tile keeps the top half and the fade hints there is
   more, which the lightbox then scrolls through in full. --- */
.fbs-mosaic--fit .fbs-vtile--clamped{height:auto;overflow:hidden}
.fbs-mosaic--fit .fbs-vtile--clamped .fbs-vtile__img{width:100%;height:100%;object-fit:cover;object-position:top center}
.fbs-vtile--clamped::after{content:'';position:absolute;left:0;right:0;bottom:0;height:34%;pointer-events:none;background:linear-gradient(to top,rgba(250,248,242,.92),rgba(250,248,242,0))}
.fbs-vtile--clamped .fbs-vtile__meta{z-index:2}

/* --- approach columns ---
   The three body paragraphs pick up a stray max-width from another page's
   module ordinals in the shared theme-builder stylesheet. Pinned by class so
   the ordinal rule cannot reach them. --- */
.et_pb_row.fbs-approach .et_pb_text{max-width:none}

/* --- caption reveal, one behaviour everywhere ---
   Every tile, photo or video, on the videos page or a discipline page,
   hides its caption until hover or keyboard focus. The caption also has to
   sit above the looping preview, which is appended after it in the DOM. --- */
.fbs-mosaic--fit .fbs-vtile__meta{opacity:0;transition:opacity .24s ease;z-index:3}
.fbs-mosaic--fit .fbs-vtile:hover .fbs-vtile__meta,
.fbs-mosaic--fit .fbs-vtile:focus-visible .fbs-vtile__meta{opacity:1}
.fbs-vtile__live{z-index:1}
.fbs-vtile__play{z-index:2}
@media (prefers-reduced-motion:reduce){.fbs-mosaic--fit .fbs-vtile__meta{transition:none !important}}
@media (hover:none){.fbs-mosaic--fit .fbs-vtile__meta{opacity:1}}

/* --- approach columns stack on narrow screens ---
   Divi 5 writes .et_flex_column_8_24_tablet and _phone rules that hold all
   three columns at 33.33% right down to phone width, so they never stack and
   the paragraphs squeeze into unreadable ribbons. Two classes beat Divi's
   single ordinal class on specificity, so no !important is needed. --- */
@media only screen and (max-width:980px){
  .et_pb_row.fbs-approach{--flex-direction:column;flex-direction:column}
  .et_pb_row.fbs-approach .et_pb_column{width:100%;max-width:100%;margin-bottom:30px}
  .et_pb_row.fbs-approach .et_pb_column:last-child{margin-bottom:0}
  .et_pb_row.fbs-approach .et_pb_text{max-width:540px}
}
@media only screen and (max-width:767px){
  .et_pb_row.fbs-approach .et_pb_column{margin-bottom:24px}
  .et_pb_row.fbs-approach .et_pb_text{max-width:none}
}

/* --- approach type pinned against ordinal bleed ---
   At the phone breakpoint Divi was handing .et_pb_text_4 an 8px size meant
   for a different page's module, so the first paragraph shrank while the
   other two stayed at 16px. Two classes outrank the single ordinal. --- */
.et_pb_row.fbs-approach .fbs-approach__label,
.et_pb_row.fbs-approach .fbs-approach__label p{font-family:'Press Start 2P',monospace;font-size:9px;line-height:1.9em;font-weight:400}
.et_pb_row.fbs-approach .fbs-approach__body,
.et_pb_row.fbs-approach .fbs-approach__body p{font-family:'IBM Plex Sans',sans-serif;font-size:16px;line-height:1.65em;font-weight:400}
@media only screen and (max-width:767px){
  .et_pb_row.fbs-approach .fbs-approach__label,
  .et_pb_row.fbs-approach .fbs-approach__label p{font-size:9px;line-height:1.9em}
  .et_pb_row.fbs-approach .fbs-approach__body,
  .et_pb_row.fbs-approach .fbs-approach__body p{font-size:16px;line-height:1.65em}
}

/* --- no play icon on video tiles ---
   Hidden rather than stripped from the markup, so it is one line to bring
   back. The caption and the cursor label still signal a playable tile. --- */
.fbs-vtile__play{display:none !important}
