/* WRG Pulse — the shell and the shared pieces every rebuilt screen draws with.
 *
 * Layered over tokens.css, which is the White Rabbit Group design system's own generated
 * token file and is not edited here. Everything in this file is either the shell (top bar,
 * tabs, page frame) or a piece more than one screen uses: cards, pills, the RAG chip, the
 * mono label, the number style, tables.
 *
 * styles.css is still loaded alongside this, and still owns the four record screens that came
 * across from the previous build — Discovery, New Projects, Quality Concerns and their edit
 * drawers. Making those read as part of this design system is the work that follows the
 * rebuild, and the design canvas says so in as many words. The two stylesheets are scoped
 * apart: everything here is under `.pulse`, and no rule in this file is written bare.
 */

.pulse {
  --pg: var(--rabbit-white);
  --card: var(--white);
  --tint: var(--surface-tint);
  --ink: var(--black-950);
  --ink2: var(--black-750);
  --ink3: var(--black-550);
  --hair: var(--black-150);
  --rule: var(--black-750);
  /* Amber and green are not in the design system's token set — it carries one accent, red.
     These two are the design's own, and they are chosen to differ in LIGHTNESS as well as
     hue so the three bands are still three things in greyscale and to a red-green colour
     blind reader: the RAG chip always carries its word as well as its dot for the same
     reason. */
  --amber: #e09a2b;
  --green: #2e9e5b;
  --blue: #3a6fd8;
  --client: var(--black-950);
  --internal: var(--black-350);
  font-family: var(--font-display);
  font-size: 15px;
  line-height: 1.45;
  letter-spacing: -.005em;
  color: var(--ink);
  background: var(--pg);
  min-height: 100vh;
  font-variant-numeric: tabular-nums;
  box-sizing: border-box;
}

.pulse * { box-sizing: border-box; }
.pulse p { margin: 0; }
.pulse a { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
.pulse a:hover { color: var(--red); }

/* Dark is driven by the viewer's own setting; there is no theme switch in the product.
   A dashboard somebody leaves open all day on a second monitor should follow the desk it
   sits on, and a switch is one more piece of state to keep per account. */
@media (prefers-color-scheme: dark) {
  .pulse {
    --pg: var(--black-950);
    --card: var(--black-850);
    --tint: #1d1d1b;
    --ink: var(--rabbit-white);
    --ink2: var(--black-250);
    --ink3: var(--black-350);
    --hair: var(--black-750);
    --rule: var(--black-350);
    --blue: #7ea3f0;
    --client: var(--rabbit-white);
    --internal: var(--black-550);
    color-scheme: dark;
  }
}

/* ------------------------------------------------------------------- the top bar */

.pulse__bar {
  background: var(--surface-dark);
  color: var(--rabbit-white);
  padding: 0 var(--gutter-header);
}
.pulse__bar-inner {
  max-width: 1440px;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: center;
  min-height: 68px;
}
.pulse a.pulse__brand {
  display: flex;
  align-items: center;
  gap: 12px;
  color: inherit;
  text-decoration: none;
  flex: none;
  letter-spacing: -.02em;
  white-space: nowrap;
}
/* Both selectors here carry the element as well as the class, and that is the point: `.pulse a`
   above underlines every link at rest, and styles.css — which loads after this file — adds a
   bare `a:hover{text-decoration:underline}`. A plain `.pulse__brand` loses to both, which is
   how the wordmark came to sit on a line. Neutralised in every state rather than only at rest:
   a logo that gains an underline reads as a broken link. */
.pulse a.pulse__brand:hover, .pulse a.pulse__brand:focus-visible, .pulse a.pulse__brand:active {
  color: inherit;
  text-decoration: none;
}
.pulse__brand-name { display: block; font-size: 20px; line-height: 1.15; }
.pulse__brand-sub {
  display: block;
  font-family: var(--font-mono-accent);
  font-size: 10.5px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: rgba(250, 250, 249, .55);
}
.pulse__mark { width: 19px; height: 22px; display: block; flex: none; }
.pulse__nav { display: flex; flex-wrap: wrap; align-self: stretch; margin-left: 8px; }
.pulse__nav a {
  border: 0;
  background: none;
  padding: 0 14px;
  min-height: 68px;
  display: inline-flex;
  align-items: center;
  font-family: var(--font-mono-primary);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--black-350);
  border-bottom: 2px solid transparent;
  text-decoration: none;
}
.pulse__nav a:hover { color: var(--rabbit-white); }
.pulse__nav a[aria-current="page"] { color: var(--rabbit-white); border-bottom-color: var(--red); }
.pulse__who {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--black-350);
  white-space: nowrap;
}
.pulse__role {
  font-family: var(--font-mono-primary);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  border-radius: var(--radius-pill);
  box-shadow: inset 0 0 0 1px var(--black-550);
  padding: 3px 10px;
  color: var(--rabbit-white);
}
.pulse__bar-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: 0;
  border-radius: var(--radius-pill);
  padding: 9px 16px;
  font-family: var(--font-display);
  font-size: 14px;
  background: transparent;
  color: var(--rabbit-white);
  box-shadow: inset 0 0 0 1px var(--black-550);
  cursor: pointer;
  text-decoration: none;
}
.pulse__bar-btn:hover { background: rgba(250, 250, 249, .08); color: var(--rabbit-white); }
.pulse__bar-btn[disabled] { opacity: .5; cursor: progress; }

.pulse__tabs {
  background: var(--card);
  box-shadow: inset 0 -1px 0 var(--hair);
  padding: 0 var(--gutter-header);
}
.pulse__tabs-inner {
  max-width: 1440px;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
}
.pulse__tabs a {
  padding: 0 14px;
  min-height: 48px;
  display: inline-flex;
  align-items: center;
  font-size: 14.5px;
  letter-spacing: -.01em;
  color: var(--ink3);
  text-decoration: none;
}
.pulse__tabs a:hover { color: var(--ink); }
.pulse__tabs a[aria-current="page"] { color: var(--ink); box-shadow: inset 0 -2px 0 var(--ink); }

/* --------------------------------------------------------------------- page frame */

.pulse__main {
  max-width: 1440px;
  margin: 0 auto;
  padding: 28px var(--gutter-header) 64px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}
.pulse .h1 { margin: 0; font-weight: 300; font-size: 44px; line-height: 1; letter-spacing: -.04em; }
.pulse .h2 { margin: 0; font-weight: 300; font-size: 30px; line-height: 1.05; letter-spacing: -.035em; }
.pulse .h3 { margin: 0; font-weight: 400; font-size: 20px; line-height: 1.15; letter-spacing: -.02em; }
.pulse .accent { display: inline-block; width: 28px; height: 3px; background: var(--red); }
.pulse .mono {
  font-family: var(--font-mono-primary);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--ink3);
}
.pulse .p-num { font-family: var(--font-mono-accent); letter-spacing: -.03em; }
.pulse .row { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.pulse .sp { flex: 1; }
.pulse .muted { color: var(--ink3); }
.pulse .ink2 { color: var(--ink2); }
.pulse .small { font-size: 14px; }
.pulse .xs { font-size: 12px; }
.pulse .r { text-align: right; font-family: var(--font-mono-accent); letter-spacing: -.03em; white-space: nowrap; }

.pulse .p-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 0;
  border-radius: var(--radius-pill);
  padding: 7px 14px;
  font-family: var(--font-display);
  font-size: 14px;
  cursor: pointer;
  white-space: nowrap;
  background: transparent;
  color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--hair);
  text-decoration: none;
}
.pulse .p-pill:hover { color: var(--ink); background: var(--tint); }
.pulse .p-pill.on { background: var(--ink); color: var(--pg); box-shadow: none; }
.pulse .p-pill.on:hover { background: var(--ink); color: var(--pg); }
.pulse .p-pill[disabled] { opacity: .45; cursor: not-allowed; }
.pulse .pill--dark { background: var(--ink); color: var(--pg); box-shadow: none; }
.pulse .pill--dark:hover { background: var(--ink2); color: var(--pg); }
/* Wraps. A six-option segmented control is 477px wide, and on a phone an unwrapped one
   stretches the card it is in past the viewport — which also defeats the `overflow-x: auto`
   on the table below it, because that scroller is then wider than the screen too. */
.pulse .p-seg { display: inline-flex; gap: 4px; flex-wrap: wrap; }

.pulse .p-card {
  background: var(--card);
  border-radius: var(--radius-card);
  box-shadow: inset 0 0 0 1px var(--hair);
}
.pulse .p-card__head {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  padding: 18px 20px 12px;
}
.pulse .p-card__body { padding: 0 20px 20px; }

.pulse .p-kpis { display: flex; flex-wrap: wrap; gap: 12px; }
.pulse .p-kpi {
  flex: 1 1 170px;
  background: var(--card);
  border-radius: var(--radius-card);
  box-shadow: inset 0 0 0 1px var(--hair);
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.pulse .p-kpi .v { font-family: var(--font-mono-accent); font-size: 28px; line-height: 1; letter-spacing: -.05em; }

/* The RAG chip and the three band colours. The chip always carries its word, never a bare
   dot: colour alone is not a label. */
.pulse .rag {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  border-radius: var(--radius-pill);
  box-shadow: inset 0 0 0 1px var(--hair);
  padding: 3px 11px 3px 9px;
  font-family: var(--font-mono-primary);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--ink);
}
.pulse .rag i, .pulse .dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; flex: none; }
.pulse .red i, .pulse .dot.red, .pulse .bar.red { background: var(--red); }
.pulse .amber i, .pulse .dot.amber, .pulse .bar.amber { background: var(--amber); }
.pulse .green i, .pulse .dot.green, .pulse .bar.green { background: var(--green); }
/* An indicator nothing could answer. Hollow, not grey-filled: an empty ring reads as absent
   where a filled grey dot reads as a fourth status somebody assigned. */
.pulse .none i, .pulse .dot.none, .pulse .bar.none { background: transparent; box-shadow: inset 0 0 0 1.5px var(--ink3); }

.pulse .bar { display: block; height: 6px; border-radius: 3px; background: var(--tint); }
.pulse .p-areas { display: grid; grid-template-columns: repeat(6, minmax(58px, 1fr)); gap: 8px; min-width: 420px; }
.pulse .p-area {
  display: flex;
  flex-direction: column;
  gap: 5px;
  font-family: var(--font-mono-primary);
  font-size: 10.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink3);
}

/* The utilisation pill: blue under, green in band, red over. */
.pulse .u {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border-radius: var(--radius-pill);
  padding: 2px 10px;
  font-family: var(--font-mono-accent);
  font-size: 13px;
  white-space: nowrap;
  color: var(--ink);
}
.pulse .u:before { content: ""; width: 7px; height: 7px; border-radius: 50%; }
.pulse .u.good { background: color-mix(in srgb, var(--green) 14%, transparent); }
.pulse .u.good:before { background: var(--green); }
.pulse .u.over { background: color-mix(in srgb, var(--red) 16%, transparent); }
.pulse .u.over:before { background: var(--red); }
.pulse .u.under { background: color-mix(in srgb, var(--blue) 16%, transparent); }
.pulse .u.under:before { background: var(--blue); }

.pulse .p-tag {
  display: inline-flex;
  border-radius: var(--radius-pill);
  box-shadow: inset 0 0 0 1px var(--hair);
  padding: 1px 9px;
  font-size: 12px;
  color: var(--ink2);
  white-space: nowrap;
}
/* A dashed outline for internal work, so client and internal differ in more than colour. */
.pulse .p-tag.int { box-shadow: none; border: 1px dashed var(--ink3); }
/* A tag that has to be noticed. Red outline and a red dot, ink text — the word never relies
   on the hue to be read, which is also what keeps it above 4.5:1 in both themes. */
.pulse .p-tag--alarm {
  box-shadow: inset 0 0 0 1px var(--red);
  color: var(--ink);
  align-items: center;
  gap: 6px;
}

.pulse .tw { overflow-x: auto; }
.pulse table { border-collapse: collapse; width: 100%; font-size: 14px; }
.pulse th {
  font-family: var(--font-mono-primary);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--ink3);
  text-align: left;
  padding: 11px 14px;
  border-bottom: 1px solid var(--rule);
  white-space: nowrap;
}
.pulse td { padding: 14px; border-bottom: 1px solid var(--hair); vertical-align: middle; }
.pulse tbody tr:last-child td { border-bottom: 0; }
.pulse tr.click { cursor: pointer; }
.pulse tr.click:hover { background: var(--tint); }
.pulse tr.tot td { border-top: 1px solid var(--rule); font-weight: 500; }

.pulse .p-field { display: flex; flex-direction: column; gap: 6px; }
.pulse .p-field input,
.pulse .p-field select,
.pulse .p-field textarea {
  font: inherit;
  font-size: 14.5px;
  color: var(--ink);
  background: var(--card);
  border: 0;
  box-shadow: inset 0 0 0 1px var(--hair);
  border-radius: var(--radius-card);
  padding: 10px 12px;
  width: 100%;
}
.pulse .p-field input[disabled] { color: var(--ink3); }
/* The in-table control (the Access card's role picker). Built to the p-tag's measurements
   rather than the p-field input's, because it sits in a table cell where that tag used to be:
   a form-sized control in a row of 12px text sets the row height for the whole table. The
   native appearance is dropped for the same reason — the platform arrow carries its own
   padding and chrome, which is what made the first attempt twice the height of its row. */
.pulse .p-select {
  appearance: none;
  font: inherit;
  font-size: 12px;
  line-height: 1.5;
  color: var(--ink2);
  background: transparent;
  border: 0;
  box-shadow: inset 0 0 0 1px var(--hair);
  border-radius: var(--radius-pill);
  padding: 1px 24px 1px 9px;
  cursor: pointer;
  /* currentColor cannot be used inside a data URI, so the caret is drawn in the same grey the
     text is and both themes read it against their own surface. */
  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238a8a85' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 8px center;
  background-size: 11px;
}
.pulse .p-select:hover { color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink3); }
/* A filter box in a page head: the p-field input's frame, sized to itself rather than to a
   column, because it sits beside a heading and not in a form. */
.pulse .p-search {
  font: inherit;
  font-size: 13.5px;
  color: var(--ink);
  background: var(--card);
  border: 0;
  box-shadow: inset 0 0 0 1px var(--hair);
  border-radius: var(--radius-pill);
  padding: 8px 14px;
  width: 240px;
  max-width: 100%;
}
.pulse .p-search::placeholder { color: var(--ink3); }
.pulse .p-search:focus { outline: 0; box-shadow: inset 0 0 0 1px var(--ink2); }
.pulse .p-select[disabled] { color: var(--ink3); cursor: progress; }
.pulse .p-hint { font-size: 12px; color: var(--ink3); }
.pulse .cell {
  width: 64px;
  text-align: right;
  font-family: var(--font-mono-accent);
  font-size: 14px;
  color: var(--ink);
  background: var(--card);
  border: 0;
  box-shadow: inset 0 0 0 1px var(--hair);
  border-radius: 8px;
  padding: 6px 8px;
}
.pulse .search {
  font: inherit;
  font-size: 14px;
  color: var(--ink);
  background: var(--card);
  border: 0;
  box-shadow: inset 0 0 0 1px var(--hair);
  border-radius: var(--radius-pill);
  padding: 7px 14px;
  min-width: 200px;
}

/* A card drawn where data would be, when there is none to draw. The four kinds are four
   different sentences — no source configured, never synced, synced and empty, not allowed —
   and this is only the box they sit in. */
.pulse .nodata {
  background: var(--card);
  border-radius: var(--radius-card);
  box-shadow: inset 0 0 0 1px var(--hair);
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: 78ch;
}
.pulse .nodata h3 { margin: 0; font-weight: 400; font-size: 18px; letter-spacing: -.02em; }
.pulse .nodata p { color: var(--ink2); font-size: 14.5px; }
/* The same box in red, for a refusal rather than an absence. */
.pulse .nodata--stop { background: color-mix(in srgb, var(--red) 8%, var(--card)); }

.pulse .p-note {
  border-radius: var(--radius-card);
  background: color-mix(in srgb, var(--red) 10%, var(--card));
  padding: 12px 14px;
  font-size: 14px;
  display: flex;
  gap: 10px;
  align-items: flex-start;
}
.pulse .p-note:before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--red);
  margin-top: 7px;
  flex: none;
}

/* The indicator drill-down, which is a panel beside the page on a desktop and a sheet from
   the bottom on a phone. Not a dialog element: it never traps, and the page behind it stays
   readable, which is the point of a drill-down. */
.pulse__drill {
  position: fixed;
  inset: 0 0 0 auto;
  width: min(560px, 100vw);
  background: var(--card);
  border-left: 1px solid var(--hair);
  box-shadow: -12px 0 40px rgba(8, 8, 7, .12);
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  z-index: 40;
}
.pulse__drill-head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 20px 24px;
  border-bottom: 1px solid var(--rule);
  position: sticky;
  top: 0;
  background: var(--card);
}
.pulse__drill-close {
  border: 0;
  background: none;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-pill);
  color: var(--ink);
  cursor: pointer;
  flex: none;
}
.pulse__drill-close:hover { background: var(--tint); }
.pulse__drill-body { padding: 16px 24px 32px; display: flex; flex-direction: column; gap: 6px; }
.pulse .it {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 4px 12px;
  padding: 14px 0;
  border-top: 1px solid var(--hair);
}
.pulse .due { font-family: var(--font-mono-accent); font-size: 13px; white-space: nowrap; text-align: right; }

/* Focus is never removed, only restyled: a ring that follows the ink colour reads in both
   themes, which `outline: none` plus a box-shadow would not. */
.pulse :focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }

.pulse .sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ------------------------------------------------------------------- phone width */

@media (max-width: 1100px) {
  .pulse .p-areas { grid-template-columns: repeat(3, minmax(0, 1fr)); min-width: 0; }
}

@media (max-width: 760px) {
  .pulse__bar, .pulse__tabs, .pulse__main { padding-left: 16px; padding-right: 16px; }
  .pulse__main { padding-top: 18px; gap: 14px; }
  .pulse .h1 { font-size: 32px; line-height: 1.04; }
  .pulse__nav { margin-left: 0; width: 100%; overflow-x: auto; }
  .pulse__nav a { min-height: 48px; }
  .pulse__who { order: 3; }
  /* The drill-down becomes a bottom sheet: a 560px panel on a 390px screen is the page. */
  .pulse__drill { inset: auto 0 0 0; width: 100%; max-height: 86vh; border-left: 0; border-top: 1px solid var(--hair); }
  /* Wide tables scroll inside their card rather than the page. */
  .pulse .tw { -webkit-overflow-scrolling: touch; }
}

/* ------------------------------------------------- the indicator list on a project */

.pulse .sec { overflow: hidden; }
.pulse .sh {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 20px;
  border-bottom: 1px solid var(--rule);
}
.pulse .ind, .pulse .hd {
  display: grid;
  grid-template-columns: 28px minmax(170px, 1.1fr) 120px minmax(170px, 1.2fr) minmax(200px, 1.5fr) minmax(200px, 1.4fr) 110px;
  gap: 16px;
  align-items: start;
}
.pulse .hd { padding: 10px 20px; background: var(--tint); }
.pulse .ind { padding: 16px 20px; border-top: 1px solid var(--hair); font-size: 14px; }
.pulse .ind:first-of-type { border-top: 0; }
.pulse .ind .n { padding-top: 3px; }
/* An indicator with no source is quieter than one that scored, and its rule still reads. */
.pulse .ind--none { background: color-mix(in srgb, var(--tint) 60%, transparent); }

@media (max-width: 1100px) {
  .pulse .ind, .pulse .hd { grid-template-columns: 28px minmax(0, 1fr) auto; }
  .pulse .ind > .wide { grid-column: 2 / -1; }
  /* The column headings stack into a list of words once the columns are gone, which reads as
     four headings over one column. The row below still labels its own parts, so the wide
     headings are dropped rather than stacked. */
  .pulse .hd > .wide { display: none; }
  .pulse .ind--none .wide[style] { grid-column: 2 / -1 !important; }
}

/* The skip link, which is the first thing in the document and visible only on focus. */
.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--black-950);
  color: var(--rabbit-white);
  padding: 12px 18px;
  z-index: 100;
}
.skip:focus { left: 0; }

/* --------------------------------------------------------- the allocation team list */

.pulse .team {
  background: var(--card);
  border-radius: var(--radius-card);
  box-shadow: inset 0 0 0 1px var(--hair);
  overflow: hidden;
}
.pulse .th {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  align-items: center;
  padding: 16px 20px;
  border-bottom: 1px solid var(--rule);
}
.pulse .p-grp { padding: 8px 20px; background: var(--tint); display: flex; gap: 12px; align-items: center; }
.pulse .p, .pulse .ph {
  display: grid;
  grid-template-columns: minmax(150px, 1fr) minmax(220px, 1.6fr) 90px 90px 110px minmax(180px, 1.4fr);
  gap: 16px;
  align-items: center;
}
.pulse .ph { padding: 10px 20px; }
.pulse .p { padding: 12px 20px; border-top: 1px solid var(--hair); font-size: 14px; }

/* The allocation bar: a DM's standing hours first, then the hours ClickUp tasks imply, with
   a tick at the day's length. The two sources differ in lightness, not only in hue. */
.pulse .alloc { position: relative; height: 10px; border-radius: 5px; background: var(--tint); }
.pulse .alloc span { position: absolute; top: 0; bottom: 0; }
.pulse .alloc .c { background: var(--client); border-radius: 5px 0 0 5px; }
.pulse .alloc .i { background: var(--internal); }
.pulse .alloc .t { position: absolute; top: -4px; bottom: -4px; width: 2px; background: var(--red); left: 83%; }

/* The utilisation heat grid. */
.pulse .heat {
  display: grid;
  grid-template-columns: minmax(130px, 1.2fr) repeat(5, minmax(70px, 1fr)) minmax(80px, 1fr);
  gap: 6px;
  align-items: center;
  font-size: 14px;
}
.pulse .c-cell {
  text-align: center;
  padding: 10px 0;
  border-radius: var(--radius-card);
  font-family: var(--font-mono-accent);
  font-size: 13px;
  color: var(--ink);
  background: var(--tint);
}
.pulse .c-cell.good { background: color-mix(in srgb, var(--green) 22%, transparent); }
.pulse .c-cell.over { background: color-mix(in srgb, var(--red) 24%, transparent); }
.pulse .c-cell.under { background: color-mix(in srgb, var(--blue) 22%, transparent); }

.pulse .split {
  display: flex;
  height: 10px;
  border-radius: 5px;
  overflow: hidden;
  background: var(--tint);
  min-width: 140px;
}
.pulse .split span { display: block; height: 100%; }
.pulse .two { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.pulse .layout { display: grid; grid-template-columns: minmax(300px, 420px) minmax(0, 1fr); gap: 16px; align-items: start; }

/* The leave calendar. */
.pulse .p-cal { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 6px; }
.pulse .day {
  border-radius: var(--radius-card);
  background: var(--tint);
  padding: 8px 10px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-height: 58px;
}
.pulse .day b { font-family: var(--font-mono-accent); font-weight: 400; font-size: 13px; }
.pulse .day.today { box-shadow: inset 0 0 0 1.5px var(--ink); }
.pulse .day.has { background: color-mix(in srgb, var(--red) 10%, var(--card)); }
.pulse .day .lv { font-size: 12px; color: var(--ink2); }
.pulse .li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: 12px;
  padding: 12px 0;
  border-top: 1px solid var(--hair);
  align-items: center;
  font-size: 14px;
}
.pulse .chipi {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border-radius: var(--radius-pill);
  background: var(--tint);
  padding: 3px 6px 3px 11px;
  font-size: 13.5px;
}
.pulse .chipi button {
  border: 0;
  background: none;
  color: var(--ink3);
  width: 22px;
  height: 22px;
  border-radius: 50%;
  cursor: pointer;
  font: inherit;
}
.pulse .chipi button:hover { background: var(--hair); color: var(--ink); }

@media (max-width: 1100px) {
  .pulse .p, .pulse .ph { grid-template-columns: minmax(0, 1fr) auto auto; }
  .pulse .p > .hide, .pulse .ph > .hide { display: none; }
  .pulse .two, .pulse .layout { grid-template-columns: minmax(0, 1fr); }
}

.pulse .p-inputs { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 14px; }
/* Checkboxes in the access matrix: big enough to hit, and visibly disabled where a cell is
   locked rather than silently inert. */
.pulse input[type="checkbox"] { width: 18px; height: 18px; accent-color: var(--red); cursor: pointer; }
.pulse input[type="checkbox"][disabled] { cursor: not-allowed; opacity: .45; }

/* The router paints into #page, so the main column's gap falls between the heading and the
   page rather than between the page's own sections. The same column, repeated one level in. */
.pulse__main > #page { display: flex; flex-direction: column; gap: 20px; }

/* The screens still drawn by styles.css — Discovery Tracker, New Projects, Quality Concerns,
   their edit drawers, and the project record.
 *
 * They are NOT pinned to a light palette. styles.css separates its brand palette from a
 * semantic layer and says so in its own comment — "semantic — override these for themes" —
 * and it carries a commented dark stub that was never filled in. This is that stub, filled
 * in against the Pulse tokens, so those screens follow the viewer's theme like everything
 * else rather than arriving as a white slab in a dark shell.
 *
 * Only the semantic names are redefined. The brand palette above them is untouched: red is
 * red in both themes, and remapping `--wrg-white` would change what every derived token
 * means. This is a theme, not a re-skin, and the rebuild of these screens onto the design
 * system is still the work that follows.
 *
 * Light needs no block at all — styles.css's own `:root` values are the light theme. */
.pulse #page.legacy { color-scheme: light; }

@media (prefers-color-scheme: dark) {
  .pulse #page.legacy {
    color-scheme: dark;

    --bg-app: var(--pg);
    --bg-surface: var(--card);
    --bg-subtle: var(--tint);
    --bg-hover: var(--black-750);
    --border: var(--hair);
    --border-strong: var(--black-550);
    --text: var(--ink);
    --text-muted: var(--ink2);
    --text-faint: var(--ink3);
    /* Text that sits ON an inverted chip. The inverted surface is light in a dark theme, so
       the text on it is dark — the opposite of its light-theme value, which is the whole
       point of the name. */
    --text-invert: var(--black-950);

    /* The three status hues. Their light-theme values are dark inks on pale tints, and both
       halves have to flip: the ink lightens so it reads on a dark card, and the tint becomes
       a low-alpha wash of the same hue rather than a near-white pastel. Mixed against the
       card rather than against transparent, so a chip on the page and a chip inside a drawer
       land on the same colour. */
    /* The ink is lighter than the hue its tint is mixed from, deliberately. An alert sets its
       text to `--ok`/`--warn`/`--info` and its background to the matching `*-soft`, so the
       two are measured against each other: a mid-tone ink on an 18% wash of the same mid-tone
       lands at about 2.7:1. These pass 4.5:1 on their own tint, which is the only pairing
       that occurs. */
    --ok: #9fdcbb;
    --ok-soft: color-mix(in srgb, #5fbf8a 18%, var(--card));
    --warn: #ecd292;
    --warn-soft: color-mix(in srgb, #d9ab4e 18%, var(--card));
    --info: #b3cbf8;
    --info-soft: color-mix(in srgb, #7ea3f0 18%, var(--card));
    /* The red tint behind a danger pill, for the same reason. */
    --wrg-red-soft: color-mix(in srgb, var(--red) 20%, var(--card));

    /* Shadows are black on black here, which reads as nothing. Depth comes from the hairline
       borders in this theme, so the two biggest ones are dropped to a hint and the rest stay
       as they are — a raised card with no visible shadow is correct, a card with a black
       smear under it is not. */
    --sh-2: 0 2px 10px rgba(0, 0, 0, .35);
    --sh-3: 0 12px 34px rgba(0, 0, 0, .5);

    /* Two of the brand neutrals are flipped after all, and only these two. Both are used
       directly as the EMPTY half of a measure — a meter's unlit ticks, a progress track, a
       bar's second segment, a soft avatar, an agenda's rule. Left light they become the
       loudest thing on a dark card, so every meter reads inverted: the part with no value in
       it is the part that shines. Flipping them is what keeps "empty" quiet.

       The other brand values are untouched. Red is red in both themes, and `--wrg-grey-900`
       stays dark because it is a SURFACE as often as a mark — `.btn--dark`, the today cell,
       the avatar chip and the active page number all put a hard-coded white on it, and a
       light fill under white text is unreadable. The marks that use it are re-pointed
       below instead. */
    --wrg-grey-100: var(--tint);
    --wrg-grey-200: var(--black-750);
  }

  /* The data marks that drew themselves in `--wrg-grey-900`. Each is a line or a fill with no
     text on it, so it wants the ink colour of the theme rather than a fixed near-black — on a
     dark card the near-black ones vanish into it, which is the other half of the inverted
     meter above. Only the marks are listed: the surfaces that carry white text keep their
     dark fill, which is correct in both themes. */
  .pulse #page.legacy .meter__ticks i.on,
  .pulse #page.legacy .bars__seg,
  .pulse #page.legacy .progress__fill { background: var(--ink); }
  .pulse #page.legacy .kpi__spark path,
  .pulse #page.legacy .area .series { stroke: var(--ink); }
  .pulse #page.legacy .meter__caret { border-top-color: var(--ink); }
  .pulse #page.legacy .tab.is-active { border-bottom-color: var(--ink); }

  /* The four alert variants are the one place styles.css does not go through its own tokens:
     each hard-codes a dark ink and a pale border beside its `*-soft` background. Those inks
     were chosen against a pale tint and land at 2.7:1 on a dark one, so each is re-pointed at
     the token its background already uses. */
  .pulse #page.legacy .alert--ok { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 35%, transparent); }
  .pulse #page.legacy .alert--warn { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 35%, transparent); }
  .pulse #page.legacy .alert--info { color: var(--info); border-color: color-mix(in srgb, var(--info) 35%, transparent); }
  .pulse #page.legacy .alert--danger {
    color: #f6a9a6;
    border-color: color-mix(in srgb, var(--red) 40%, transparent);
  }
}

/* ------------------------------------------------------- the delivery overview */

/* `.hint` is styles.css's class and the one `projectHints` emits. It is aliased rather than
   renamed because that function's markup is pinned by tests/public/overview-view.test.ts, and
   the wording is what those tests are about — not which stylesheet colours it. */
.pulse .hint { font-size: 12px; color: var(--ink3); }

/* The three shared empty-state cards (notConfiguredCard, neverSyncedCard, noRowsVisibleCard)
   are still the ones the screens they link to use, so this screen cannot describe a situation
   differently from the screen beside it. They emit styles.css's class names; these four rules
   give them the Pulse surface so they do not arrive as a white box in a dark shell. Scoped to
   `#page:not(.legacy)`, so the record screens still drawn by styles.css keep theirs. */
.pulse #page:not(.legacy) .card {
  background: var(--card);
  border-radius: var(--radius-card);
  box-shadow: inset 0 0 0 1px var(--hair);
  color: var(--ink);
}
.pulse #page:not(.legacy) .card__body { padding: 20px; font-size: 14.5px; }
.pulse #page:not(.legacy) .card__body p + p { margin-top: 8px; }
/* `dash()` in shared.js renders an em dash as `.cell-muted`, and the rebuilt Delivery
   overview uses it — so one class from the old stylesheet reaches a screen that is not
   `.legacy` and therefore gets no token mapping. It is coloured here rather than by changing
   `dash()`, whose markup three other screens depend on. */
.pulse #page:not(.legacy) .cell-muted { color: var(--ink3); }
.pulse #page:not(.legacy) .card code {
  font-family: var(--font-mono-primary);
  font-size: 12.5px;
  background: var(--tint);
  border-radius: 6px;
  padding: 1px 6px;
}

/* The roll-up table beside its rail. One column under 1000px — a 320px rail next to a
   five-column table is neither. */
.pulse .ov { display: grid; grid-template-columns: minmax(0, 2fr) minmax(280px, 1fr); gap: 16px; align-items: start; }

/* Where the work sits: a label row over a bar, per state. */
.pulse .wk { display: flex; flex-direction: column; gap: 6px; padding: 8px 0; }
.pulse .wk__meta { display: flex; justify-content: space-between; align-items: baseline; font-size: 14px; }
.pulse .wk__meta b { font-weight: 400; }

/* This week: a date gutter beside the day's items. */
.pulse .ag { display: grid; grid-template-columns: 52px minmax(0, 1fr); gap: 12px; padding: 10px 0; border-top: 1px solid var(--hair); }
.pulse .ag:first-child { border-top: 0; }
.pulse .ag__date { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; }
.pulse .ag__date b { font-size: 18px; letter-spacing: -.03em; }
.pulse .ag__items { display: flex; flex-direction: column; gap: 8px; }
.pulse .ag__item { display: flex; flex-direction: column; gap: 2px; font-size: 14px; padding-left: 10px; border-left: 2px solid var(--hair); }
/* An ending carries a deadline, so it takes the accent rule. */
.pulse .ag__item--accent { border-left-color: var(--red); }

/* Recent activity. */
.pulse .fd { display: grid; grid-template-columns: 26px minmax(0, 1fr); gap: 10px; padding: 10px 0; border-top: 1px solid var(--hair); align-items: start; }
.pulse .fd:first-child { border-top: 0; }
.pulse .fd__dot { display: grid; place-items: center; width: 26px; height: 26px; border-radius: 50%; background: var(--tint); color: var(--ink2); }
.pulse .fd__dot--accent { background: color-mix(in srgb, var(--red) 16%, transparent); color: var(--red); }
.pulse .fd__body { display: flex; flex-direction: column; gap: 2px; }

@media (max-width: 1000px) {
  .pulse .ov { grid-template-columns: minmax(0, 1fr); }
}


/* A grid or flex child defaults to `min-width: auto`, which is its content's width — so one
   wide table or one long control pushes its card past the column it was given, and past the
   viewport with it. Every card here is allowed to be narrower than what is inside it; the
   scrollers within them (`.tw`) then do their job. */
.pulse .p-card, .pulse .p-kpi { min-width: 0; }
.pulse .ov > *, .pulse .two > *, .pulse .layout > * { min-width: 0; }

/* ------------------------------------------------- the portfolio card grid (Projects health)

   The Pulse portfolio's layout: band tiles that filter, then one card per project. The card
   is an <a> and not a div with a click handler, so it is one tab stop and one target.
   Deliberately no burn bar, no stack row and no people grid: the portfolio prototype draws
   those from fields this dashboard has no source for. */

.pulse .p-kpi--btn {
  font-family: inherit;
  font-size: inherit;
  color: inherit;
  text-align: left;
  border: 0;
  cursor: pointer;
}
.pulse .p-kpi--btn:hover { background: var(--tint); }
/* The pressed tile. An inset ruled border rather than a fill, because the dot inside it
   already carries the band's colour and a filled tile would restate it louder than the
   cards. */
.pulse .p-kpi--on { box-shadow: inset 0 0 0 2px var(--ink); }
.pulse .p-kpi--on:hover { background: var(--card); }

.pulse .p-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
  gap: 12px;
}
.pulse .p-proj {
  display: flex;
  flex-direction: column;
  gap: 10px;
  background: var(--card);
  border-radius: var(--radius-card);
  box-shadow: inset 0 0 0 1px var(--hair);
  padding: 16px 18px;
  color: var(--ink);
  text-decoration: none;
  min-width: 0;
}
.pulse .p-proj:hover { color: var(--ink); box-shadow: inset 0 0 0 1px var(--rule); background: var(--tint); }
.pulse .p-proj__top {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  justify-content: space-between;
}
.pulse .p-proj__name { font-weight: 500; line-height: 1.25; }
.pulse .p-proj__act { display: block; min-height: 20px; }
/* The six bars are sized for a table cell, where they sit beside four other columns. In a
   card they are the full width they are given and must not force the grid wider — and six
   across a 290px card runs the labels into each other, so they wrap to two rows of three. */
.pulse .p-proj .p-areas { min-width: 0; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px 10px; }

/* The card's people grid: label and name, four rows at most (PM, AM, DM, TL), each row only
   when the Projects list has that person recorded. */
.pulse .p-people {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 2px 10px;
  font-size: 13px;
  align-items: baseline;
}
.pulse .p-people__k {
  font-family: var(--font-mono-primary);
  font-size: 10.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink3);
}
.pulse .p-people__v { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
