/* ============================================================================
   Lumen — override tampilan OHIF Viewer (image resmi ohif/app, TIDAK di-fork
   atau dibangun ulang dari sumber). File ini disuntik lewat nginx sub_filter
   di deploy/nginx/viewer.conf (<link> ditambah sebelum </head> pada respons
   index.html), jadi upgrade OHIF_VERSION cukup pull image baru -- tidak
   butuh proses build terpisah untuk viewer.

   OHIF tidak menyediakan nama kelas semantik atau data-attribute untuk
   elemen di bawah, jadi target-nya lewat kombinasi kelas utility Tailwind
   OHIF sendiri. PENTING: kombinasi kelas ini bisa berubah kalau
   OHIF_VERSION naik dan komponennya di-refactor upstream. Kalau override
   di bawah berhenti berlaku setelah upgrade versi, cek ulang lewat DevTools
   pada elemen yang bersangkutan, lalu bandingkan dengan backup CSS asli di
   deploy/ohif/backup-css-original/ (lihat README di folder itu).
   ========================================================================= */

/* --- 1. Peringatan "investigational use only" -- dibikin lebih soft ---
   Warna aslinya pakai token --popover (hsl 219 90% 15%, biru jenuh) di atas
   background hitam pekat -- kontras tinggi, kesannya alert/urgent padahal
   isinya cuma disclaimer standar. Diganti ke token --muted (permukaan
   redup yang sudah dipakai OHIF sendiri untuk elemen kurang menonjol),
   border ditipiskan & dijernihkan, shadow dilembutkan. Lebar 90% layar
   terasa terlalu dominan, jadi dipersempit dan dipindah ke pojok kanan
   bawah supaya tidak menghalangi citra yang sedang dilihat. */
div[class~="fixed"][class~="bottom-2"][class~="justify-center"]{
  justify-content:flex-end !important;
  padding-right:16px;
}
div[class~="bg-popover"][class~="border-muted"][class~="shadow-lg"]{
  width:auto !important;
  max-width:400px;
  background:hsl(var(--muted) / .96) !important;
  border-color:hsl(0 0% 100% / .08) !important;
  border-width:1px !important;
  box-shadow:0 4px 20px rgba(0,0,0,.4) !important;
}

/* Judul disclaimer aslinya text-[19px] -- kepanjangan, bikin kartu jadi
   3 baris dan lebih dominan dari yang perlu. Dikecilkan, dan ikonnya
   (SVG 68x68 bawaan) ikut dikecilkan proporsional. */
div[class~="bg-popover"][class~="border-muted"][class~="shadow-lg"] div[class~="text-foreground"][class~="text-[19px]"]{
  font-size:13px !important;
  line-height:1.35;
}
div[class~="bg-popover"][class~="border-muted"][class~="shadow-lg"] svg{
  width:36px !important;
  height:36px !important;
}
div[class~="bg-popover"][class~="border-muted"][class~="shadow-lg"] a{
  font-size:12px !important;
}
div[class~="bg-popover"][class~="border-muted"][class~="shadow-lg"] > button{
  font-size:13px !important;
}

/* --- 2. Rapikan di layar sempit (mobile) --- */
@media (max-width:640px){
  /* Tinggi wrapper luar di-hardcode 86px oleh OHIF. Di layar sempit teks
     disclaimer di atas bisa perlu 3-4 baris dan bertabrakan dengan tombol
     "Confirm and hide" (terverifikasi lewat screenshot mobile viewport).
     Disusun ulang jadi kolom & tinggi mengikuti isi. */
  div[class~="fixed"][class~="bottom-2"][class~="justify-center"]{
    height:auto !important;
    justify-content:center !important;
    padding-right:0;
  }
  div[class~="bg-popover"][class~="border-muted"][class~="shadow-lg"]{
    flex-direction:column !important;
    align-items:flex-start !important;
    gap:10px;
    width:92vw !important;
    max-width:92vw;
  }
  div[class~="bg-popover"][class~="border-muted"][class~="shadow-lg"] > button{
    align-self:flex-end;
  }

  /* Wordmark "Lumen" custom kita (lihat whiteLabeling.createLogoComponentFn
     di app-config.js) bertabrakan dengan ikon toolbar di layar sempit --
     disembunyikan; di layar sekecil ini ikon lebih penting dipakai
     daripada logo. */
  .lumen-wordmark{ display:none !important; }
}

/* --- 3. Font Lumen -- disamakan dengan frontend/public/css/lumen.css (--font) ---
   OHIF default pakai font sistem/Inter bawaan Tailwind. body diberi !important
   supaya menang dari aturan Tailwind yang biasanya juga men-set font-family di
   elemen yang sama (bukan cuma di elemen anak yang lebih spesifik). */
body{
  font-family:'Segoe UI','Source Sans 3',Tahoma,Geneva,Verdana,sans-serif !important;
}

/* --- 4. Recolor aksen ke palet Lumen (cobalt #0050EF -> HSL 220 100% 47%) ---
   TIDAK mengubah bentuk ikon (itu perlu fork+build ulang OHIF, sengaja
   dihindari -- lihat header file ini). Cuma menimpa token warna CSS yang
   SUDAH dipakai OHIF sendiri untuk elemen aktif/terpilih/interaktif
   (ikon toolbar yang lagi aktif, dsb pakai fill:currentColor mengikuti
   token ini). :root di sini menang atas :root bawaan OHIF karena
   stylesheet ini disuntik PALING TERAKHIR sebelum </head> (lihat
   sub_filter di deploy/nginx/viewer.conf) -- spesifisitas sama, urutan
   menentukan. Kalau warnanya kurang pas / merusak kontras di suatu
   elemen, ini yang pertama dicek & disesuaikan.
   BELUM diverifikasi visual (butuh login OIDC) -- cek langsung setelah
   deploy sebelum dianggap final. */
:root, .dark{
  /* --- Palet "Lumen Clinical Dark" (brief user 2026-09-11) ---
     Di-convert dari hex ke HSL (format token OHIF: "H S% L%", dipakai
     lewat hsl(var(--x))) pakai colorsys Python, bukan tebak manual.
     Target DUA selector (:root DAN .dark) -- pelajaran dari perbaikan
     --primary sebelumnya: OHIF definisikan token yang SAMA di keduanya,
     literal di elemen (bukan diwariskan), jadi override :root SENDIRIAN
     kalah kalau elemen sungguhan pakai class .dark. */

  --background:210 30% 4%;         /* Main canvas #070A0D */
  --foreground:200 37% 97%;        /* Primary text #F4F8FA */

  --card:206 28% 11%;              /* Panel #151E25 */
  --card-foreground:200 37% 97%;

  --popover:205 27% 14%;           /* Elevated surface #1A252D (dropdown/dialog/disclaimer) */
  --popover-foreground:200 37% 97%;

  --primary:185 100% 45%;          /* Primary cyan #00D5E8 */
  --primary-foreground:210 30% 4%; /* teks gelap di atas tombol cyan terang -- kontras lebih baik drpd putih */

  --secondary:206 28% 11%;         /* Panel, dipakai ulang */
  --secondary-foreground:200 37% 97%;

  --muted:206 28% 11%;             /* Panel */
  --muted-foreground:202 16% 66%;  /* Secondary text #9BACB6 */

  --accent:188 83% 14%;            /* Active background #063941 -- hover/selected item */
  --accent-foreground:185 100% 45%;/* teks/ikon cyan di atas active background */

  --border:207 22% 19%;            /* Divider #26323C */
  --input:207 22% 19%;
  --ring:185 100% 45%;             /* Focus ring cyan */
  --highlight:185 100% 45%;

  /* Bukan token standar OHIF -- disiapkan untuk dipakai manual kalau perlu
     nuansa lebih (mis. teks tersier paling redup, indikator warning). */
  --lumen-muted-text:204 11% 50%;  /* Muted text #71818C */
  --lumen-warning:32 100% 50%;     /* Warning orange #FF8600 */

  /* Corner radius: default OHIF 0.5rem (8px), spec minta 4-6px --
     --radius satu-satunya token dipakai (dikonfirmasi lewat cek langsung
     app.bundle.css), rounded-sm/md/lg semuanya di-calc() dari sini. */
  --radius:0.375rem;
}

/* --- 5. Sembunyikan ikon+link GitHub OHIF di About modal ---
   Disembunyikan (bukan diubah teksnya, lihat catatan di gantiTeksOhif
   app-config.js) atas permintaan user. Struktur asli (AboutModal.tsx
   SocialItem): <div class="flex items-center"><div class="inline-block">
   <svg GitHub></div><Button><a href="https://github.com/OHIF/Viewers">
   ...</a></Button></div> -- ikonnya SAUDARA div terpisah SEBELUM <a>,
   BUKAN di dalamnya, jadi menyembunyikan <a> saja (percobaan pertama)
   menyisakan ikon tetap tampil. :has() dipakai untuk menyasar div
   PEMBUNGKUS keduanya sekaligus lewat keberadaan link itu di dalamnya --
   lebih tahan banting daripada nama class Tailwind yang bisa berubah
   antar build. */
div:has(> a[href*="github.com/OHIF"]){ display:none !important; }
/* CATATAN: sengaja HANYA versi child langsung (">") -- versi tanpa ">"
   akan cocok ke SEMUA div leluhur (termasuk pembungkus modal itu sendiri)
   dan menyembunyikan seluruh About modal, bukan cuma barisnya. Kalau
   Button asChild (Radix Slot) di source berubah render-nya suatu saat
   sehingga <a> tidak lagi anak langsung, selector ini perlu diperiksa
   ulang -- BUKAN diperlebar jadi tanpa ">". */

/* --- 6. Toolbar rata kiri, bukan center (alternatif aman dari rail vertikal) ---
   Rail vertikal (toolbar dipindah ke sisi kiri viewport, setelah Study
   Navigator) BUTUH restrukturisasi pohon komponen React -- Toolbar
   dirender sebagai children <Header> (ViewerHeader.tsx), yang notabene
   SAUDARA terpisah DI ATAS ResizablePanelGroup (Left Panel-Viewport-Right
   Panel), BUKAN bagian darinya. Memindah lewat CSS position:fixed/absolute
   berisiko merusak dropdown/tooltip toolbar yang menghitung posisi dari
   lokasi asli di DOM. Alternatif aman: tetap di header, rata kiri.

   Selector persis dari source (ViewerHeader.tsx): wrapper toolbar primer
   punya class "relative flex justify-center gap-[4px]" -- dikombinasikan
   supaya HANYA wrapper ini yang kena, bukan .justify-center lain di
   seluruh app. */
.relative.flex.justify-center.gap-\[4px\]{
  justify-content:flex-start !important;
}

/* --- 7. Panel kiri: judul "STUDY NAVIGATOR" & accent bar studi terpilih ---
   Judul asli "Studies" adalah i18next key (SidePanel:Studies,
   getPanelModule.tsx) -- diganti lewat DOM-patch teks di app-config.js
   (gantiStudiesJadiNavigator), bukan CSS, karena teksnya utuh bukan
   dirakit dari beberapa node seperti kasus "OHIF" sebelumnya.

   Accent bar: struktur asli (Thumbnail.tsx) TIDAK punya bar aksen di sisi
   kiri kartu -- yang ada cuma badge modality kecil 10x10px pojok kiri
   bawah (jadi cyan juga saat aktif lewat bg-highlight, sudah otomatis
   ikut palet baru). Bar aksen kiri card yang diminta ditambahkan manual
   lewat border-left pada kombinasi class PERSIS yang cuma muncul saat
   kartu thumbnail aktif (isActive && 'bg-popover rounded' pada wrapper
   'flex h-full w-full flex-col items-center justify-center gap-[2px]
   p-[4px]') -- kombinasi 10 class sekaligus, sangat kecil kemungkinan
   collision dengan elemen lain. BELUM diverifikasi visual. */
.flex.h-full.w-full.flex-col.items-center.justify-center.gap-\[2px\].p-\[4px\].bg-popover.rounded{
  border-left:4px solid hsl(var(--primary));
  border-top-left-radius:0;
  border-bottom-left-radius:0;
}

/* --- 8. Konsolidasi info overlay viewport jadi satu area bawah ---
   Selector STABIL data-cy (ViewportOverlay.tsx, platform/ui-next) --
   lebih tahan banting antar versi OHIF dibanding nama class Tailwind.
   Default: topLeft (tanggal+deskripsi seri) di ATAS, bottomLeft (W/L) +
   bottomRight (instance) di BAWAH -- diminta jadi satu area bawah saja.
   topLeft dipindah ke bawah, disusun di kiri SEBELUM bottomLeft (jarak
   left diberi ruang) supaya tidak tumpang tindih. BELUM diverifikasi
   visual -- jarak/offset di bawah ini estimasi, kemungkinan perlu
   disesuaikan setelah dilihat langsung. */
[data-cy="viewport-overlay-top-left"]{
  /* KOREKSI: left:0.5rem semula tumpang tindih dengan ikon status
     ViewportActionCorners.bottomLeft -- sistem TERPISAH dari overlay teks
     ini (platform/ui-next/src/components/Viewport/ViewportActionCorners.tsx),
     posisinya PERSIS "bottom-[3px] left-[0px] pl-[4px]", nyaris sama
     persis dengan posisi overlay ini sebelum dikoreksi. Digeser lebih ke
     kanan (2rem) supaya lewat ikon itu, bukan menimpanya. */
  top:auto !important;
  bottom:0.6rem !important;
  left:2rem !important;
}
[data-cy="viewport-overlay-bottom-left"]{
  bottom:0.6rem !important;
  left:12.5rem !important;
}
[data-cy="viewport-overlay-bottom-right"]{
  bottom:0.6rem !important;
}
/* Pita latar belakang status bar SENGAJA DITUNDA -- posisi z-index yang
   benar (di belakang teks, di depan citra) butuh tahu stacking context
   nyata dari canvas cornerstone yang tidak bisa dipastikan tanpa lihat
   langsung. Reposisi teks di atas sudah jalan duluan; pita latar
   menyusul setelah reposisi ini diverifikasi. */

/* --- 9. Thumbnail Study Navigator lebih besar ---
   Ukuran asli hardcode 114x128px di 3 tempat (Thumbnail.tsx: div
   pembungkus, <img> sendiri, div fallback placeholder) -- SEMUANYA pakai
   kombinasi class PERSIS "h-[114px] w-[128px]", jadi satu selector
   kombinasi menimpa ketiganya sekaligus (kontainer, gambar, dan
   placeholder ikut membesar proporsional, bukan cuma satu doang yang
   besar sementara yang lain masih ukuran lama). Rasio asli 128:114 (~1.12)
   dipertahankan -- 180x160px (naik ~40%). object-contain pada <img> tetap
   berlaku, jadi citra thumbnail tidak gepeng. */
/* KOREKSI setelah lihat DOM inspector sungguhan (user, Firefox devtools):
   versi OHIF yang JALAN pakai class BERBEDA dari yang ditemukan di source
   GitHub v3.13.6 (h-[114px] w-[128px]) -- kartu thumbnail sungguhan
   pakai h-[170px] w-[135px] di WRAPPER KARTU itu sendiri (bukan di <img>
   nested). Pelajaran: source GitHub adalah PANDUAN, bukan kebenaran
   mutlak -- versi image yang di-build/dipublikasikan bisa beda revisi
   kecil. Rasio asli 135:170 (~1.26) dipertahankan -- 175x220px. */
.h-\[170px\].w-\[135px\]{
  height:170px !important;
  width:197px !important;
}
/* KOREKSI LAGI: ternyata ADA DUA level ukuran hardcode, bukan cuma satu.
   h-[170px]/w-[135px] di atas itu KARTU LUAR (sudah benar kena, dikonfirmasi
   inspector: "Final Size: 175px"). TAPI di dalamnya, kotak gambar sendiri
   pakai class TERPISAH h-[114px]/w-[128px] (dikonfirmasi lewat inspect
   Anda: <div class="h-[114px] w-[128px]"><img class="h-[114px] w-[128px]
   ...">) -- rule ini sempat saya HAPUS di percobaan sebelumnya karena
   dikira salah target, padahal harusnya DIPERTAHANKAN BERSAMA rule kartu
   luar, bukan gantikan. Diskalakan proporsional dgn faktor pembesaran
   kartu luar (~1.295x): 128->166, 114->148. Kena 3 tempat sekaligus
   (kontainer gambar, <img>, fallback placeholder -- ketiganya pakai
   kombinasi class yang sama persis di source). */
.h-\[114px\].w-\[128px\]{
  height:114px !important;
  width:187px !important;
}
/* KOREKSI: percobaan pertama (timpa grid-template-columns lewat selector
   4-class gabungan) TIDAK berhasil -- diverifikasi user masih terpotong
   sama persis. Ganti pendekatan: daripada tebak ulang nilai px yang di-
   escape dalam selector (rawan meleset lagi), kontainernya diubah dari
   CSS Grid ke Flexbox yang wrapping -- itu MENGHILANGKAN konsep "lebar
   sel tetap" sama sekali, jadi tidak perlu cocok persis dengan
   grid-template-columns aslinya. Ditarget lewat kombinasi 2 class
   (.grid.place-items-start) yang dikonfirmasi cuma dipakai bareng di 2
   tempat di source (ThumbnailList.tsx untuk panel ini, PreviewContent.tsx
   untuk halaman WorkList terpisah -- tidak pernah tampil bersamaan). */
.grid.place-items-start{
  display:flex !important;
  flex-wrap:wrap !important;
}

/* --- 10. Lebar default panel kiri (Study Navigator) diperkecil ---
   Default 282px (leftPanelInitialExpandedWidth, extensions/default/src/
   ViewerLayout/constants/panels.ts) di-hardcode di kode mode, BUKAN
   customization resmi -- tidak bisa diubah lewat config/app-config.js.
   Diakali lewat CSS !important menimpa inline style min/maxWidth yang
   dipasang JS (react-resizable-panels, lihat setMinMaxWidth() di
   ResizablePanelsHook.tsx) -- !important CSS class MENANG atas inline
   style biasa. Ditarget lewat [data-panel-id] (atribut yang dipasang
   react-resizable-panels sendiri untuk lookup DOM via getPanelElement()),
   id panelnya "viewerLayoutResizableLeftPanel" persis dari source.
   200px dipilih supaya pas dengan thumbnail baru (175px + padding kartu)
   tanpa banyak sisa kosong. BELUM diverifikasi visual -- kalau
   react-resizable-panels TERNYATA pakai atribut lain (bukan
   data-panel-id), selector ini perlu dicek ulang lewat inspector. */
[data-panel-id="viewerLayoutResizableLeftPanel"]{
  width:200px !important;
  min-width:200px !important;
  max-width:200px !important;
}

/* --- 11. Sembunyikan "Learn more about Lumen Viewer" di popover disclaimer ---
   Struktur asli (InvestigationalUseDialog.tsx): baris ini <span
   onClick={() => window.open('https://ohif.org/')}> dibungkus <div
   className="text-foreground text-[13px]"> TERPISAH dari baris utama
   "...investigational use only" (yang pakai text-[19px]). Disembunyikan
   lewat parent-scoped selector (dibatasi HANYA di dalam popover
   disclaimer yang sudah kita kenali -- div.bg-popover.border-muted.
   shadow-lg -- supaya .text-\[13px\] tidak sengaja kena elemen lain di
   halaman yang kebetulan pakai ukuran teks sama). */
div.bg-popover.border-muted.shadow-lg .text-\[13px\]{
  display:none !important;
}

/* --- 12. Perbaiki teks tooltip nyaris tak terbaca (hitam di atas gelap) ---
   Komponen Tooltip bawaan OHIF (platform/ui-next/src/components/Tooltip/
   Tooltip.tsx) memasangkan `text-primary-foreground` dengan latar
   `bg-muted` -- pasangan token yang salah dari sumbernya sendiri (baru
   ketahuan sekarang karena override #4 di atas SENGAJA menggelapkan
   --primary-foreground supaya teks tombol cyan terang kontrasnya bagus;
   Tooltip.tsx lalu ikut memakai token yang sama untuk konteks yang
   berbeda -- teks di atas latar gelap `muted`, bukan di atas tombol cyan
   terang -- sehingga nyaris tak kelihatan, hampir hitam di atas hitam).
   Berlaku untuk SEMUA tooltip hover di viewer, bukan cuma toolbar
   MPR/MIP/MinIP/3D. Diperbaiki dengan dipasangkan ke `--muted-foreground`
   (token yang memang didesain terang, utk dibaca di atas latar `muted`)
   -- TIDAK mengubah token --primary-foreground itu sendiri (supaya
   kontras teks tombol cyan tetap seperti semula), cukup timpa warna
   tooltip-nya saja lewat selector spesifik struktur Radix Tooltip. */
[data-radix-popper-content-wrapper] [data-side]{
  color:hsl(var(--muted-foreground)) !important;
}

/* --- 13. Viewer kepotong di bawah saat dibuka di tablet ---
   Dilaporkan 14 Sep 2026: di tablet, lebar aman tapi bagian bawah viewer
   (toolbar/gambar) terpotong, tidak ada scroll ke sana sama sekali.

   Root cause: OHIF mengukur tinggi elemen utamanya pakai class Tailwind
   `.h-screen` (height:100vh) dan turunan `h-full` yang berujung ke situ.
   Di Chrome desktop 100vh selalu = tinggi viewport penuh, jadi selalu
   pas. Di Safari/Chrome TABLET, 100vh dihitung dari tinggi viewport
   TERBESAR (seolah address bar/toolbar browser sedang tersembunyi) --
   sedangkan area yang benar-benar terlihat lebih pendek karena toolbar
   itu MASIH ada. Bagian bawah elemen jadi ke-render di luar area
   terlihat, dan karena body di-set overflow:hidden (viewer didesain
   sbg app satu-layar, sengaja tidak bisa page-scroll), tidak ada jalan
   sampai ke sana.

   Fix: unit CSS modern `dvh` (dynamic viewport height) -- otomatis
   menyesuaikan tinggi toolbar browser yang benar-benar terlihat, bukan
   viewport maksimal teoretis. Dipasang SETELAH deklarasi vh (bukan
   menggantikannya) supaya browser lama yang belum kenal `dvh` tetap
   pakai vh sebagai fallback (aturan CSS terakhir yang dikenali browser
   yang menang).

   TERBUKTI TIDAK CUKUP SENDIRIAN (uji lewat tablet asli 14 Sep 2026 --
   panel coronal/sagittal di bawah tetap kepotong): dvh mengurangi
   selisihnya tapi tidak menjamin PAS di semua tablet/browser.

   Percobaan KEDUA yang GAGAL LEBIH PARAH (baru diketahui lewat verifikasi
   emulator SEBELUM sempat sampai ke tablet -- lihat diskusi, jangan
   diulang): memaksa `#root, #root > *{height:auto}` supaya body bisa
   "mengembang" mengikuti konten. Ternyata layout grid viewport Cornerstone
   BERGANTUNG pada rantai tinggi definitif (bukan auto) dari #root ke
   bawah utk menghitung ukuran piksel kanvas gambar via ResizeObserver --
   begitu salah satu leluhurnya jadi height:auto, seluruh viewport
   RUNTUH ke tinggi 0 dan HALAMAN JADI KOSONG TOTAL (bukan cuma
   kepotong, malah tidak render apa-apa). #root DAN turunannya TIDAK
   BOLEH disentuh height/min-height-nya sama sekali.

   Fix yang benar (tahap 1): JANGAN ubah rantai tinggi #root ke bawah
   (biarkan OHIF mengatur ukuran kanvasnya sendiri lewat dvh di atas).
   Cuma izinkan `overflow-y:auto` pada html/body TANPA memaksa height
   apa pun di situ -- kalau tinggi konten (hasil dvh) kebetulan masih
   lebih tinggi dari viewport yang benar-benar terlihat, body/html yang
   overflow BUKAN #root, jadi aman di-scroll tanpa mengganggu
   perhitungan ukuran kanvas. Berlaku universal (tidak dibatasi
   tablet) -- aman di desktop krn overflow-y:auto tidak berbuat apa-apa
   selama konten tidak melebihi tinggi layar.

   TAHAP 1 MASIH TIDAK CUKUP (uji tablet asli lagi, 14 Sep 2026): `.h-
   screen` TERNYATA TIDAK PERNAH DIPAKAI SAMA SEKALI di route viewer ini
   (dicek langsung: querySelectorAll('.h-screen') kosong) -- rule itu
   selama ini TIDAK BERBUAT APA-APA di halaman yang bermasalah, salah
   sasaran dari awal. Elemen yang SEBENARNYA menentukan tinggi baris
   konten (pembungkus panel kiri + grid viewport + panel kanan, di
   BAWAH header) ternyata diset lewat INLINE STYLE dari JS OHIF sendiri:
   style="height: calc(-52px + 100vh)" pada
   div.relative.flex.w-full.flex-row.flex-nowrap.items-stretch.overflow-hidden.bg-background
   -- 52px = tinggi header (h-[48px] + border), 100vh = sumber masalah
   yang sama (vh vs dvh), TAPI di-set inline, jadi class .h-screen tidak
   relevan di sini. Elemen ini JUGA punya overflow-hidden SENDIRI, jadi
   kalau 100vh > tinggi yang benar-benar terlihat, baris ini memotong
   ISINYA SENDIRI (grid viewport) -- ini yang bikin gejala "scroll ada,
   tapi cuma di section gambar 2x2" (overflow html/body dari tahap 1
   menggeser baris yang SUDAH kepotong ini, bukan mencegahnya kepotong).

   Override lewat CSS eksternal + !important -- SATU-SATUNYA cara CSS
   biasa menang atas inline style, dan tetap menang meski JS OHIF
   menulis ulang inline style itu tiap resize (nilai computed akhir
   tetap ikut rule !important kita, bukan string vh yang JS tulis).
   TIDAK diubah ke `auto` (pelajaran dari percobaan kedua di atas) --
   cuma ganti unit vh->dvh, tetap nilai definitif. 52px di-hardcode
   sesuai yang OHIF sendiri hitung utk header Lumen ini (stabil kecuali
   header di-redesain ulang). */
.h-screen{
  height:100dvh !important;
}
html, body{
  overflow-y:auto !important;
}
div[class~="flex-row"][class~="flex-nowrap"][class~="items-stretch"][class~="overflow-hidden"]{
  height:calc(-52px + 100dvh) !important;
}
