/* v2 OFF+BRAND — case studies as broadcast race reports. Loaded on /work/{slug}. */
.rhero{position:relative;min-height:min(100svh,1000px);display:grid;align-content:end;overflow:hidden;isolation:isolate}
.rhero-img{position:absolute;inset:0;z-index:-2;overflow:hidden}
.rhero-img img{width:100%;height:100%;object-fit:cover;filter:grayscale(1) contrast(1.2) brightness(.5);transform:scale(1.05)}
.mo .rhero-img img{animation:zoomOut 420ms var(--out) both}   /* was 480ms, over the ≤450ms reveal budget */
@keyframes zoomOut{from{transform:scale(1.15)}to{transform:scale(1.05)}}
.rhero-scrim{position:absolute;inset:0;z-index:-1;background:linear-gradient(180deg,rgba(0,0,0,.75),rgba(0,0,0,.2) 32%,rgba(0,0,0,.35) 50%,rgba(0,0,0,.95))}
.rhero-in{padding-block:var(--sp-9) var(--sp-f-7)}
.rhero-top{display:flex;justify-content:space-between;align-items:flex-end;gap:var(--sp-4);margin-bottom:var(--sp-3)}
.r-logo{width:clamp(56px,6vw,90px);height:auto}
.r-word{font-family:var(--disp);font-style:italic;font-weight:900;font-size:28px;text-transform:uppercase}
.r-title{margin:0;font-family:var(--disp);font-style:italic;font-weight:900;font-size:clamp(64px,15vw,300px);line-height:var(--lh-mega);letter-spacing:var(--tr-mega);text-transform:uppercase;overflow-wrap:anywhere}
.r-title b{display:inline-block;font-weight:900}
.mo .r-title b{animation:slamL 260ms var(--snap) both;animation-delay:calc(var(--i,0) * 1ms)}
.mo .r-title b:nth-child(2){animation-delay:12ms}.mo .r-title b:nth-child(3){animation-delay:24ms}.mo .r-title b:nth-child(4){animation-delay:36ms}
.mo .r-title b:nth-child(5){animation-delay:48ms}.mo .r-title b:nth-child(6){animation-delay:60ms}.mo .r-title b:nth-child(n+7){animation-delay:72ms}
@keyframes slamL{0%{transform:scale(2.2) skewX(-16deg);opacity:0}35%{opacity:1}100%{transform:none;opacity:1}}
.r-lede{margin:var(--sp-4) 0 0;max-width:var(--measure-lede);font-size:clamp(19px,1.7vw,26px);line-height:1.38;color:var(--g3)}
.r-meta{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-2) var(--sp-4);margin-top:var(--sp-5);color:var(--g3)}
.r-tags{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:var(--sp-1)}
/* ── the bevel, on the case-study components ─────────────────────────────
   These eight were the whole of report.css's contribution to the square-edge
   mismatch: the sweep that chamfered the cards and panels covered site.css
   only, so the eight case studies carried chamfered buttons and .tick marks
   above square tag chips, a square SWOT, a square lap card and a square
   filmstrip frame. The PLATE itself is declared once, in site.css, and these
   selectors are named in its list — one declaration of the idiom, not a
   second copy living here.

   Two things every one of them has to respect, and both are why this file
   needed editing rather than just extending that list:

   1. report.css LOADS AFTER site.css, so a `background:` shorthand here
      overrides the plate's background-image and silently erases the edge.
      Every fill below is therefore `background-color`.
   2. A FILLED box cannot be chamfered by the plate at all. The plate's lines
      are the same colour as the fill they sit on, so they are invisible and
      the box reads as a square block among bevelled neighbours. Those take
      `clip-path`, which cuts the fill itself. It cuts the plate's lines away
      with it, which is safe for the one reason it is unsafe elsewhere: at
      that point there is no contrasting edge left to break. */
.r-tags li{padding:var(--sp-1) var(--sp-2);--pl-line:var(--g2)}
.r-tags li.em{background-color:var(--wh);color:var(--bk);--pl-line:var(--wh);clip-path:var(--bevel)}
.p-report .tele-bar{margin-top:0;border-top:0}
.p-report .chnav{margin-top:0}

/* was a raw --sp-f-10, the only section on the site not using the two shared
   section paddings even though it resolved to the same value */
.r-sec{padding-block:var(--sec-lg) 0}
.r-head{margin-bottom:var(--sp-f-7)}
.r-eb{display:flex;align-items:center;gap:var(--sp-2);margin:0 0 var(--sp-3);color:var(--g3)}
.r-eb b{display:inline-grid;place-items:center;min-width:34px;height:22px;background:var(--wh);color:var(--bk);font-weight:600}
.r-h{margin:0;max-width:19ch;font-family:var(--disp);font-style:italic;font-weight:900;font-size:clamp(44px,6.8vw,128px);line-height:var(--lh-lg);letter-spacing:var(--tr-lg);text-transform:uppercase}
.r-cols{display:grid;grid-template-columns:minmax(0,1.5fr) minmax(0,1fr);gap:var(--sp-f-8);align-items:start}
@media (max-width:900px){.r-cols{grid-template-columns:1fr}}
/* .r-body moved to site.css — the partner pages and the city pages use it
   without loading report.css, so it rendered unstyled there. */
.r-lead p:first-child{font-family:var(--disp);font-weight:700;font-size:clamp(26px,2.6vw,42px);line-height:1.02;text-transform:uppercase;color:var(--wh)}
.r-side h3{margin:0 0 var(--sp-3);color:var(--g3)}
/* .svc-del moved to site.css — /ho-chi-minh-city carries the same list and
   does not load report.css */

/* lap chart / sector splits */
.lapchart{position:relative;padding-inline:var(--g)}
/* Below 1001px the splits become a horizontal scroller (see the media query
   at the foot of this block) and nothing said so. site.js unhides the rail
   only where the container actually scrolls, so above that width — where the
   grid already shows every split — it never appears. */
.lapchart .prail-sc{margin-bottom:var(--sp-4)}
.lap-track{height:3px;background:var(--hair);position:relative;overflow:hidden}
.lap-track i{position:absolute;inset:0;background:var(--wh);transform-origin:left}
@supports (animation-timeline:view()){.mo .lap-track i{animation:fillLap linear both;animation-timeline:view();animation-range:entry 30% cover 50%}}
@keyframes fillLap{from{transform:scaleX(0)}to{transform:scaleX(1)}}
.laps{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(var(--n,6),minmax(0,1fr))}
.laps[data-n="5"]{--n:5}.laps[data-n="7"]{--n:7}
/* The lap chart had a vertical rule between every split. The diamond node and
   the outlined S-numeral already mark where each one starts. */
.lap{position:relative;display:grid;gap:var(--sp-2);align-content:start;padding:var(--sp-5) var(--sp-5) var(--sp-6) 0}
.lap+.lap{padding-left:var(--sp-5)}
.lap::before{content:"";position:absolute;left:0;top:-7px;width:11px;height:11px;background:var(--bk);border:1px solid var(--wh);transform:rotate(45deg)}
.lap+.lap::before{left:-6px}
.lap-s{font-family:var(--disp)!important;font-style:italic;font-weight:900!important;font-size:46px!important;line-height:.9;letter-spacing:0!important;color:transparent;-webkit-text-stroke:var(--stroke) var(--wh);font-variant-numeric:tabular-nums}
.lap-p{color:var(--wh)}
.lap h3{margin:0;font-family:var(--disp);font-weight:800;font-size:clamp(22px,1.8vw,30px);line-height:1;text-transform:uppercase}
.lap p{margin:0;color:var(--g3);font-size:15px}
@media (max-width:1000px){
  .lap-track{display:none}
  .laps{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;gap:var(--sp-2);padding-bottom:var(--sp-2)}
  /* The lap card draws NO edge above this breakpoint — the diamond node and
     the outlined numeral mark each split instead — so the plate is switched
     off by its own colour tokens in site.css and switched back on here,
     rather than the 14-line declaration being duplicated inside this query. */
  .lap,.lap+.lap{flex:0 0 min(78vw,320px);padding:var(--sp-4);--pl-line:var(--g1);--pl-hi:var(--wh);scroll-snap-align:start}
  .lap::before,.lap+.lap::before{display:none}
}

/* brand & marketing / CMO */
.bm-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr))}
.bm{display:grid;gap:var(--sp-3);align-content:start;padding:var(--sp-5);color:var(--g3)}
/* column dividers removed; the grid gap separates the three panels */
.bm h3{margin:0;color:var(--wh);font-family:var(--disp);font-style:italic;font-weight:900;font-size:clamp(28px,2.6vw,42px);line-height:.92;text-transform:uppercase}
.bm p{margin:0}
@media (max-width:900px){.bm-grid{grid-template-columns:1fr;gap:var(--sp-5)}}
.cmo{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,3fr);gap:var(--sp-5);margin-top:var(--sp-f-8)}
.cmo-q p{margin:0;font-family:var(--disp);font-weight:700;font-size:clamp(24px,2.3vw,38px);line-height:1.1;text-transform:uppercase;max-width:44ch}
@media (max-width:900px){.cmo{grid-template-columns:1fr}}

/* engagement readout */
.readout{display:grid;gap:var(--sp-2);align-content:start;padding:var(--sp-f-6)}
.readout b{font-family:var(--disp);font-style:italic;font-weight:900;font-size:clamp(64px,9vw,170px);line-height:var(--lh-lg);letter-spacing:var(--tr-lg);text-transform:uppercase;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
#summary .r-cols{grid-template-columns:minmax(0,1fr) minmax(0,1.4fr)}
@media (max-width:900px){#summary .r-cols{grid-template-columns:1fr}}

/* CMO analysis points */
.pts{list-style:none;margin:0;padding:0;display:grid;gap:var(--sp-5)}
.pts li{display:grid;grid-template-columns:clamp(70px,9vw,140px) minmax(0,1fr);gap:var(--sp-5);padding:var(--sp-5) 0;color:var(--g3)}
.pt-n{font-family:var(--disp);font-style:italic;font-weight:900;font-size:clamp(56px,6vw,110px);line-height:.8;letter-spacing:var(--tr-lg);color:transparent;-webkit-text-stroke:var(--stroke) var(--wh);font-variant-numeric:tabular-nums}
.pts h3{margin:0 0 var(--sp-3);max-width:30ch;color:var(--wh);font-family:var(--disp);font-weight:800;font-size:clamp(24px,2.2vw,36px);line-height:1.06;letter-spacing:var(--tr-sm);text-transform:uppercase}
.pts p{margin:0;max-width:var(--measure)}

/* marketing execution */
.c-three{display:grid;grid-template-columns:repeat(3,minmax(0,1fr))}
.c-three>div{padding:var(--sp-5)}
/* column dividers removed; the grid gap separates the three columns */
.c-three h3{margin:var(--sp-1) 0 var(--sp-4);font-family:var(--disp);font-style:italic;font-weight:900;font-size:clamp(30px,2.8vw,44px);line-height:.9;text-transform:uppercase}
.c-three ul{margin:0;padding:0;list-style:none;display:grid;gap:var(--sp-2);color:var(--g3)}
.c-three li{display:grid;grid-template-columns:18px 1fr}
.c-three li::before{content:"+";color:var(--g2)}
@media (max-width:900px){.c-three{grid-template-columns:1fr;gap:var(--sp-5)}}

/* SWOT 2×2 HUD */
.swot{position:relative;display:grid;grid-template-columns:repeat(2,minmax(0,1fr))}
.swot::before,.swot::after{content:"";position:absolute;background:var(--wh);pointer-events:none}
.swot::before{left:50%;top:50%;width:26px;height:1px;translate:-50% -50%}
.swot::after{left:50%;top:50%;width:1px;height:26px;translate:-50% -50%}
.sw{position:relative;display:grid;gap:var(--sp-3);align-content:start;padding:var(--sp-f-7);overflow:hidden;isolation:isolate;color:var(--g3)}
/* The 2×2 keeps its outer plate and its crosshair — that mark IS the quadrant
   reading — but loses the internal rules that doubled it. */
.sw-l{position:absolute;right:10px;bottom:-40px;z-index:-1;font-family:var(--disp);font-style:italic;font-weight:900;font-size:clamp(160px,18vw,280px);line-height:1;letter-spacing:var(--tr-mega);color:transparent;-webkit-text-stroke:var(--stroke-fine) var(--deco-stroke)}
.sw h3{margin:0;color:var(--wh);font-family:var(--disp);font-style:italic;font-weight:900;font-size:clamp(30px,3vw,50px);line-height:.92;text-transform:uppercase}
.sw ul{margin:0;padding:0;list-style:none;display:grid;gap:var(--sp-2);max-width:46ch}
.sw li{display:grid;grid-template-columns:18px 1fr}
.sw li::before{content:"—";color:var(--g2)}
@media (max-width:760px){.swot{grid-template-columns:1fr;gap:var(--sp-5)}.swot::before,.swot::after{display:none}}

/* founder quote — moved to site.css; the seven partner pages that carry a
   testimonial use the same component and do not load report.css */

/* the build: stage progress rail */
.rail{position:relative;list-style:none;margin:0;padding:0 0 0 var(--sp-f-10)}
.rail-line{position:absolute;left:clamp(26px,3.4vw,50px);top:10px;bottom:10px;width:3px;background:var(--hair)}
.rail-line i{position:absolute;inset:0;background:var(--wh);transform-origin:top;transform:scaleY(var(--p,1))}
.mo .rail-line i{transform:scaleY(var(--p,0))}
.rail-s{position:relative;padding:0 0 var(--sp-f-8)}
.rail-n{position:absolute;left:calc(clamp(70px,9vw,130px) * -1 + clamp(26px,3.4vw,50px) - 27px);top:0;display:grid;place-items:center;width:57px;height:57px;background-color:var(--bk);--pl-line:var(--g2);font-family:var(--disp);font-style:italic;font-weight:900;font-size:26px;font-variant-numeric:tabular-nums;transition:background-color var(--t-med),color var(--t-med)}
/* Filled in BOTH states — black at rest, white once reached — so this is one
   of the clip-path cases: the plate would be drawing white lines onto a white
   fill. Note the second selector: under reduced motion every numeral is
   filled, so the chamfer has to come from the same rule rather than from the
   scroll-driven .on class, or the whole rail is square for those readers. */
.rail-s.on .rail-n,html:not(.mo) .rail-n{background-color:var(--wh);color:var(--bk);--pl-line:var(--wh);clip-path:var(--bevel)}
.rail-c{max-width:var(--measure);color:var(--g3)}
.rail-c>.hud{margin:0 0 var(--sp-1);color:var(--wh)}
.rail-c h3{margin:0 0 var(--sp-3);color:var(--wh);font-family:var(--disp);font-style:italic;font-weight:900;font-size:clamp(30px,3.2vw,54px);line-height:.9;text-transform:uppercase}
.rail-c p{margin:0 0 var(--sp-3)}
.rail-o{display:inline-block;margin-top:var(--sp-1)!important;padding:var(--sp-1) var(--sp-2);color:var(--wh)}

/* partners table */
.ptable .pn{color:var(--wh);font-weight:600}
/* .ptable a takes the shared prose-link affordance from site.css (brighter ink,
   inverting to a filled chip on hover). It previously re-declared an underline
   here, and report.css loads after site.css, so it would have won. */

/* gallery filmstrip */
/* The control row holds two different things and they are not the same thing:
   the rail says WHERE YOU ARE, the hint says HOW TO MOVE. The hint was all
   there was, which is why nothing told a reader the strip ran past the edge. */
.film-ctl{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;
  gap:var(--sp-2) var(--sp-5);margin-bottom:var(--sp-3);color:var(--g3)}
.film-ctl .prail-sc{flex:1 1 280px;max-width:560px;margin-bottom:0}
.film-hint{flex:0 0 auto}
/* A ground behind the filmstrip, DAY ONLY (Bailey, 2026-09-23). `.frame figure`
   is a clip-path tile and deliberately carries no border -- a clip cuts a
   border away along the diagonal, which is the trap the whole bevel idiom
   exists around -- so on the night site a bright gallery photo has a crisp edge
   against black and on the day site it dissolves into the page. The fix is a
   band for the photos to sit on rather than an edge on each photo, which would
   contradict the bevel rule. --g0 is the softest step on the day palette and
   reads as a tray, not a panel. Full-bleed: .filmstrip is the scroller, so the
   band is painted on the section around it and cannot clip the scroll. */
/* #gallery, not a class: the filmstrip's section is `<section class="r-sec"
   id="gallery">` and .r-sec is shared by every chapter on the page. */
html[data-theme="day"] #gallery{background-color:var(--g0)}
.filmstrip{list-style:none;margin:0;padding:0 var(--g) var(--sp-4);display:flex;gap:var(--sp-2);overflow-x:auto;scroll-snap-type:x proximity;scroll-padding-inline:var(--g);cursor:grab;overscroll-behavior-x:contain}
.filmstrip.drag{cursor:grabbing;scroll-snap-type:none}
.filmstrip.drag img{pointer-events:none}
.frame{flex:0 0 auto;scroll-snap-align:start}
/* A photo tile, so it takes the clip-path rather than the plate: the image is
   the interior, and a clip cuts the media with the box. The border goes rather
   than being kept and left broken on the two diagonals. The caption is safe at
   left/top — the chamfers are top-RIGHT and bottom-LEFT. */
.frame figure{position:relative;margin:0;height:clamp(300px,58vh,620px);clip-path:var(--bevel);overflow:hidden}
.frame img{height:100%;width:auto;max-width:none;object-fit:cover;filter:grayscale(1) contrast(1.15);transition:filter var(--t-med)}
.frame:hover img{filter:grayscale(1) contrast(1.15) brightness(1.1)}
.frame figcaption{position:absolute;left:10px;top:10px;padding:var(--sp-1) var(--sp-2);background:var(--bk)}
@media (max-width:560px){.frame figure{height:52vh}}

.r-links{margin-top:var(--sec-lg)}
.r-links>.hud{margin:0 0 var(--sp-3)}
.p-report .close{margin-top:0}
