/* =========================================================================
 * jps-dialog-redesign.css
 * 金鐘獎評審系統 (jps.gbawards.net) Dialog UI/UX 重設計
 *
 * Revision 2 — 2026-05-24
 *   - gbajps.css `#entirePage .ui-dialog { width: 80% !important }` 已被刪除
 *   - 不再需要 specificity 競賽；本檔規則自然贏 PrimeFaces inline style 即可
 *   - 寬度分組從 6 類收斂到 3 類 (info/form/media) + 1 sub-type (confirm)
 *
 * Cascade 策略：
 *   1. PrimeFaces 5.3/13 dialog 在 show() 會 inline `style="width:Xpx; top:Yp; left:Zp"`
 *      → 我們需要 `!important` 才能蓋掉 inline width
 *   2. 各 type 寬度宣告為 same-specificity，靠**規則順序**讓 per-type override 通則
 *   3. 不使用 #entirePage 拉特異性，因為通則跟例外都用 [id*="Dlg"] / [id$="DlgId"]
 *      即可，特異性都是 (0,2,0)，cascade 順序決定勝負
 *
 * Scope：所有規則都用 `.ui-dialog[id*="Dlg"]` 或 `[id$="...DlgId"]`，
 *        必含 "Dlg" 字串才命中 → 不影響其他頁面的 PrimeFaces dialog
 *
 * Tokens：所有尺寸/間距/顏色都用 CSS custom property，未來改設計只動 :root
 *
 * CSS 變數 prefix `--jps-*`：與 gba-app/a11y-contrast.css 的 `--a11y-*` 同 pattern
 *   （功能域 prefix），未來若整個應用都搬到統一 design system 再 rename。
 * ========================================================================= */

/* ============== Design tokens ============== */
:root {
  /* 3 主寬度類型 + 1 sub confirm，全部 clamp(min, fluid, max) */
  --jps-dlg-w-info:    clamp(320px, 92vw, 720px);   /* 讀為主：workDlg, cvDlg, menualDlg, file-list 6 個, creative-text 2 個 */
  --jps-dlg-w-form:    clamp(320px, 92vw, 640px);   /* 輸入：remarkDlg, qualifyDlg */
  --jps-dlg-w-media:   clamp(320px, 92vw, 920px);   /* 圖片影音：picDlg, musicDlg */
  --jps-dlg-w-confirm: clamp(280px, 92vw, 480px);   /* 小型 confirm：logoutDlg */

  --jps-dlg-max-h:     min(92vh, 920px);

  /* Spacing scale (4px base) */
  --jps-sp-1: 4px; --jps-sp-2: 8px; --jps-sp-3: 12px;
  --jps-sp-4: 16px; --jps-sp-5: 20px; --jps-sp-6: 24px; --jps-sp-7: 32px;

  /* Touch targets (WCAG 2.5.5 AAA = 44px; Apple HIG = 44pt) */
  --jps-touch-min: 44px;

  /* Typography */
  --jps-fs-header: 1.125rem;
  --jps-fs-label:  0.9375rem;
  --jps-fs-value:  1rem;
  --jps-fs-meta:   0.8125rem;
  --jps-lh-content: 1.65;

  /* Palette — 沿用 GBA 既有色系，藍色從 #3379b8 改 #2c5e8a 確保 WCAG AA 對比 */
  --jps-color-text:          #2b2b2b;
  --jps-color-text-muted:    #555;
  --jps-color-label:         #2c5e8a;
  --jps-color-divider:       #e3dac0;
  --jps-color-border:        #c9b27c;
  --jps-color-bg:            #fffdf6;
  --jps-color-bg-alt:        #f6f0dd;
  --jps-color-bg-image:      #1a1a1a;        /* picDlg 黑色背景，凸顯不規則長寬比的圖片 */
  --jps-color-overlay:       rgba(20, 18, 12, 0.55);
  --jps-color-link:          #2c5e8a;
  --jps-color-primary:       #ce5f00;
  --jps-color-primary-hover: #a64d00;
  --jps-color-focus:         #ffaa1d;

  --jps-radius:    12px;
  --jps-radius-sm: 8px;
  --jps-shadow:    0 18px 50px rgba(0, 0, 0, 0.35), 0 2px 6px rgba(0, 0, 0, 0.2);
}

/* =========================================================================
 * 1. Base dialog container — info 寬度為預設
 *    Selector 同時 cover form1:xxxDlgId 與 body 層級的 logoutDlgId
 * ========================================================================= */
.ui-dialog[id*="Dlg"],
.ui-dialog[id*="DlgId"] {
  width: var(--jps-dlg-w-info) !important;
  max-width: calc(100vw - 16px) !important;
  max-height: var(--jps-dlg-max-h);
  height: auto !important;
  border: none !important;
  border-radius: var(--jps-radius);
  background: var(--jps-color-bg);
  color: var(--jps-color-text);
  box-shadow: var(--jps-shadow);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  font-family: "PingFang TC", "Microsoft JhengHei", "Noto Sans CJK TC",
               system-ui, -apple-system, sans-serif;
}

/* =========================================================================
 * 2. Width by dialog type — same specificity (0,2,0)
 *    在 base rule 之後宣告 → cascade 後者贏
 * ========================================================================= */

/* form: textarea-based note dialogs */
.ui-dialog[id$="remarkDlgId"],
.ui-dialog[id$="qualifyDlgId"] {
  width: var(--jps-dlg-w-form) !important;
}

/* media: picture + music player */
.ui-dialog[id$="picDlgId"],
.ui-dialog[id$="musicDlgId"] {
  width: var(--jps-dlg-w-media) !important;
}

/* 2026-05-27 picDlg 開啟未置中修正：
   PrimeFaces show() 算 top/left 時圖片還沒載入，後續高度變化但 top/left 不重算，
   造成 dialog 偏下方需滾動才見。改 CSS-only 置中（top:50% + transform）由瀏覽器
   每幀重算，content 高度變化也跟著置中。max-height 92vh 內部自滾。 */
.ui-dialog[id$="picDlgId"] {
  top: 50% !important;
  left: 50% !important;
  transform: translate(-50%, -50%) !important;
  margin: 0 !important;
}

/* confirm: tiny modal confirm */
.ui-dialog[id="logoutDlgId"] {
  width: var(--jps-dlg-w-confirm) !important;
}

/* info 是預設值（base rule），下列 11 個 dialog 不需個別宣告：
 *   workDlg, cvDlg, menualDlg,
 *   waDlg, scriptDlg, raDlg, authDlg, radioScriptDlg, musicPdfDlg,
 *   creativeConteDlg, tvCreativeConteDlg
 */

/* =========================================================================
 * 3. Title bar — proper header + 44×44 close button
 * ========================================================================= */
.ui-dialog[id*="Dlg"] > .ui-dialog-titlebar {
  position: relative;
  flex: 0 0 auto;
  padding: 14px 56px 14px 20px;    /* right=56 reserves close-btn space */
  background: linear-gradient(180deg, #fffaef 0%, #f3e9cc 100%);
  border: none !important;
  border-bottom: 1px solid var(--jps-color-divider) !important;
  border-radius: var(--jps-radius) var(--jps-radius) 0 0 !important;
  color: var(--jps-color-text);
  min-height: 56px;
  display: flex;
  align-items: center;
}

.ui-dialog[id*="Dlg"] > .ui-dialog-titlebar .ui-dialog-title {
  font-size: var(--jps-fs-header);
  font-weight: 600;
  line-height: 1.4;
  color: var(--jps-color-text);
  margin: 0;
  padding-right: 16px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1 1 auto;
  min-width: 0;
  text-shadow: none;
}

.ui-dialog[id*="Dlg"] > .ui-dialog-titlebar .ui-dialog-titlebar-close {
  position: absolute !important;
  top: 50% !important;
  right: 10px !important;
  transform: translateY(-50%) !important;
  width: var(--jps-touch-min) !important;
  height: var(--jps-touch-min) !important;
  margin: 0 !important;
  padding: 0 !important;
  border: none !important;
  border-radius: 50% !important;
  background: rgba(0, 0, 0, 0.06) !important;
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  opacity: 1 !important;
  cursor: pointer;
  transition: background-color 120ms ease, transform 120ms ease;
}
.ui-dialog[id*="Dlg"] > .ui-dialog-titlebar .ui-dialog-titlebar-close:hover {
  background: rgba(0, 0, 0, 0.14) !important;
  transform: translateY(-50%) scale(1.05) !important;
}
.ui-dialog[id*="Dlg"] > .ui-dialog-titlebar .ui-dialog-titlebar-close:focus-visible {
  outline: none !important;
  box-shadow: 0 0 0 3px var(--jps-color-focus);
}
/* Hide PrimeFaces' built-in icon glyph, use our own × */
.ui-dialog[id*="Dlg"] > .ui-dialog-titlebar .ui-dialog-titlebar-close .ui-icon {
  display: none !important;
}
.ui-dialog[id*="Dlg"] > .ui-dialog-titlebar .ui-dialog-titlebar-close::after {
  content: "\00d7";   /* × */
  font-size: 22px;
  line-height: 1;
  color: var(--jps-color-text);
  font-family: sans-serif;
  font-weight: 400;
}

/* =========================================================================
 * 4. Content area — scrollable body
 * ========================================================================= */
.ui-dialog[id*="Dlg"] > .ui-dialog-content {
  flex: 1 1 auto;
  padding: 20px 24px !important;
  background: var(--jps-color-bg) !important;
  color: var(--jps-color-text) !important;
  font-size: var(--jps-fs-value) !important;
  line-height: var(--jps-lh-content) !important;
  overflow-y: auto !important;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: rgba(0, 0, 0, 0.2) transparent;
}
.ui-dialog[id*="Dlg"] > .ui-dialog-content::-webkit-scrollbar {
  width: 8px;
}
.ui-dialog[id*="Dlg"] > .ui-dialog-content::-webkit-scrollbar-thumb {
  background: rgba(0, 0, 0, 0.2);
  border-radius: 4px;
}

/* =========================================================================
 * 5. Inner reset — kill Bootstrap row/col + hard-coded widths
 *    源碼用 <div class="row"><div class="col-lg-12 ..."><div class="gba-table">
 *    三層巢狀；內層的 scrollPanel 寫死 width:600px height:400px → 與外層
 *    dialog 寬度脫鉤造成大片留白。本節把這些壓回 100%。
 * ========================================================================= */
.ui-dialog[id*="Dlg"] .row,
.ui-dialog[id*="Dlg"] .col-lg-12,
.ui-dialog[id*="Dlg"] .col-md-12,
.ui-dialog[id*="Dlg"] .col-sm-12,
.ui-dialog[id*="Dlg"] .col-xs-12 {
  margin: 0 !important;
  padding: 0 !important;
  width: 100% !important;
  float: none !important;
}

/* Kill hard-coded width:600px on inner scroll divs */
.ui-dialog[id*="Dlg"] [style*="width:600px"],
.ui-dialog[id*="Dlg"] [style*="width: 600px"],
.ui-dialog[id*="Dlg"] .ui-scrollpanel {
  width: 100% !important;
  max-width: 100% !important;
  height: auto !important;
  max-height: 60vh !important;
}
/* 2026-05-24 Rev 4 Bug 3 fix: PrimeFaces actual rendered class names are
 * .ui-scrollpanel-vbar / -track / -drag / -cap (not .ui-scrollpanel-bar).
 * Previous selector .ui-scrollpanel-bar didn't match → fake scrollbar still
 * visible on right side of raDlg as a striped/hatched strip. Hide all
 * scrollbar visual elements. */
.ui-dialog[id*="Dlg"] .ui-scrollpanel .ui-scrollpanel-bar,
.ui-dialog[id*="Dlg"] .ui-scrollpanel .ui-scrollpanel-vbar,
.ui-dialog[id*="Dlg"] .ui-scrollpanel .ui-scrollpanel-hbar,
.ui-dialog[id*="Dlg"] .ui-scrollpanel .ui-scrollpanel-track,
.ui-dialog[id*="Dlg"] .ui-scrollpanel .ui-scrollpanel-drag,
.ui-dialog[id*="Dlg"] .ui-scrollpanel .ui-scrollpanel-cap {
  display: none !important;
}
/* 2026-05-24 Rev 4 Bug 1 fix: PF scrollpanel sets inline height:0 on
 * .ui-scrollpanel-container + overflow:hidden, and puts content as
 * position:absolute. This clips the content (esp. images in picDlg) to 0px
 * visible region. Force container to natural height + visible overflow, and
 * unset absolute on content so it pushes container height normally. */
.ui-dialog[id*="Dlg"] .ui-scrollpanel .ui-scrollpanel-container {
  width: 100% !important;
  height: auto !important;
  overflow: visible !important;
  position: static !important;
}
.ui-dialog[id*="Dlg"] .ui-scrollpanel .ui-scrollpanel-wrapper,
.ui-dialog[id*="Dlg"] .ui-scrollpanel .ui-scrollpanel-content {
  width: 100% !important;
  height: auto !important;
  overflow: visible !important;
  padding-right: 0 !important;
  position: static !important;
}

/* gba-table container + table neutralise */
.ui-dialog[id*="Dlg"] .gba-table {
  background: none !important;
  border: none !important;
  padding: 0 !important;
  overflow: visible !important;
}
.ui-dialog[id*="Dlg"] table.gba-table {
  background: none !important;
  border: none !important;
  width: 100% !important;
}
/* 2026-05-24 Rev 6 Bug 1 fix: exclude .rwd-table-dialog (cvDlg uses it) so
 * its td stays display: table-cell (proper table layout). Previous rule
 * dropped cvDlg td to display:block → cells stacked vertically on desktop. */
.ui-dialog[id*="Dlg"] table.gba-table:not(.rwd-table-dialog) > tbody > tr > td {
  padding: 0 0 16px 0 !important;
  border: none !important;
  background: none !important;
  display: block;
}

/* =========================================================================
 * 6. Info dialog: label / value 2-col grid
 *    所有 gba-input-group 都套這個 grid，桌面 label-value 平鋪，手機堆疊
 * ========================================================================= */
.ui-dialog[id*="Dlg"] .gba-input-group {
  display: grid !important;
  grid-template-columns: minmax(160px, 220px) 1fr !important;
  gap: 4px 24px !important;
  padding: 12px 0 !important;
  margin: 0 !important;
  border-bottom: 1px solid var(--jps-color-divider);
  font-size: var(--jps-fs-value) !important;
  font-weight: normal !important;
  line-height: var(--jps-lh-content) !important;
  align-items: baseline;
  width: 100% !important;
}
.ui-dialog[id*="Dlg"] .gba-input-group:last-child {
  border-bottom: none;
}
.ui-dialog[id*="Dlg"] .gba-label {
  display: block !important;
  width: auto !important;
  font-size: var(--jps-fs-label) !important;
  font-weight: 600 !important;
  color: var(--jps-color-label) !important;
  padding: 0 !important;
  text-align: left !important;
}
.ui-dialog[id*="Dlg"] .gba-input-control {
  display: block !important;
  padding: 0 !important;
  text-align: left !important;
  color: var(--jps-color-text);
  word-break: break-word;
}
/* 2026-05-24 Rev 5 Task A fix: workDlg has groups where label was commented
 * out in xhtml, leaving <div class="gba-input-group"><div class="gba-input-control">
 * 長段播放資訊文字</div></div>. Grid default flow placed the control in column 1
 * (label slot, 220px) → long text wrapped in narrow column, column 2 stayed
 * empty. Same applies to section-heading groups with label-only (e.g. "播放
 * 資訊", "節目企畫及內容說明"). Fix: when group has only one child
 * (control-only OR label-only), span both columns. */
.ui-dialog[id*="Dlg"] .gba-input-group > .gba-input-control:only-child,
.ui-dialog[id*="Dlg"] .gba-input-group > .gba-label:only-child {
  grid-column: 1 / -1;
}
/* Section-heading label (label-only group, no value): stronger visual treatment
 * matching the existing "節目企畫及內容說明" inline-styled section headers */
.ui-dialog[id*="Dlg"] .gba-input-group > .gba-label:only-child {
  font-size: 1rem;
  font-weight: 700;
  border-left: 4px solid var(--jps-color-label);
  padding-left: 10px !important;
  margin: 16px 0 4px 0;
}
@media (max-width: 640px) {
  .ui-dialog[id*="Dlg"] .gba-input-group {
    grid-template-columns: 1fr !important;
  }
}

/* Section heading inside workDlg ("節目企畫及內容說明：" etc.) */
.ui-dialog[id*="workDlgId"] [style*="color:#3379b8"],
.ui-dialog[id*="workDlgId"] [style*="color: #3379b8"] {
  display: block !important;
  font-size: 1rem !important;
  font-weight: 700 !important;
  color: var(--jps-color-label) !important;
  border-left: 4px solid var(--jps-color-label);
  padding: 0 0 0 10px !important;
  margin: 24px 0 12px 0 !important;
  background: none !important;
  text-align: left !important;
}

/* =========================================================================
 * 7. File-list dialogs (waDlg / scriptDlg / raDlg / authDlg /
 *                       radioScriptDlg / musicPdfDlg)
 *    Each link is a 44px-tall card with download icon prefix
 * ========================================================================= */
.ui-dialog[id*="waDlgId"] a[target^="_"],
.ui-dialog[id*="raDlgId"] a[target^="_"],
.ui-dialog[id*="scriptDlgId"] a[target^="_"],
.ui-dialog[id*="radioScriptDlgId"] a[target^="_"],
.ui-dialog[id*="authDlgId"] a[target^="_"],
.ui-dialog[id*="musicPdfDlgId"] a[target^="_"] {
  display: flex !important;
  align-items: center;
  gap: 10px;
  min-height: var(--jps-touch-min);
  padding: 10px 14px;
  margin: 0 0 6px 0;
  width: 100%;
  background: #fff;
  border: 1px solid var(--jps-color-border);
  border-radius: var(--jps-radius-sm);
  color: var(--jps-color-link);
  text-decoration: none;
  font-weight: 500;
  box-sizing: border-box;
  transition: background 120ms ease, box-shadow 120ms ease;
}
.ui-dialog[id*="waDlgId"] a[target^="_"]:hover,
.ui-dialog[id*="raDlgId"] a[target^="_"]:hover,
.ui-dialog[id*="scriptDlgId"] a[target^="_"]:hover,
.ui-dialog[id*="radioScriptDlgId"] a[target^="_"]:hover,
.ui-dialog[id*="authDlgId"] a[target^="_"]:hover,
.ui-dialog[id*="musicPdfDlgId"] a[target^="_"]:hover {
  background: #fffaef;
  text-decoration: none;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
}
.ui-dialog[id*="waDlgId"] a[target^="_"]::before,
.ui-dialog[id*="raDlgId"] a[target^="_"]::before,
.ui-dialog[id*="scriptDlgId"] a[target^="_"]::before,
.ui-dialog[id*="radioScriptDlgId"] a[target^="_"]::before,
.ui-dialog[id*="authDlgId"] a[target^="_"]::before,
.ui-dialog[id*="musicPdfDlgId"] a[target^="_"]::before {
  content: "\2b07";   /* ⬇ download arrow */
  font-size: 14px;
  color: var(--jps-color-primary);
  flex-shrink: 0;
}
/* Wrapper table inside these file dialogs collapses to block.
 * 2026-05-24 Rev 4 Bug 2 fix: previous selector only set tr/td → block but
 * left <table> as display:table (intrinsic content width) → waDlg link got
 * trapped in 84px table → looked like small button instead of full-width
 * card. Now reset table/tbody too so links inherit full content width.
 * Note: cvDlg uses table.rwd-table-dialog which has its own rules in §12;
 * this `:not(.rwd-table-dialog)` exclusion keeps that intact. */
.ui-dialog[id*="Dlg"] table:not(.rwd-table-dialog),
.ui-dialog[id*="Dlg"] table:not(.rwd-table-dialog) tbody,
.ui-dialog[id*="Dlg"] table:not(.rwd-table-dialog) tr,
.ui-dialog[id*="Dlg"] table:not(.rwd-table-dialog) td {
  display: block !important;
  width: 100% !important;
  padding: 0 !important;
  border: none !important;
  background: none !important;
}

/* =========================================================================
 * 8. Image dialog (picDlg) — black background + object-fit contain
 *    Solves the cropping bug from before screenshots (face cut to eyes only)
 * ========================================================================= */
.ui-dialog[id*="picDlgId"] .ui-dialog-content {
  background: var(--jps-color-bg-image) !important;
  padding: 16px !important;
}
/* 2026-05-24 Rev 4 Bug 1 fix: grid was placed on outer .ui-scrollpanel, but
 * children are .ui-scrollpanel-container > .ui-scrollpanel-content > <img>.
 * Container was a single grid item; images were 3 levels deep and (combined
 * with PF inline height:0 on container) clipped invisible on iPhone.
 *
 * Rev 4 fix: move grid to .ui-scrollpanel-content (the level images are
 * direct children of). Outer .ui-scrollpanel becomes simple block, normal
 * height/overflow flow. Combined with §5 reset (container/content position
 * static, height auto, overflow visible) images now render naturally in grid. */
.ui-dialog[id*="picDlgId"] .ui-scrollpanel {
  display: block !important;
  width: 100% !important;
  max-height: min(72vh, 720px) !important;
  overflow: visible !important;
  background: transparent !important;
}
/* 2026-05-24 Rev 7 fix: grid auto-fit with minmax(260,1fr) made single image
 * take only 1 column out of potential 3, leaving 2 columns of black space →
 * image looked "broken" with excessive letterbox. Use flex wrap so single
 * image fills full width, multiple images wrap into rows. */
.ui-dialog[id*="picDlgId"] .ui-scrollpanel .ui-scrollpanel-content,
.ui-dialog[id*="picDlgId"] .ui-dialog-content > .row > div {
  display: flex !important;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px !important;
  width: 100% !important;
  background: transparent !important;
}
.ui-dialog[id*="picDlgId"] img {
  flex: 1 1 260px;
  min-width: 0;
}
.ui-dialog[id*="picDlgId"] img {
  display: block;
  width: 100% !important;
  height: auto !important;
  max-height: 72vh;
  object-fit: contain !important;
  background: #000;
  border-radius: var(--jps-radius-sm);
}
@media (max-width: 640px) {
  .ui-dialog[id*="picDlgId"] .ui-scrollpanel .ui-scrollpanel-content,
  .ui-dialog[id*="picDlgId"] .ui-dialog-content > .row > div {
    /* flex-direction column stacks images vertically on iPhone */
    flex-direction: column;
  }
}

/* =========================================================================
 * 9. Form dialogs (remarkDlg / qualifyDlg)
 *    Full-width textarea + sticky footer with primary save button
 * ========================================================================= */
.ui-dialog[id*="remarkDlgId"] .ui-dialog-content,
.ui-dialog[id*="qualifyDlgId"] .ui-dialog-content {
  display: flex;
  flex-direction: column;
  padding-bottom: 0 !important;
}
.ui-dialog[id*="remarkDlgId"] textarea,
.ui-dialog[id*="qualifyDlgId"] textarea {
  width: 100% !important;
  min-height: 220px !important;
  max-height: 50vh !important;
  resize: vertical !important;
  box-sizing: border-box !important;
  padding: 12px 14px !important;
  border: 1px solid var(--jps-color-border) !important;
  border-radius: var(--jps-radius-sm) !important;
  font-size: var(--jps-fs-value) !important;
  line-height: 1.6 !important;
  color: var(--jps-color-text) !important;
  background: #fff !important;
  font-family: inherit !important;
}
.ui-dialog[id*="remarkDlgId"] textarea:focus,
.ui-dialog[id*="qualifyDlgId"] textarea:focus {
  outline: none;
  border-color: var(--jps-color-link) !important;
  box-shadow: 0 0 0 3px rgba(44, 94, 138, 0.2);
}
.ui-dialog[id*="remarkDlgId"] .ui-dialog-content > .row:last-child,
.ui-dialog[id*="qualifyDlgId"] .ui-dialog-content > .row:last-child {
  flex: 0 0 auto;
  position: sticky;
  bottom: 0;
  background: var(--jps-color-bg);
  margin: 16px -24px 0 -24px !important;
  padding: 14px 24px !important;
  border-top: 1px solid var(--jps-color-divider);
  display: flex;
  justify-content: flex-end;
}
.ui-dialog[id*="remarkDlgId"] a.btn-primary,
.ui-dialog[id*="qualifyDlgId"] a.btn-primary {
  min-width: 120px;
  min-height: var(--jps-touch-min);
  padding: 0 24px !important;
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  font-size: var(--jps-fs-value);
  font-weight: 600;
  background: var(--jps-color-primary) !important;
  border: none !important;
  color: #fff !important;
  border-radius: var(--jps-radius-sm);
  transition: background 120ms ease;
}
.ui-dialog[id*="remarkDlgId"] a.btn-primary:hover,
.ui-dialog[id*="qualifyDlgId"] a.btn-primary:hover {
  background: var(--jps-color-primary-hover) !important;
}
@media (max-width: 640px) {
  .ui-dialog[id*="remarkDlgId"] a.btn-primary,
  .ui-dialog[id*="qualifyDlgId"] a.btn-primary {
    width: 100%;
  }
}

/* =========================================================================
 * 10. Creative content dialogs (creativeConteDlg / tvCreativeConteDlg)
 *    Either inline read-only textarea OR a single PDF link
 * ========================================================================= */
.ui-dialog[id*="creativeConteDlgId"] table,
.ui-dialog[id*="tvCreativeConteDlgId"] table {
  width: 100% !important;
  border: none !important;
  background: none !important;
}
.ui-dialog[id*="creativeConteDlgId"] textarea,
.ui-dialog[id*="tvCreativeConteDlgId"] textarea {
  width: 100% !important;
  min-height: 240px !important;
  max-height: 55vh !important;
  resize: vertical !important;
  box-sizing: border-box !important;
  padding: 12px 14px !important;
  border: 1px solid var(--jps-color-border) !important;
  border-radius: var(--jps-radius-sm) !important;
  font-size: var(--jps-fs-value) !important;
  line-height: 1.6 !important;
  background: #fff !important;
}

/* =========================================================================
 * 11. Music dialog (musicDlg) — audio player + tracklist
 * ========================================================================= */
.ui-dialog[id*="musicDlgId"] audio,
.ui-dialog[id*="musicDlgId"] .html5-audio {
  width: 100% !important;
  height: 48px !important;
  margin: 0 0 16px 0 !important;
  border-radius: var(--jps-radius-sm);
  background: var(--jps-color-bg-alt);
}
.ui-dialog[id*="musicDlgId"] a.ui-commandlink {
  display: flex !important;
  align-items: center;
  gap: 10px;
  min-height: var(--jps-touch-min);
  padding: 10px 14px;
  margin: 0 0 6px 0;
  background: #fff;
  border: 1px solid var(--jps-color-border);
  border-radius: var(--jps-radius-sm);
  color: var(--jps-color-link);
  text-decoration: none;
  font-weight: 500;
}
.ui-dialog[id*="musicDlgId"] a.ui-commandlink:hover {
  background: #fffaef;
  text-decoration: none;
}
.ui-dialog[id*="musicDlgId"] a.ui-commandlink::before {
  content: "\25b6";   /* ▶ */
  font-size: 11px;
  color: var(--jps-color-primary);
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: rgba(206, 95, 0, 0.12);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.ui-dialog[id*="musicDlgId"] br { display: none; }

/* =========================================================================
 * 12. CV dialog (cvDlg) — multi-participant CV viewer
 * ========================================================================= */
.ui-dialog[id*="cvDlgId"] hr {
  border: none;
  border-top: 1px dashed var(--jps-color-divider);
  margin: 24px 0;
}
.ui-dialog[id*="cvDlgId"] table.rwd-table-dialog {
  width: 100% !important;
  border: 1px solid var(--jps-color-border) !important;
  border-radius: var(--jps-radius-sm) !important;
  overflow: hidden;
  border-collapse: separate !important;
  border-spacing: 0 !important;
  margin: 8px 0 0 0 !important;
  font-size: 0.9375rem;
}
.ui-dialog[id*="cvDlgId"] table.rwd-table-dialog th {
  background: #555 !important;
  color: #fff !important;
  padding: 8px !important;
  font-weight: 600;
}
.ui-dialog[id*="cvDlgId"] table.rwd-table-dialog td {
  padding: 8px !important;
  background: var(--jps-color-bg-alt) !important;
}
.ui-dialog[id*="cvDlgId"] table.rwd-table-dialog tr:nth-child(odd) td {
  background: #ebe4cf !important;
}

/* =========================================================================
 * 13. Confirm dialog (logoutDlg) — center text + larger padding
 * ========================================================================= */
.ui-dialog[id="logoutDlgId"] .ui-dialog-content {
  text-align: center;
  padding: 24px !important;
  font-size: var(--jps-fs-value);
}

/* =========================================================================
 * 14. Mobile (< 640px) — full-screen bottom-sheet
 *    Uses same specificity → declared late so it overrides per-type widths
 *    via cascade order
 * ========================================================================= */
@media (max-width: 640px) {
  .ui-dialog[id*="Dlg"],
  .ui-dialog[id*="DlgId"] {
    width: 100vw !important;
    max-width: 100vw !important;
    min-width: 0 !important;
    left: 0 !important;
    right: 0 !important;
    top: 0 !important;
    bottom: 0 !important;
    height: 100vh !important;
    max-height: 100vh !important;
    border-radius: 0 !important;
    margin: 0 !important;
    padding-bottom: env(safe-area-inset-bottom);
  }
  .ui-dialog[id*="Dlg"] > .ui-dialog-titlebar {
    border-radius: 0 !important;
    position: sticky;
    top: 0;
    z-index: 2;
  }
  .ui-dialog[id*="Dlg"] > .ui-dialog-content {
    padding: 16px !important;
  }
  .ui-dialog[id*="Dlg"] a[target^="_"],
  .ui-dialog[id*="Dlg"] a.ui-commandlink {
    font-size: 1rem;
    min-height: 48px;
  }
}

/* =========================================================================
 * 15. Focus visibility (WCAG 2.4.7)
 * ========================================================================= */
.ui-dialog[id*="Dlg"] a:focus-visible,
.ui-dialog[id*="Dlg"] button:focus-visible,
.ui-dialog[id*="Dlg"] textarea:focus-visible,
.ui-dialog[id*="Dlg"] input:focus-visible {
  outline: 2px solid var(--jps-color-focus);
  outline-offset: 2px;
}

/* =========================================================================
 * 16. Modal overlay (when modal=true used)
 * ========================================================================= */
.ui-widget-overlay {
  background: var(--jps-color-overlay) !important;
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}

/* =========================================================================
 * 17. Rev 6 — workDlg playback info label-value pairing + readability (Bug 2)
 *
 * Background: 「播放資訊」 in xhtml is split into TWO consecutive .gba-input-group:
 *   <div class="gba-input-group"><div class="gba-label">播放資訊</div></div>  ← label only
 *   <div class="gba-input-group"><div class="gba-input-control">long text</div></div>
 *                                  (label was commented out in xhtml line 750)
 *
 * Rev 5 made each :only-child group span both columns (workaround). Ray then
 * requested they be paired as label-value (label on left, value on right).
 *
 * Rev 6 approach: apply `display: contents` to .gba-input-group inside
 * .work-detail so its children (.gba-label / .gba-input-control) become DIRECT
 * grid items of .work-detail. CSS Grid auto-flow naturally pairs them:
 *   item1=label "播放資訊"     → row N col 1
 *   item2=control (long text)   → row N col 2 (next empty cell)
 *
 * Plus: white-space: pre-line on only-child control preserves source \n line
 * breaks → multi-period info appears on separate lines for readability.
 * ========================================================================= */
.ui-dialog[id*="workDlgId"] .work-detail {
  display: grid !important;
  grid-template-columns: minmax(160px, 220px) 1fr !important;
  gap: 0 24px !important;
  align-items: stretch;        /* 2026-05-28: 左右欄等高，bottom border 對齊 */
}
.ui-dialog[id*="workDlgId"] .work-detail > .gba-input-group {
  display: contents !important;          /* dissolve into parent grid */
  /* border-bottom would not render with display:contents — moved to children */
}
.ui-dialog[id*="workDlgId"] .work-detail > .gba-input-group > .gba-label,
.ui-dialog[id*="workDlgId"] .work-detail > .gba-input-group > .gba-input-control {
  padding: 10px 0 !important;
  border-bottom: 1px solid var(--jps-color-divider);
}
/* Rev 5's :only-child grid-column: 1/-1 rule would force control-only to span
 * both columns → defeats pairing. Reset for workDlg.work-detail context: */
.ui-dialog[id*="workDlgId"] .work-detail > .gba-input-group > .gba-input-control:only-child,
.ui-dialog[id*="workDlgId"] .work-detail > .gba-input-group > .gba-label:only-child {
  grid-column: auto;        /* let CSS Grid auto-flow place it */
}
.ui-dialog[id*="workDlgId"] .work-detail > .gba-input-group > .gba-label:only-child {
  /* Don't make section-heading; it's now just a label paired with next value */
  border-left: none;
  margin: 0;
  padding-left: 0 !important;
  font-size: var(--jps-fs-label);
  font-weight: 600;
  color: var(--jps-color-label) !important;
}
/* Readability: preserve source \n line breaks in long playback info text */
.ui-dialog[id*="workDlgId"] .work-detail > .gba-input-group > .gba-input-control:only-child {
  white-space: pre-line;
  line-height: 1.7;
}

/* 2026-05-28: 「播放資訊」拆成多列子欄位 + 每筆 broadcast info 之間加分隔線 */
.ui-dialog[id*="workDlgId"] .playback-info {
  display: flex;
  flex-direction: column;
  gap: 12px;
  white-space: normal;          /* 蓋掉前面 pre-line（這格不是 only-child，本來不會吃，但保險） */
  line-height: 1.6;
}
.ui-dialog[id*="workDlgId"] .playback-entry {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.ui-dialog[id*="workDlgId"] .playback-entry + .playback-entry {
  border-top: 1px dashed var(--jps-color-divider);
  padding-top: 12px;
}
.ui-dialog[id*="workDlgId"] .playback-entry .pe-row {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 6px;
}
.ui-dialog[id*="workDlgId"] .playback-entry .pe-label {
  flex: 0 0 auto;
  min-width: 5em;
  color: var(--jps-color-label);
  font-weight: 600;
}

/* =========================================================================
 * 18. Rev 6 — picDlg image loading spinner (Bug 3)
 *
 * Background: large photos from CloudFront take ~500ms-2s on first load. Until
 * then user sees blank black area. Add a CSS-only spinner via ::before on the
 * container; img element renders on top so when image pixels paint, they
 * cover the spinner naturally (no JS load-state class needed).
 *
 * Trick: parent has #000 background + centered spinner pseudo-element.
 * img has transparent background (was #000 in Rev 4, but that covered spinner).
 * Letterbox area still shows #000 from parent.
 * ========================================================================= */
.ui-dialog[id*="picDlgId"] .ui-scrollpanel-content,
.ui-dialog[id*="picDlgId"] .ui-dialog-content > .row > div {
  position: relative;
  min-height: 120px;                /* reserve space for spinner */
  background: var(--jps-color-bg-image) !important;
}
.ui-dialog[id*="picDlgId"] .ui-scrollpanel-content::before,
.ui-dialog[id*="picDlgId"] .ui-dialog-content > .row > div::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 40px;
  height: 40px;
  margin: -20px 0 0 -20px;
  border: 3px solid rgba(255, 255, 255, 0.22);
  border-top-color: var(--jps-color-primary);
  border-radius: 50%;
  animation: jps-spin 0.85s linear infinite;
  z-index: 0;
  pointer-events: none;
}
@keyframes jps-spin { to { transform: rotate(360deg); } }
/* Img on top of spinner; transparent bg so spinner shows during load.
 * After image paints, img pixels cover spinner naturally. Letterbox sides
 * remain #000 from parent background. */
.ui-dialog[id*="picDlgId"] img {
  position: relative;
  z-index: 1;
  background: transparent !important;
}

/* End of jps-dialog-redesign.css (Rev 6 — cvDlg + workDlg + picDlg fixes) */
