/* Layout glue only: how the design system's components sit in the running app (page frame, fixed layers,
   breakpoints). Every colour, size and component style comes from jgl.css; nothing here restyles a component. */
html, body { margin: 0; min-height: 100%; background: var(--bg); color: var(--text); font-family: var(--font-ui); }
:lang(ja) body { font-family: var(--font-ja); }

.app-shell { display: flex; flex-direction: column; min-height: 100vh; }
.app-shell > .topbar { position: sticky; top: 0; z-index: 10; }
.app-body { display: flex; flex: 1; align-items: stretch; min-height: 0; }
.app-nav { flex: 0 0 224px; border-right: 1px solid var(--line); position: sticky; top: 52px; height: calc(100vh - 52px); overflow-y: auto; box-sizing: border-box; }
.app-nav .nav-foot { margin-top: auto; padding: 16px 10px 4px; }
.app-nav .nav-foot .xs { display: flex; align-items: center; gap: 6px; }
.app-main { flex: 1 1 560px; min-width: 0; padding: 20px 24px 32px; display: flex; flex-direction: column; gap: 14px; outline: none; }

/* Task panel: a fixed side sheet under the top bar; the page narrows beside it (body.has-panel). */
#panel-root .panel { position: fixed; top: 52px; right: 0; bottom: 0; width: 600px; max-width: 100%; z-index: 15; overflow-y: auto; }
body.has-panel .app-main { margin-right: 600px; }

/* Fixed layers for dialogs, menus, toasts and tooltips (the design draws them inside artboards). */
.dlg-layer { position: fixed; inset: 0; z-index: 40; }
.dlg-layer .scrim { position: fixed; }
.dlg-layer .overlay { position: fixed; top: 10vh; max-height: 80vh; }
.dlg-layer .dlg { max-width: calc(100vw - 32px); max-height: 80vh; overflow-y: auto; }
.menu-pop { position: fixed; z-index: 50; }
#toast-root { position: fixed; right: 16px; bottom: 16px; z-index: 60; display: flex; flex-direction: column; gap: 8px; }
#tip { position: fixed; z-index: 70; pointer-events: none; }
#tip[hidden] { display: none; } /* .tipbox sets display, which would otherwise override the hidden attribute */

/* Phones and narrow windows: navigation moves into a sheet; the panel and dialogs go full screen. */
@media (max-width: 767px) {
  .app-shell > .topbar { display: none; }
  .app-nav { display: none; }
  .app-nav.open { display: flex; position: fixed; inset: 56px 0 0 0; height: auto; z-index: 30; width: auto; border: 0; }
  .app-main { padding: 12px 12px 88px; }
  body.has-panel .app-main { margin-right: 0; }
  #panel-root .panel { top: 0; width: 100%; z-index: 35; }
  .dlg-layer .overlay { top: auto; bottom: 0; padding: 0; }
  .dlg-layer .dlg { width: 100% !important; max-width: 100%; border-radius: 12px 12px 0 0; }
  #toast-root { left: 12px; right: 12px; bottom: 76px; }
  #toast-root .toast { width: auto; }
}
@media (min-width: 768px) { .phone-only { display: none !important; } }

/* Phone shell (< 768px): header (.phone-top), bottom tab bar (.phone-tabs) and the navigation sheet (.app-nav.open).
   Layers: header 10 · tab bar 20 · sheet 30 · task panel 35 · dialogs 40 · menus 50 · toasts 60. */
@media (max-width: 767px) {
  .app-shell > .phone-top { position: sticky; top: 0; z-index: 10; }
  .phone-top .run { flex: 0 1 auto; min-width: 0; overflow: hidden; } /* narrow phones: the run day gives way */
  @media (max-width: 399px) { #phone-zone .ic { display: none; } }
  .phone-top .brand-t { min-width: 0; overflow: hidden; text-overflow: ellipsis; } /* very narrow phones: the wordmark gives way first */
  .phone-tabs { position: fixed; left: 0; right: 0; bottom: 0; z-index: 20; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); height: 64px; background: var(--surface); border-top: 1px solid var(--line); }
  .phone-tabs > a, .phone-tabs > button { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; min-height: 44px; position: relative; color: var(--text-2); text-decoration: none; font-size: 11px; text-align: center; }
  :lang(ja) .phone-tabs > a, :lang(ja) .phone-tabs > button { font-size: 12px; }
  .phone-tabs > [aria-current="page"] { color: var(--accent); font-weight: 600; box-shadow: inset 0 2px 0 var(--accent); }
  .phone-tabs .n { position: absolute; top: 7px; left: 56%; font-family: var(--font-mono); font-size: 11px; line-height: 16px; background: var(--surface-3); color: var(--text); border-radius: 8px; padding: 0 5px; font-weight: 400; }
  .app-nav.open { overflow-y: auto; overscroll-behavior: contain; padding-bottom: 16px; }
  .app-nav.open > * { flex-shrink: 0; }
  .app-nav.open a { height: 44px; }
  .app-nav .nav-phone { display: flex; flex-direction: column; gap: 4px; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line); }
  .app-nav .nav-phone .segc { align-self: flex-start; margin: 4px 0 4px 10px; }
  .app-nav .nav-phone .segc button { height: 44px; min-width: 64px; padding: 0 14px; font-size: 13px; }
  .app-nav .nav-phone .me { min-height: 44px; padding: 0 10px; }
}
@media (max-width: 1180px) and (min-width: 768px) { body.has-panel .app-main { margin-right: 0; } }
/* The top bar's "· Go-Live in N" gives way first on narrower windows (the dashboard still shows it). */
@media (max-width: 1279px) { .topbar .countdown .cd-gl { display: none; } }
/* Long task text without spaces must wrap inside phone rows instead of widening the page. */
.trow.phone .desc { overflow-wrap: anywhere; }
/* The whole task row opens the task (plan.js onRowClick); the description reads as the link on hover. */
li.trow[data-tid] { cursor: pointer; }
li.trow[data-tid]:hover .desc { text-decoration: underline; text-underline-offset: 2px; }
/* Keyboard focus never lands under the sticky top bar / phone header or the phone tab bar (WCAG 2.4.11). */
html { scroll-padding-top: 64px; }
@media (max-width: 767px) { html { scroll-padding-top: 68px; scroll-padding-bottom: 76px; } }
/* The discussion composer's boundary needs 3:1 against the surface (WCAG 1.4.11): use the field line colour. */
.composer { border-color: var(--field-line); }
/* Mid-size windows (768–1679px): the top bar drops the long texts so nothing pushes Sign out off-screen. The run
   range, your name and the Admin word go first (the avatar, the run name and the countdown number stay). Up to 1679px
   because the live indicator and the Japanese labels need the room (QA round 4: the bar overflowed at 1440). */
@media (min-width: 768px) and (max-width: 1679px) {
  .topbar .run .run-r, .topbar .me .b5, .topbar .me .tag { display: none; }
  .topbar .run { padding-right: 3px; }
  .topbar { gap: 8px; overflow: hidden; }
}
@media (min-width: 768px) and (max-width: 1023px) {
  .topbar .brand { font-size: 0; gap: 0; }
  .topbar .countdown { display: none; } /* the dashboard shows it */
}
/* Dashboard: the phase progress and gate list stack when there isn't room for both side by side. */
@media (max-width: 1279px) { .dash-2col { grid-template-columns: minmax(0, 1fr) !important; } }
.dash-2col > * { min-width: 0; overflow-x: auto; } /* a narrow window scrolls the gate table inside its card */
/* "No executor" sits on most rows before the Mock: a neutral dashed chip, so the attention colour stays for Needs
   attention (site review, ux F4). Same look as the plan rows. */
.pc.none { color: var(--text-2); border-color: var(--line-strong); }
/* Round-3 accessibility pass ---------------------------------------------------------------------------------------- */
/* Native controls (checkboxes, select pop-ups, scrollbars) follow the theme. */
.jgl { color-scheme: light; }
.jgl.dark { color-scheme: dark; }
/* Japanese reads better with more line height on task rows. */
.trow .desc:lang(ja) { line-height: 1.6; }
/* Small grey text on the selected (indigo) background in dark mode needs 4.5:1: use the stronger grey there. */
.jgl.dark .menu-i .k, .jgl.dark .ppl .role { color: var(--text-2); }
/* Date and time fields on the current run's accent card need a 3:1 boundary against that card. */
.plan-cur .inp { border-color: var(--text-3); }
/* Windows High Contrast / forced colours: selected and pressed states, the Programme's Today line and Next ring. */
@media (forced-colors: active) {
  .jgl [role="tab"][aria-selected="true"] { border-bottom: 3px solid Highlight; }
  .jgl .segc button[aria-pressed="true"], .jgl .nav a[aria-current="page"] { outline: 2px solid Highlight; outline-offset: -2px; }
  .jgl .menu-i[aria-checked="true"] { border-left: 4px solid Highlight; }
  .jgl .prog-today { forced-color-adjust: none; background: CanvasText !important; opacity: 1 !important; }
  .jgl .prog-next { outline: 2px solid Highlight; }
}
/* Live indicator (main.js paintLive): is the data on screen current? */
.live-ind { appearance: none; font: inherit; display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px; border-radius: 14px;
  border: 1px solid var(--line); background: var(--surface); color: var(--text-2); font-size: 12px; white-space: nowrap; cursor: pointer; }
.live-ind .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--ok); flex: none; }
.live-ind.paused .dot { background: var(--text-3); }
.live-ind.stale { border-color: var(--warn-line); background: var(--warn-bg); color: var(--warn); font-weight: 600; }
.live-ind.stale .dot { background: var(--warn); }
.live-ind.ph { height: 30px; padding: 0 8px; margin-right: 2px; }
/* Full words ("Live · updated 12s ago") only where there is room; a short word below 1680px, just the dot below 1280px
   (stale always says so). On the phone: a dot (hollow while paused), and "!" when stale. The name says it all. */
.live-ind .lt-short { display: none; }
@media (max-width: 1679px) { .topbar .live-ind .lt-long { display: none; } .topbar .live-ind .lt-short { display: inline; } }
@media (min-width: 768px) and (max-width: 1279px) { .topbar .live-ind:not(.stale) .lt-short { display: none; } .topbar .live-ind:not(.stale) { padding: 0 9px; } }
.live-ind.paused .dot { background: transparent; border: 2px solid var(--text-2); box-sizing: border-box; }
@media (forced-colors: active) { .jgl .live-ind .dot { forced-color-adjust: none; background: CanvasText; } .jgl .live-ind.stale { border: 2px solid Highlight; } }
.live-ind.ph .lt-long { display: none; }
.live-ind.ph .lt-short { display: inline; }
.live-ind.ph:not(.stale) .lt-short { display: none; }
/* Company tags next to names: Infor as a red block with white text in Infor's own red (Brad, 26 Oct 2026), like PING's
   black block. White on #D71E25 is 5.3:1. */
.co.infor { background: #D71E25; color: #fff; border: 1px solid #D71E25; padding: 1px 4px; }
@media (forced-colors: active) { .jgl .co.infor { border-color: CanvasText; } }
