/* ============================================================
   PASSAGE — final polish layer
   Loads LAST, after every feature and mobile stylesheet, so these
   rules win without needing !important.
   ============================================================ */

/* ---------- government-links rail ----------
   It was set to `padding:0 30px 12px; margin-top:-6px` — no top padding and a
   negative top margin — so it sat jammed against the top bar and read as
   stuck rather than as its own rail. Give it real breathing room top and
   bottom, separate it from the chrome above, and make the horizontal scroll
   legible: the last pill used to sit flush-cut at the viewport edge, which
   looked broken rather than scrollable. */
.gv-bar{
  padding:11px 30px 13px;
  margin-top:0;
  border-bottom:1px solid var(--stroke-soft);
  background:linear-gradient(180deg, rgba(244,240,233,.34), rgba(244,240,233,0));
}
.gv-bar::after{
  content:"";
  position:absolute;
  top:0;
  right:0;
  bottom:0;
  width:38px;
  pointer-events:none;
  background:linear-gradient(90deg, rgba(251,249,244,0), rgba(251,249,244,.92));
}
.gv-track{
  gap:9px;
  padding-right:22px;   /* so the final pill never sits flush against the edge */
}
.gv-link{
  padding:6px 14px;
  flex:0 0 auto;
}

@media (max-width:760px){
  .gv-bar{
    padding:9px 12px 10px;
    margin-top:0;
  }
  .gv-bar::after{width:26px}
  .gv-track{gap:6px;padding-right:16px}
  .gv-link{padding:5px 11px;font-size:11px}
}

/* ---------- LMIA Desk on phones ----------
   Two separate faults made this page the worst one on mobile.

   1. `styles.css` forces `.kpis{grid-template-columns:1fr 1fr!important}` under
      760px. That is right for the dashboard's short numeric tiles, but the LMIA
      desk reuses `.kpi` for EMPLOYER cards, and "Maple Ridge Care Homes Ltd."
      in a 179px column wrapped to three lines and still clipped. Employer cards
      get the full width; !important is needed only to beat that !important.

   2. The compliance meter's requirement labels carry an inline
      `max-width:180px; white-space:nowrap; text-overflow:ellipsis`, sized for a
      desktop table column. Inside the restacked card that column is ~180px of a
      336px cell, so every requirement was cut mid-word ("Job Bank posting (4
      week…", "2 additional recruitment…"). Let them wrap and use the full row. */
@media (max-width:760px){
  .kpis.lmia-emps{grid-template-columns:1fr!important}
  .kpis.lmia-emps .kpi{padding:12px 14px}
  .kpis.lmia-emps .kpi .k-num{font-size:15.5px!important;line-height:1.3}
  .kpis.lmia-emps .kpi .k-lbl{font-size:10.5px;margin-top:3px}
  .kpis.lmia-emps .kpi .k-sub{font-size:11.5px;margin-top:5px}

  .comp-meter{gap:7px;width:100%}
  .comp-meter .cm-row{align-items:flex-start;gap:8px}
  .comp-meter .cm-row span{
    max-width:none!important;
    white-space:normal!important;
    overflow:visible!important;
    text-overflow:clip!important;
    font-size:11.5px!important;
    line-height:1.35;
  }
  /* a compliance cell needs the whole card width, not the value column */
  .tbl.cardable td:has(.comp-meter){display:block;width:100%}
  .tbl.cardable td:has(.comp-meter)::before{display:block;margin-bottom:6px}
}

/* ---------- grid/flex children must be allowed to shrink ----------
   A grid or flex item defaults to `min-width:auto`, which refuses to shrink
   below its content's intrinsic width. So a `overflow-x:auto` scroller nested
   inside one (the NOC Explorer's TEER chip row, for example) cannot actually
   constrain itself — the item stretched to 557px inside a 366px column and
   pushed its content out of view. This is the single most common cause of
   mystery overflow in CSS grid layouts; fix it once, here. */
@media (max-width:760px){
  .grid-2 > *, .grid-3 > *, .dash-grid > *, .dash-col > *,
  .kpis > *, .toolrow > *, .panel > *{ min-width:0; }

  /* inputs must never be wider than the card holding them */
  input, select, textarea{ max-width:100%; box-sizing:border-box; }
}

/* ---------- misc ---------- */

/* The mobile search-collapse close button is injected into `.searchbox` on
   every viewport, but it was only given a `display:none` inside the
   max-width:760px block — so on desktop it rendered as a stray ✕ sitting in
   the search field. Hide it globally; the mobile open-state rule
   (`.searchbox.ms-open .ms-search-close`) is more specific and still wins. */
.ms-search-close{display:none}

/* The kanban and any horizontally-scrolled rail should never hand its scroll
   to the page on iOS. */
.gv-track,.tabs,.kan{overscroll-behavior-x:contain}

/* ---------- unemployment table: read-only by default ---------- */
.gv-rate-ro{font-variant-numeric:tabular-nums;font-size:14px}
.gv-editnote{font-size:11.5px;color:var(--gold-deep);letter-spacing:.04em}

/* ---------- small mobile clipping nits found in the full sweep ---------- */
@media (max-width:760px){
  .doc-box{flex:0 0 24px;overflow:visible}
  .panel-title{min-width:0;flex-wrap:wrap;row-gap:6px}
  .panel-title .hint{min-width:0;overflow:hidden;text-overflow:ellipsis}
}

/* ---------- desktop sidebar: a light tightening ----------
   Not a shrink — the rail keeps its presence and its type stays readable.
   The nav simply grew from 11 items to 17 as the practice modules landed,
   so a few pixels per row is what keeps every section visible without
   scrolling the sidebar. Scoped above the mobile breakpoint so the phone's
   full-screen menu is untouched. */
@media (min-width:761px){
  .side{width:212px;flex:0 0 212px;padding:20px 12px 14px}
  .nav{gap:2px}
  .nav-it{padding:5px 9px;gap:10px;border-radius:12px}
  .nav-it .orb{width:32px;height:32px;flex:0 0 32px}
  .nav-it .orb svg{width:15px;height:15px}
  .nav-it .lbl{font-size:13.5px}
  .nav-sec{padding:11px 11px 4px;font-size:9px}
  .nav-sec:first-child{padding-top:0}
  .brand{padding:0 6px 16px;gap:10px}
  .brand-orb{width:38px;height:38px;flex:0 0 38px}
  .brand-orb svg{width:21px;height:21px}
  .brand-name{font-size:15.5px;letter-spacing:.2em}
}

/* ---------- dashboard: fewer words ----------
   The alert sub-lines carry the full statutory rule ("15 days from referral to
   the RPD (port-of-entry); inland claims file with the claim"), which belongs
   on the Protection Desk where the work happens — on the dashboard it turns a
   scannable list into a wall of prose. One line, ellipsis; the full text is a
   click away on the record. */
.db-arow-sub{
  white-space:nowrap;
  overflow:hidden;
  text-overflow:ellipsis;
  max-width:100%;
}
.db-arow-main{min-width:0}

/* ---------- pull to refresh ---------- */
.pr-ind{
  position:fixed;
  left:50%;
  top:0;
  z-index:58;                     /* under modals (100) and the menu, over content */
  transform:translate3d(-50%,0,0);
  opacity:0;
  pointer-events:none;
  will-change:transform,opacity;
}
.pr-ind.pr-snap{transition:transform .3s cubic-bezier(.2,.9,.3,1),opacity .3s ease}
.pr-orb{
  width:36px;height:36px;border-radius:50%;
  display:grid;place-items:center;
  color:var(--paper);
  background:radial-gradient(circle at 32% 28%,var(--gold-hi),var(--gold) 58%,var(--gold-deep));
  box-shadow:0 8px 20px -8px rgba(60,46,20,.55), 0 0 0 4px rgba(251,249,244,.9);
}
.pr-orb svg{width:19px;height:19px;display:block}
.pr-ind.pr-armed .pr-orb{box-shadow:0 10px 26px -8px rgba(60,46,20,.7), 0 0 0 5px rgba(251,249,244,.95)}
.pr-ind.pr-busy .pr-orb{animation:prSpin .9s linear infinite}
@keyframes prSpin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){
  .pr-ind.pr-busy .pr-orb{animation:none}
  .pr-ind.pr-snap{transition:opacity .2s ease}
}

/* ---------- residual clipping found in the final sweep ---------- */

/* Alert titles were nowrap+ellipsis, so a long one ("Job match date — Long-Haul
   Truck Driver (Class 1)") lost its tail on a phone. The title is the thing you
   read to decide whether to act — let it wrap to two lines. Only the sub-line
   stays a single clipped line. */
.db-arow-title{white-space:normal;overflow:visible;text-overflow:clip;line-height:1.3}
@media (max-width:760px){
  .db-arow{align-items:flex-start}
  .db-arow-meta{flex:0 0 auto;text-align:right}
}

@media (max-width:760px){
  /* Case-family names ("Humanitarian & Protection") don't fit a 92px label
     column. Give the practice-mix rows a label line of their own. */
  .fun-row{grid-template-columns:1fr 34px;grid-template-areas:"lbl n" "bar bar";row-gap:5px}
  .fun-lbl{grid-area:lbl;white-space:normal;line-height:1.25}
  .fun-n{grid-area:n}
  .fun-track{grid-area:bar;height:18px}

  /* the hydrated tick SVG rendered wider than its 22px box */
  .doc-it .doc-box{width:24px;height:24px;flex:0 0 24px;overflow:hidden}
  .doc-it .doc-box svg{width:12px;height:12px;flex:0 0 12px}

  /* long inline labels inside panels (CRS factor rows, firm settings) */
  .crs-wrap span,.panel label{overflow-wrap:anywhere}
  .frow,.fld{min-width:0}
}
@media (max-width:760px){
  /* practice-mix rows: the label cell needs to be allowed to shrink */
  .fun-row > *{min-width:0}
  .fun-row{box-sizing:border-box;max-width:100%}
  .funnel{min-width:0;max-width:100%}
}

/* The practice-mix rows are a grid; their cells default to min-width:auto and
   refuse to shrink, pushing the row ~6px past its container at every width.
   Not scoped to mobile — it was overflowing on desktop too. */
.fun-row > *{min-width:0}
.funnel,.fun-row{max-width:100%;box-sizing:border-box}
.fun-lbl{overflow:hidden;text-overflow:ellipsis}

/* ============================================================
   Dashboard layout — desktop first
   A single full-width column of alert rows reads as a phone
   notification list, not a dashboard. On a wide screen the action
   list is one column beside the revenue chart, and the visual
   panels use the remaining width.
   ============================================================ */
.db-top{
  display:grid;
  grid-template-columns:1.05fr 1fr;
  gap:14px;
  align-items:start;
  margin-bottom:14px;
}
.db-lower{
  display:grid;
  grid-template-columns:1fr 1fr 1fr;
  gap:14px;
  align-items:start;
}
.db-top > *,.db-lower > *{min-width:0}

/* The action list scrolls inside its own panel rather than pushing the whole
   page down — the practice can have twenty live deadlines. */
.db-actions-col .panel{max-height:432px;display:flex;flex-direction:column}
.db-actions-col .panel .panel-title{flex:0 0 auto}
.db-actions-col .db-groups,
.db-actions-col .panel > div:not(.panel-title){
  overflow-y:auto;
  min-height:0;
  scrollbar-width:thin;
  margin-right:-6px;
  padding-right:6px;
}
.db-chart-col .panel{min-height:432px}

@media (max-width:1100px){
  .db-lower{grid-template-columns:1fr 1fr}
}
@media (max-width:760px){
  .db-top,.db-lower{grid-template-columns:1fr;gap:10px;margin-bottom:10px}
  /* on a phone the deadline list is the whole point — let it run */
  .db-actions-col .panel{max-height:none;display:block}
  .db-actions-col .panel > div:not(.panel-title){overflow:visible;margin-right:0;padding-right:0}
  .db-chart-col .panel{min-height:0}
}

/* The revenue chart is a fixed 150px tall, so pinning its panel to the height of
   the action list left a dead band underneath. Let the chart grow into the space
   instead — a taller chart is also a more readable one. */
@media (min-width:761px){
  /* The bars are sized in % of .rev-stack, which is height:100% of .rev-wrap —
     so .rev-wrap needs a DEFINITE height. Setting it to flex/auto broke the
     percentage chain and the bars collapsed to zero. Give it a bigger fixed
     height instead; a taller chart is more readable anyway. */
  .db-chart-col .panel{display:flex;flex-direction:column}
  .db-chart-col .rev-wrap{height:292px;align-items:flex-end}
  .db-chart-col .legend{flex:0 0 auto;margin-top:auto;padding-top:10px}

  /* signal that the deadline list continues below the fold */
  .db-actions-col .panel{position:relative}
  .db-actions-col .panel::after{
    content:"";position:absolute;left:1px;right:1px;bottom:1px;height:34px;
    border-radius:0 0 var(--r-lg) var(--r-lg);
    background:linear-gradient(180deg,rgba(255,255,255,0),rgba(252,250,246,.96));
    pointer-events:none;
  }
}

/* QR intake, surfaced from the Intake page rather than its own nav tab */
.intake-qr-strip{
  display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;
  border:1px solid var(--stroke-soft);border-radius:var(--r-md);
  background:linear-gradient(180deg,rgba(216,184,119,.12),rgba(216,184,119,.04));
  padding:13px 18px;margin:16px 0 4px;
}
.intake-qr-strip b{font-family:var(--disp);font-size:14px;display:block}
.intake-qr-strip .muted{font-size:12.5px}
@media (max-width:760px){
  .intake-qr-strip{padding:12px 14px;margin:12px 0 4px}
  .intake-qr-strip button{width:100%}
}

/* ============================================================
   Worker / student dossier — identity band
   The passport belongs beside the person's name and key dates, not
   below the tabs: it IS their identity, and a consultant checking a
   permit expiry wants the passport in the same glance. Two columns on
   a wide screen — the passport narrow, the dates given the room.
   ============================================================ */
.wk-idband{
  display:grid;
  grid-template-columns:minmax(300px,0.85fr) 1.6fr;
  gap:20px;
  align-items:start;
  margin-top:22px;
  padding-top:18px;
  border-top:1px solid rgba(169,130,76,.18);
}
.wk-idband > *{min-width:0}
.wk-idband-pp .pp-wrap{margin-bottom:0;gap:9px}
.wk-idband-pp .pp-book{max-width:none}
.wk-idband-pp .pp-disclaimer{font-size:10.5px;padding-top:8px}
/* the stats strip already had its own top border in .dh-stats — the band owns it now */
.wk-idband .dh-stats{margin-top:0;padding-top:0;border-top:0}

@media (max-width:1100px){
  .wk-idband{grid-template-columns:1fr;gap:14px}
}
@media (max-width:760px){
  /* on a phone the dates matter first; the passport follows */
  .wk-idband{margin-top:14px;padding-top:12px;gap:12px}
  .wk-idband-pp{order:2}
  .wk-idband .dh-stats{order:1}
}

/* ============================================================
   IDENTITY TILES (28 Sep 2026)
   The passport and work permit as compact tiles on the worker file; a click
   opens the full replica in a pop-up (worker.js — wkIdTiles / openIdDoc).
   Drawn full size they stood ~550px tall and pushed the tab bar below the
   fold. Styled as siblings of the .dh-stat boxes beside them, so the band
   reads as one strip of facts, with a small cover swatch so the passport is
   still recognisable at a glance.
   ============================================================ */
.wk-idband.wk-idband-tiles{grid-template-columns:auto minmax(0,1fr);align-items:center;gap:18px}
.wk-idtiles{display:flex;gap:10px}
.wk-idtile{
  display:flex;align-items:center;gap:12px;width:248px;
  padding:9px 14px 9px 9px;
  background:rgba(255,255,255,.72);border:1px solid var(--stroke-soft);border-radius:18px;
  font:inherit;color:inherit;text-align:left;cursor:pointer;
  transition:border-color .18s, box-shadow .18s, transform .18s;
}
.wk-idtile:hover{border-color:rgba(169,130,76,.45);box-shadow:var(--shadow-soft);transform:translateY(-1px)}
.wk-idtile:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
/* A passport is portrait, a permit is landscape — the swatch keeps the shape. */
.wk-idtile-cover{
  flex:0 0 auto;width:40px;height:54px;border-radius:5px;
  display:grid;place-items:center;
  background:var(--wk-cover,#22303F);color:rgba(255,255,255,.86);
  font-size:9.5px;font-weight:700;letter-spacing:.14em;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.10), 0 2px 6px -2px rgba(0,0,0,.35);
}
/* A real flag (28 Sep 2026): 4:3, like the files, with a hairline so a white
   field (Japan, Canada's edges) does not melt into the tile. */
.wk-idtile-flag{flex:0 0 auto;width:48px;height:36px;border-radius:5px;overflow:hidden;display:block;
  box-shadow:0 0 0 1px rgba(26,27,24,.12),0 2px 6px -2px rgba(0,0,0,.30)}
.wk-idtile-flag img{width:100%;height:100%;object-fit:cover;display:block}
.wk-idtile-wp .wk-idtile-cover{
  width:54px;height:40px;
  background:linear-gradient(103deg,#1E4F44 0%,#2A6B58 46%,#1B4A40 100%);
}
.wk-idtile-body{display:flex;flex-direction:column;gap:1px;min-width:0;flex:1}
.wk-idtile-k{font-size:10.5px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-faint)}
.wk-idtile-v{font-size:14.5px;font-weight:600;letter-spacing:.02em;font-variant-numeric:tabular-nums;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.wk-idtile-v .muted{font-size:12.5px;font-weight:400}
.wk-idtile-s{font-size:12px;color:var(--ink-soft);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.wk-idtile-go{flex:0 0 auto;font-size:11.5px;font-weight:600;color:var(--gold-deep);letter-spacing:.02em}
/* five stat boxes on one line beside the tiles, not two rows */
.wk-idband-tiles .dh-stat{min-width:118px}
/* the replicas in the pop-up: no trailing gap under the card */
.wk-iddoc-modal .pp-wrap,.wk-iddoc-modal .wp-wrap{margin-bottom:0}

@media (max-width:1100px){
  .wk-idband.wk-idband-tiles{grid-template-columns:1fr}
}
@media (max-width:760px){
  .wk-idtiles{display:grid;grid-template-columns:1fr 1fr;order:2}
  .wk-idtile{width:auto}
}
@media (max-width:440px){
  .wk-idtiles{grid-template-columns:1fr}
}
