/* ═══════════════════════════════════════════════════════════════════
   GLAMMBOX 2026 — MEDIA (Builder 2)
   Film cards + the cinematic lightbox. Page-scoped: never edit site.css.
   Depends on tokens.css only. Higgsfield-style presentation:
   the film IS the card. No chrome, no borders, no rounded-box look.
   ─────────────────────────────────────────────────────────────────── */

/* ── FILM CARD ─────────────────────────────────────────────────────
   Higgsfield / Runway grammar: the film is one rectangle of moving
   image with NOTHING on it, and the caption is a line of type UNDER
   the frame. Stamping a name and a description onto a screenshot was
   the "cheap card" — it fought the picture and never read cleanly on
   a light site capture. Zero radius; the gap does the separating. */
.gb-film{
  position:relative;display:block;
  background:none;border:0;border-radius:0;overflow:visible;
  text-decoration:none;color:inherit;cursor:pointer;
}
.gb-film-frame{
  position:relative;display:block;isolation:isolate;
  background:var(--gb-ink);overflow:hidden;border-radius:0;
  aspect-ratio:var(--film-ar,16/9);
  transform:translateZ(0);
  transition:transform var(--d-md) var(--e-out),box-shadow var(--d-md) var(--e-out);
}
.gb-film-frame::after{ /* the only "chrome": a 1px inner light, not a border */
  content:"";position:absolute;inset:0;z-index:3;pointer-events:none;
  box-shadow:inset 0 0 0 1px var(--gb-line-soft);
}
.gb-film-frame > img,
.gb-film-frame > video{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:var(--film-fit,cover);object-position:var(--film-pos,center);
  display:block;z-index:1;
}
.gb-film-frame > video{opacity:0;transition:opacity var(--d-md) var(--e-out)}
.gb-film[data-gbfilm-state="playing"] .gb-film-frame > video{opacity:1}
.gb-film[data-gbfilm-state="playing"] .gb-film-frame > img{opacity:0;transition:opacity var(--d-lg) var(--e-out)}

/* the scrim is now only the faint floor the play affordance sits on */
.gb-film-scrim{
  position:absolute;inset:0;z-index:2;pointer-events:none;
  background:linear-gradient(to top,rgba(7,8,10,.42) 0%,rgba(7,8,10,0) 38%);
  opacity:.9;transition:opacity var(--d-md) var(--e-out);
}

/* the whole frame is the play target; the label is for screen readers
   and for the keyboard, never a floating pill on the picture */
.gb-film-open{
  position:absolute;inset:0;z-index:5;
  width:100%;height:100%;
  border:0;background:transparent;padding:0;margin:0;
  font-size:0;line-height:0;color:transparent;cursor:pointer;
  overflow:hidden;white-space:nowrap;
}
.gb-film-open:focus-visible{outline:2px solid var(--gb-ember);outline-offset:-4px}

/* ── CAPTION, under the film ─────────────────────────────────────── */
.gb-film-band{
  position:static;display:block;
  padding:var(--s-3) 0 0;
}
.gb-film-band b{
  display:block;font-family:var(--f-display);
  font-size:var(--t-sm);font-weight:540;
  letter-spacing:var(--tr-head);line-height:1.2;
  color:var(--gb-bone);
}
.gb-film-band em{
  display:block;font-style:normal;
  margin-top:.28rem;min-height:2.6em;
  font-size:var(--t-xs,.82rem);line-height:1.5;
  color:var(--gb-mute);
  max-width:52ch;
  -webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden;
}
.gb-film-link{display:block;text-decoration:none;color:inherit}
/* V1 wrapped every caption in .web-card — a 1px rounded rectangle with
   padding and a wash. That IS the cheap card. Under a film the caption
   is type on the page ground, nothing else. */
.gb-film-band .web-card,
.gb-film-band .card,
.gb-film-band .gb-surface{
  background:none!important;background-image:none!important;
  border:0!important;box-shadow:none!important;border-radius:0!important;
  padding:0!important;margin:0!important;
  backdrop-filter:none!important;-webkit-backdrop-filter:none!important;
  min-height:0!important;
}
.gb-film-band .web-card > *,
.gb-film-band .card > *{padding-left:0!important;margin-left:0!important;text-indent:0!important}
.gb-film-go{
  display:inline-flex;align-items:center;gap:.4rem;
  margin-top:.5rem;
  font-family:var(--f-mono);font-size:var(--t-label);
  letter-spacing:var(--tr-label);text-transform:uppercase;
  color:var(--gb-bone-soft);
  border-bottom:1px solid var(--gb-line);
  padding-bottom:.18rem;
  transition:color var(--d-sm) var(--e-out),border-color var(--d-sm) var(--e-out),
             opacity var(--d-sm) var(--e-out),transform var(--d-sm) var(--e-out);
}
/* thirteen identical "OPEN THE SITE" lines is a list, not a gallery.
   On a pointer the invitation arrives with the pointer; on touch, where
   there is no hover to discover, it stays on. */
@media (hover:hover) and (pointer:fine){
  .gb-film-go{opacity:0;transform:translateY(5px)}
  .gb-film:hover .gb-film-go,
  .gb-film:focus-within .gb-film-go{opacity:1;transform:none}
}
.gb-film-go svg{width:.72rem;height:.72rem}
.gb-film-link:hover .gb-film-go{color:var(--gb-ember);border-color:var(--gb-ember)}
.gb-film-link:focus-visible{outline:2px solid var(--gb-ember);outline-offset:4px}
.gb-film-kicker{
  font-family:var(--f-mono);font-size:var(--t-label);
  letter-spacing:var(--tr-label);text-transform:uppercase;
  color:var(--gb-mute);
}

/* the affordance: a hairline mark that fills on hover, never a button blob */
.gb-film-mark{
  position:absolute;top:var(--s-4);right:var(--s-4);z-index:4;
  width:2.35rem;height:2.35rem;border-radius:var(--r-pill);
  display:grid;place-items:center;
  background:var(--gb-glass);backdrop-filter:blur(14px) saturate(1.3);
  -webkit-backdrop-filter:blur(14px) saturate(1.3);
  box-shadow:inset 0 0 0 1px var(--gb-line-strong);
  color:var(--gb-bone);
  opacity:0;transform:scale(.86);
  transition:opacity var(--d-sm) var(--e-out),transform var(--d-sm) var(--e-out),background var(--d-sm) var(--e-out);
}
.gb-film-mark svg{width:.95rem;height:.95rem;display:block}

@media (hover:hover) and (pointer:fine){
  .gb-film:hover .gb-film-frame{box-shadow:0 26px 60px -30px rgba(0,0,0,.9)}
  .gb-film:hover .gb-film-mark,
  .gb-film:focus-within .gb-film-mark{opacity:1;transform:none}
  .gb-film:hover .gb-film-scrim{opacity:.6}
  .gb-film:hover .gb-film-frame > img,
  .gb-film:hover .gb-film-frame > video{transform:scale(1.028);transition:transform 1.1s var(--e-out)}
  .gb-film-frame > img,.gb-film-frame > video{transition:transform 1.1s var(--e-out),opacity var(--d-md) var(--e-out)}
}
@media (hover:none){
  .gb-film-mark{opacity:1;transform:none}
}

/* ── FILM GRID ─────────────────────────────────────────────────────
   Three across at 1440, two from 760, one on a phone. 8px gutters,
   no radius: a cinema wall, not a card deck. The lead film of a
   chapter runs the full width as a establishing shot. */
.gb-film-grid{
  display:grid;gap:.5rem 8px;
  grid-template-columns:1fr;
  align-items:start;
}
/* a grid item's automatic minimum is its min-content width; a film frame
   reports the poster's intrinsic width and blows the track out to 960px
   on a phone. Every track here is allowed to be narrower than its
   content — the media is cropped by the frame, never by the layout. */
.gb-film-grid > *,.gb-film,.gb-film-frame,.gb-film-band,.gb-film-band em{min-width:0}
@media (min-width:760px){
  .gb-film-grid{grid-template-columns:repeat(2,1fr);gap:1.9rem 8px}
  .gb-film-grid > .gb-film{--film-ar:16/10}
  .gb-film-grid > .gb-film--lead{grid-column:1/-1;--film-ar:21/9}
}
/* Two across, not three. Three 430px tiles of website capture read as a
   template portfolio; two 650px ones read as film. The lead runs the
   full width as the establishing shot. */
@media (min-width:1180px){
  .gb-film-grid{grid-template-columns:repeat(2,1fr);gap:1.9rem 8px;align-content:start}
  .gb-film-grid > .gb-film{--film-ar:16/10}
  .gb-film-grid > .gb-film--lead{grid-column:1/-1;--film-ar:24/9}
  .gb-film-grid > .gb-film--wide{--film-ar:16/10}
}
/* phone: a website capture is unreadable as a 16:9 strip — 4:5 shows
   the page, exactly as Grok's direction asks. */
@media (max-width:759px){
  .gb-film-grid > .gb-film{--film-ar:16/10}
  .gb-film-grid > .gb-film--site,
  .gb-film-grid > .gb-film--site.gb-film--lead{--film-ar:4/5}
  .gb-film-grid > .gb-film--portrait{--film-ar:9/16}
}
/* portrait films keep their own composition, never cropped to a letterbox */
.gb-film--portrait{--film-ar:9/16;--film-fit:cover}
.gb-film--square{--film-ar:1/1}

/* a site capture is a tall scroll-film: show the top of the page, not
   its middle, so the visitor recognises the site they are looking at */
.gb-film--site{--film-pos:center 34%}

/* ── V1 CHROME THIS PAGE RETIRES ───────────────────────────────────
   The pink→amber reading rail is a 2024 blog pattern and the only
   saturated colour left on the page. The V2 rail (.gb-rail) is an
   ember hairline and lives in system.css. */
.room-progress{display:none!important}

/* ── LIGHTBOX ──────────────────────────────────────────────────────
   Full-screen, dark, the film at the best resolution the device can
   actually use. No layout shift: the page is frozen, not re-laid-out. */
.gb-lb{
  position:fixed;inset:0;z-index:999;
  width:100%;max-width:100%;height:100%;max-height:100%;
  margin:0;padding:0;border:0;background:transparent;
  overflow:hidden;color:var(--gb-bone);
}
.gb-lb::backdrop{background:rgba(4,5,7,.82);backdrop-filter:blur(6px)}
.gb-lb-veil{
  position:absolute;inset:0;
  background:radial-gradient(120% 90% at 50% 45%,rgba(9,10,13,.90) 0%,rgba(4,5,7,.985) 68%);
  opacity:0;transition:opacity var(--d-md) var(--e-out);
}
.gb-lb[data-open="true"] .gb-lb-veil{opacity:1}

.gb-lb-stage{
  position:absolute;inset:0;
  display:grid;place-items:center;
  padding:clamp(.5rem,3vw,3.2rem);
  padding-top:max(clamp(.5rem,3vw,3.2rem),env(safe-area-inset-top));
  padding-bottom:max(clamp(3.6rem,7vh,5rem),env(safe-area-inset-bottom));
}
.gb-lb-frame{
  position:relative;
  max-width:100%;max-height:100%;
  aspect-ratio:var(--lb-ar,16/9);
  width:min(100%,calc((100vh - 8rem) * var(--lb-arn,1.7778)));
  background:#000;
  border-radius:clamp(2px,.5vw,10px);
  overflow:hidden;
  box-shadow:0 60px 140px -40px rgba(0,0,0,.95),0 0 0 1px var(--gb-line);
  opacity:0;transform:scale(.965) translateY(12px);
  transition:opacity var(--d-md) var(--e-out),transform var(--d-lg) var(--e-out);
}
.gb-lb[data-open="true"] .gb-lb-frame{opacity:1;transform:none}
.gb-lb-frame > video{
  position:absolute;inset:0;
  width:100%;height:100%;
  object-fit:contain;background:#000;display:block;
}

/* caption + resolution disclosure sit under the frame, mono, quiet */
.gb-lb-foot{
  position:absolute;left:0;right:0;bottom:0;z-index:6;
  display:flex;align-items:baseline;gap:var(--s-4);
  flex-wrap:wrap;
  padding:var(--s-4) clamp(1rem,4vw,3.2rem);
  padding-bottom:max(var(--s-4),env(safe-area-inset-bottom));
  opacity:0;transition:opacity var(--d-md) var(--e-out) .12s;
}
.gb-lb[data-open="true"] .gb-lb-foot{opacity:1}
.gb-lb-title{
  font-family:var(--f-display);font-size:var(--t-md);font-weight:540;
  letter-spacing:var(--tr-head);color:var(--gb-bone);margin:0;
}
.gb-lb-res{
  font-family:var(--f-mono);font-size:var(--t-label);
  letter-spacing:var(--tr-label);text-transform:uppercase;
  color:var(--gb-mute);margin:0;
}

.gb-lb-close{
  position:absolute;top:max(var(--s-4),env(safe-area-inset-top));right:var(--s-4);
  z-index:8;
  width:2.9rem;height:2.9rem;min-width:44px;min-height:44px;
  display:grid;place-items:center;
  border:0;border-radius:var(--r-pill);cursor:pointer;
  background:var(--gb-glass);backdrop-filter:blur(14px);
  -webkit-backdrop-filter:blur(14px);
  box-shadow:inset 0 0 0 1px var(--gb-line-strong);
  color:var(--gb-bone);
  transition:background var(--d-sm) var(--e-out),transform var(--d-sm) var(--e-out);
}
.gb-lb-close:hover{background:rgba(239,235,227,.12);transform:rotate(90deg)}
.gb-lb-close:focus-visible{outline:2px solid var(--gb-ember);outline-offset:3px}
.gb-lb-close svg{width:1.05rem;height:1.05rem}

/* a thin ember progress hairline, the only colour in the room */
.gb-lb-bar{
  position:absolute;left:0;bottom:0;height:2px;z-index:7;
  width:100%;background:var(--gb-line-soft);
}
.gb-lb-bar > i{
  display:block;height:100%;width:0%;
  background:var(--gb-ember);transform-origin:left;
}

/* body freeze — compensates the scrollbar so nothing shifts */
html.gb-lb-open{overflow:hidden}
html.gb-lb-open body{padding-right:var(--gb-sbw,0px)}

@media (prefers-reduced-motion:reduce){
  .gb-lb-frame,.gb-lb-veil,.gb-lb-foot{transition:none!important}
  .gb-lb-frame{transform:none!important}
  .gb-film,.gb-film > img,.gb-film > video{transition:none!important;transform:none!important}
}

/* ── CARD INTERACTION SPLIT ────────────────────────────────────────
   Tapping the film opens the player (Pat's "enlarge", now at full
   resolution). The band carries the real link to the live site.
   Two targets, both one tap, no nested interactive elements. */
.gb-film-open{
  position:absolute;left:0;right:0;top:0;bottom:0;z-index:3;
  appearance:none;border:0;padding:0;margin:0;background:transparent;
  cursor:zoom-in;color:transparent;font:inherit;
}
.gb-film-open:focus-visible{outline:2px solid var(--gb-ember);outline-offset:-4px;border-radius:inherit}
.gb-film-band{pointer-events:none}
.gb-film-band a{pointer-events:auto;color:inherit;text-decoration:none;display:grid;gap:var(--s-2)}
/* No stretched overlay. The anchor is exactly its own text box, so it can
   never cover the film. Film area = open the player; band text = open the
   site. (A stretched ::after here swallowed the play button — caught by the
   browser test before it shipped.) */
.gb-film-link{position:relative;z-index:5}
.gb-film-go{
  display:inline-flex!important;align-items:center;gap:.5rem;justify-self:start;
  margin-top:var(--s-2);
  font-family:var(--f-mono);font-size:var(--t-label);
  letter-spacing:var(--tr-label);text-transform:uppercase;
  color:var(--gb-bone-soft);
  border-bottom:1px solid var(--gb-line-strong);
  padding-bottom:.28rem;
  transition:color var(--d-sm) var(--e-out),border-color var(--d-sm) var(--e-out);
  min-height:24px;
}
.gb-film-link:hover .gb-film-go{color:var(--gb-ember);border-color:var(--gb-ember)}
.gb-film-link:focus-visible{outline:2px solid var(--gb-ember);outline-offset:3px;border-radius:var(--r-sm)}
.gb-film-go svg{width:.72rem;height:.72rem}
.gb-film-mark{z-index:5;pointer-events:none}

/* ── CHAPTER HEADERS ───────────────────────────────────────────────
   Editorial openers, not a bordered box. */
.gb-chapter{
  display:grid;gap:var(--s-4);
  padding:var(--section-y) 0 var(--s-7);
  max-width:var(--measure);
}
.gb-chapter .gb-kicker{
  font-family:var(--f-mono);font-size:var(--t-label);
  letter-spacing:var(--tr-label);text-transform:uppercase;
  color:var(--gb-mute);margin:0;
  display:flex;align-items:center;gap:var(--s-3);
}
.gb-chapter .gb-kicker::before{
  content:"";width:2.2rem;height:1px;background:var(--gb-ember);flex:none;
}
.gb-chapter h1,.gb-chapter h2{
  font-family:var(--f-display);font-weight:520;
  font-size:var(--t-xxl);line-height:var(--lh-head);
  letter-spacing:var(--tr-mega);
  color:var(--gb-bone);margin:0;text-wrap:balance;
}
.gb-chapter h2{font-size:var(--t-xl)}
.gb-chapter .gb-lede{
  font-size:var(--t-md);line-height:var(--lh-body);
  color:var(--gb-bone-soft);margin:0;max-width:56ch;
  letter-spacing:var(--tr-body);
}
/* the one editorial irregularity: a serif italic clause inside the opener */
.gb-chapter em.gb-turn{font-family:var(--f-serif);font-style:italic;color:var(--gb-bone)}

/* ── THE WALL BLEEDS ───────────────────────────────────────────────
   Round B: "edge-to-edge". A gallery of films held inside the text
   column reads as a list of pictures; a wall that runs off both sides
   of the screen reads as cinema. The captions keep the page gutter so
   the type still lines up with everything else in the room. */
@media (min-width:760px){
  .gb-film-grid{
    width:100vw;max-width:100vw;
    margin-inline:calc(50% - 50vw);
    padding-inline:8px;
    gap:1.7rem 8px;
  }
  .gb-film-grid > .gb-film--lead{--film-ar:24/9}
}
@media (max-width:759px){
  .gb-film-grid{
    width:100vw;max-width:100vw;
    margin-inline:calc(50% - 50vw);
    padding-inline:0;gap:1.5rem 0;
  }
  .gb-film-grid .gb-film-band{padding-inline:var(--gutter)}
}
