/* projectManagementOS — styled to Bots For That Brand Guidelines 2026.
 *
 * Core palette:       Mulberry #362838 · Raspberry #E21766 · Peony #FDE5EE · White · Black
 * Supporting palette: Dark Grey #282929 · Misty Grey #E5E5E5 · Aquamarine #7CD5CB
 *
 * Chrome uses Mulberry, Peony and White with Raspberry as the single accent.
 * The supporting palette carries the status data, which is the use section 2.4
 * of the guidelines reserves it for.
 */

/* Garet is the brand typeface but is not a webfont. Drop the two files into
 * public/fonts/ and it takes over everywhere; until then the stack falls
 * through to Avenir — the guidelines' universal face — and then Poppins, the
 * closest free geometric sans. See the README. */
@font-face {
  font-family: 'Garet';
  src: url('/static/fonts/garet-book.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: 'Garet';
  src: url('/static/fonts/garet-bold.woff2') format('woff2');
  font-weight: 700;
  font-display: swap;
}

:root {
  /* core */
  --mulberry: #362838;
  --raspberry: #e21766;
  --raspberry-deep: #8e0f45;
  --peony: #fde5ee;
  --peony-deep: #f7cfdd;
  --white: #ffffff;

  /* Capacity is a traffic light, so it steps outside the brand palette on
     purpose: green is fine, amber is close, red is over. */
  --cap-green: #12946A;
  --cap-amber: #E8A72B;
  --cap-red: #C8322B;

  /* supporting */
  --dark-grey: #282929;
  --misty-grey: #e5e5e5;
  --aquamarine: #7cd5cb;

  /* roles */
  --ink: var(--mulberry);
  --ink-soft: #6b5c6d;
  --ink-faint: #9a8c9c;
  --ground: #f4f1f4;
  --surface: var(--white);
  --rule: #e0d8e0;
  --rule-soft: #efeaef;
  --link: var(--raspberry);

  --gap: 16px;
  --rail: 248px;
  --row-h: 54px;
  --r-card: 14px;
  --r-ctl: 10px;
  --r-cell: 6px;

  --sans: 'Garet', 'Avenir Next', Avenir, 'Poppins', 'Century Gothic', Arial, sans-serif;
  /* The brand has no monospace face, so data uses the same family with
     tabular figures. */
  --data: var(--sans);
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }

body {
  background: var(--ground);
  color: var(--ink);
  font: 400 14px/1.55 var(--sans);
  -webkit-font-smoothing: antialiased;
}

a { color: var(--link); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { text-decoration-thickness: 2px; }

:focus-visible { outline: 2px solid var(--raspberry); outline-offset: 2px; }

.mono, .data {
  font-family: var(--data);
  font-variant-numeric: tabular-nums;
  letter-spacing: .01em;
}

/* ---------------------------------- shell -------------------------------- */

.shell { display: grid; grid-template-columns: var(--rail) minmax(0, 1fr); min-height: 100vh; }

/* ------------------------------ collapsing the rail ----------------------- */
/* Icons only at 66px, labels become tooltips, and the section headings become
   hairlines so the grouping survives. The width transitions; nothing inside it
   does, because sliding text is harder to read than text that is simply gone. */

.shell { transition: grid-template-columns 180ms cubic-bezier(.2, .8, .2, 1); }
.shell--collapsed { grid-template-columns: 66px 1fr; }

.rail-toggle-form { position: absolute; top: 16px; right: -13px; z-index: 5; }
.rail-toggle {
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid var(--peony-deep);
  border-radius: 50%;
  background: var(--white);
  color: var(--mulberry);
  cursor: pointer;
  box-shadow: 0 1px 3px rgba(54, 40, 56, .16);
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}
.rail-toggle svg { width: 15px; height: 15px; }
.rail-toggle:hover { background: var(--raspberry); color: var(--white); border-color: var(--raspberry); }
.rail-toggle:focus-visible { outline: 2px solid var(--raspberry); outline-offset: 2px; }
.shell--collapsed .rail-toggle svg { transform: rotate(180deg); }

/* The glyph beside each label, and the only thing left when collapsed. */
.nav-icon { width: 19px; height: 19px; flex: none; opacity: .85; }
.nav a[aria-current="page"] .nav-icon { opacity: 1; }
.nav-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.shell--collapsed .rail { padding: 20px 0 24px; }
.shell--collapsed .brand { padding: 0 8px 14px; }
/* The wordmark cannot be squeezed — 1.1 forbids distorting it — so the square
   icon stands in, which is what it is for. */
.shell--collapsed .brand img { content: url('/static/img/plan-64.png'); max-width: 34px; margin: 0 auto; }
.shell--collapsed .brand small { display: none; }

.shell--collapsed .nav { padding: 14px 8px; align-items: center; }
.shell--collapsed .nav a {
  position: relative;
  justify-content: center;
  gap: 0;
  width: 42px;
  padding: 10px 0;
}
.shell--collapsed .nav-text { display: none; }
.shell--collapsed .nav-icon { width: 20px; height: 20px; }

/* A hairline standing in for the section heading, so the grouping is still read
   even though the word is gone. */
.shell--collapsed .nav-label {
  height: 1px;
  width: 22px;
  padding: 0;
  margin: 14px auto 9px;
  overflow: hidden;
  text-indent: -999px;
  background: var(--peony-deep);
}

/* The count still matters when the label is hidden, so it moves to the corner of
   the icon rather than sitting after text that is not there. */
.shell--collapsed .nav a .count {
  position: absolute;
  top: 2px;
  right: 0;
  min-width: 15px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--raspberry);
  color: var(--white);
  font-size: 9.5px;
  font-weight: 700;
  line-height: 1.6;
  box-shadow: 0 0 0 2px var(--peony);
}
.shell--collapsed .nav a[aria-current="page"] .count { box-shadow: 0 0 0 2px var(--mulberry); }
/* "3 late" would not fit; the number alone does. */
.shell--collapsed .nav a .count.late { font-size: 0; padding: 0; min-width: 9px; height: 9px; }

.shell--collapsed .rail-foot { padding: 14px 8px 0; text-align: center; }
.shell--collapsed .rail-foot .who,
.shell--collapsed .rail-foot .role,
.shell--collapsed .rail-foot a { display: none; }
.shell--collapsed .rail-foot .initials { display: grid; }
.rail-foot .initials {
  display: none;
  width: 32px;
  height: 32px;
  margin: 0 auto;
  place-items: center;
  border-radius: 50%;
  background: var(--mulberry);
  color: var(--peony);
  font-size: 11.5px;
  font-weight: 700;
}
.shell--collapsed .rail-foot form { display: none; }

@media (prefers-reduced-motion: reduce) {
  .shell { transition: none; }
}

.rail {
  position: relative;
  background: var(--peony);
  border-right: 1px solid var(--peony-deep);
  padding: 20px 0 24px;
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
}

/* The wordmark is used exactly as supplied. Section 1.1: no redrawing, no
   recolouring, no bounding box, clear space kept around it. */
.brand { padding: 0 20px 18px; border-bottom: 1px solid var(--peony-deep); }
.brand img { display: block; width: 100%; max-width: 190px; height: auto; }
.brand small { display: block; margin-top: 13px; font-size: 11.5px; color: var(--ink-soft); }

.nav { padding: 14px 12px; display: flex; flex-direction: column; gap: 2px; }
.nav-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--raspberry);
  padding: 14px 10px 7px;
}
.nav a {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 14px;
  border-radius: 999px;
  color: var(--ink);
  text-decoration: none;
  font-size: 13.5px;
}
.nav a:hover { background: var(--white); }
.nav a[aria-current="page"] { background: var(--mulberry); color: var(--peony); font-weight: 700; }
.nav a[aria-current="page"] .count { color: rgba(253, 229, 238, .7); }
.nav a .count {
  /* Pushed to the far edge, so the labels line up against the icons instead of
     floating away from them. */
  margin-left: auto;
  font-size: 11.5px;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}

.rail-foot { margin-top: auto; padding: 16px 20px 0; border-top: 1px solid var(--peony-deep); }
.rail-foot .who { font-size: 13px; font-weight: 700; word-break: break-word; }
.rail-foot .role {
  display: inline-block;
  margin-top: 8px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  padding: 5px 11px;
  border-radius: 999px;
  background: var(--raspberry);
  color: var(--white);
}
.rail-foot form { margin-top: 12px; }
.rail-foot button {
  background: none;
  border: 0;
  color: var(--ink-soft);
  font: inherit;
  font-size: 12.5px;
  padding: 0;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.rail-foot button:hover { color: var(--raspberry); }

.main { min-width: 0; display: flex; flex-direction: column; }

/* --------------------------------- pulse --------------------------------- */
/* The one dark band on the page: last run, what it found, and the next run. */

.pulse {
  background: var(--mulberry);
  color: var(--peony);
  padding: 12px 24px;
  display: flex;
  align-items: center;
  gap: 26px;
  flex-wrap: wrap;
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
}
.pulse .field { display: flex; align-items: baseline; gap: 8px; }
.pulse .k {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .15em;
  text-transform: uppercase;
  color: rgba(253, 229, 238, .55);
}
.pulse .v { color: var(--white); font-weight: 700; }
.pulse .v.bad { color: #ff8fb4; }
.pulse .v.warn { color: var(--aquamarine); }
.pulse .v.ok { color: var(--aquamarine); }

.spark { display: flex; align-items: flex-end; gap: 3px; height: 16px; }
.spark i { display: block; width: 4px; min-height: 2px; background: rgba(253, 229, 238, .4); border-radius: 2px; }
.spark i.bad { background: #ff8fb4; }
.spark i.warn { background: var(--aquamarine); }

.pulse .live { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.dot { width: 8px; height: 8px; border-radius: 50%; background: var(--aquamarine); display: inline-block; }
.dot.off { background: rgba(253, 229, 238, .35); }
.dot.busy { background: var(--raspberry); animation: blink 1.1s steps(2, end) infinite; }
@keyframes blink { 50% { opacity: .3; } }

/* -------------------------------- headings ------------------------------- */

.page { padding: 24px 24px 48px; }

.page-head { display: flex; align-items: flex-end; gap: var(--gap); flex-wrap: wrap; margin-bottom: 20px; }
.page-head h1 { margin: 0; font-size: 30px; font-weight: 700; letter-spacing: -.015em; line-height: 1.1; }
.eyebrow {
  display: block;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--raspberry);
  margin-bottom: 8px;
}
.page-head .spacer { flex: 1; }

/* -------------------------------- controls ------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: 1.5px solid var(--raspberry);
  background: var(--raspberry);
  color: var(--white);
  font: 700 13px/1 var(--sans);
  padding: 11px 20px;
  border-radius: 999px;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
}
.btn:hover { background: var(--raspberry-deep); border-color: var(--raspberry-deep); }
.btn.ghost { background: transparent; color: var(--ink); border-color: var(--rule); }
.btn.ghost:hover { background: var(--white); border-color: var(--mulberry); color: var(--mulberry); }
.btn.danger { background: var(--mulberry); border-color: var(--mulberry); }
.btn.danger:hover { background: #000; border-color: #000; }
.btn.small { padding: 8px 15px; font-size: 12px; }
.btn[disabled] { opacity: .45; cursor: not-allowed; }
.btn .plus { font-size: 15px; line-height: 1; }

.filters {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--r-card);
  padding: 12px 14px;
  margin-bottom: 16px;
}
.filters input, .filters select { width: auto; }
.filters input[type="search"] { flex: 1 1 240px; min-width: 180px; }
.filters select { min-width: 152px; }
.filters .toggle { display: flex; align-items: center; gap: 7px; font-size: 13px; color: var(--ink-soft); }

input[type="text"], input[type="search"], input[type="email"], input[type="password"],
input[type="number"], select, textarea {
  font: 400 13.5px/1.45 var(--sans);
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--r-ctl);
  padding: 10px 13px;
  width: 100%;
}
input:focus, select:focus, textarea:focus { border-color: var(--raspberry); }
input.mono, textarea.mono { font-variant-numeric: tabular-nums; }
textarea { min-height: 90px; resize: vertical; }
input[type="checkbox"] { accent-color: var(--raspberry); }

label.field { display: block; margin-bottom: 16px; }
label.field > span {
  display: block;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 7px;
}
label.field .hint {
  display: block;
  margin-top: 6px;
  font-size: 12px;
  color: var(--ink-faint);
  letter-spacing: 0;
  text-transform: none;
  font-weight: 400;
}
.check { display: flex; align-items: center; gap: 9px; margin-bottom: 16px; font-size: 13.5px; }
.check input { width: auto; }

/* --------------------------------- board --------------------------------- */

.board-wrap {
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--r-card);
  overflow: auto;
  max-height: calc(100vh - 272px);
}

table.board { border-collapse: separate; border-spacing: 0; width: 100%; }

table.board thead th {
  position: sticky;
  top: 0;
  z-index: 3;
  background: var(--mulberry);
  color: var(--white);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  text-align: left;
  padding: 13px 11px;
  white-space: nowrap;
  line-height: 1.2;
}
table.board thead th small {
  display: block;
  font-size: 10px;
  font-weight: 400;
  letter-spacing: .02em;
  text-transform: none;
  color: rgba(253, 229, 238, .62);
  margin-top: 4px;
}
table.board thead th.stage { text-align: center; width: 112px; }
table.board thead th.date { width: 138px; }

th.pin, td.pin {
  position: sticky;
  left: 0;
  z-index: 4;
  min-width: 310px;
  max-width: 360px;
  background: var(--surface);
  border-right: 1px solid var(--rule);
}
table.board thead th.pin { z-index: 5; background: var(--mulberry); }

table.board tbody td {
  border-bottom: 1px solid var(--rule-soft);
  padding: 0 11px;
  height: var(--row-h);
  vertical-align: middle;
}
table.board thead th.stage { width: 116px; }
table.board tbody tr:hover td, table.board tbody tr:hover td.pin { background: var(--peony); }
table.board tbody tr.archived td { opacity: .55; }

/* The client's logo, or its initials when there is not one yet. */
.client-mark {
  flex: none;
  /* Sized to the row so the logo is legible at a glance, not a token. */
  width: 52px;
  height: 52px;
  border-radius: 10px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: var(--white);
  box-shadow: inset 0 0 0 1px rgba(54, 40, 56, .12);
  color: var(--white);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .02em;
}
.client-mark img { width: 100%; height: 100%; object-fit: contain; display: block; padding: 2px; }
.client-mark.lg { width: 54px; height: 54px; border-radius: 12px; font-size: 17px; }
.client-mark { font-size: 14px; }

.logo-drop { display: inline-block; cursor: pointer; }
.logo-drop:hover .client-mark { box-shadow: inset 0 0 0 2px var(--raspberry); }

.proj { display: flex; align-items: center; gap: 10px; padding: 6px 0; }
.proj .name { font-weight: 700; text-decoration: none; color: var(--ink); }
.proj .name:hover { color: var(--raspberry); }
.proj .meta {
  display: block;
  margin-top: 3px;
  font-size: 11.5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}
.proj .flag.quiet { background: var(--misty-grey); color: var(--ink-soft); }
.proj .flag {
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--white);
  background: var(--raspberry);
  border-radius: 999px;
  padding: 4px 9px;
  white-space: nowrap;
}

/* The status cell. Flat: one solid colour, no gradient, no shadow. Both colours
   come from the rules, so a board using its own labels still reads correctly. */
td.stage { padding: 4px 3px; }
.cell {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  width: 100%;
  min-height: 38px;
  padding: 6px 8px 7px;
  border-radius: 6px;
  text-align: center;
  overflow: hidden;
}
/* The status and its item count share a line. */
.cell-top {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  max-width: 100%;
}
.cell .txt {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  line-height: 1.15;
}
/* The item count, quiet enough not to compete with the label. */
.cell .n {
  flex: none;
  font-size: 9.5px;
  font-weight: 700;
  line-height: 1;
  opacity: .62;
  font-variant-numeric: tabular-nums;
}
/* How much of the group is done, as a hairline along the very bottom edge. */
/* Logged against estimated, under the status rather than behind it. */
.cell .hrs {
  position: relative;
  font-size: 8.5px;
  font-weight: 700;
  opacity: .72;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* Past the estimate. An underline reads on all six status colours, where a
   colour change would fight two of them. */
.cell .hrs.over {
  opacity: 1;
  text-decoration: underline;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 1px;
}
.cell .bar {
  position: absolute;
  left: 0;
  bottom: 0;
  height: 2px;
  background: currentColor;
  opacity: .45;
}
.cell.empty {
  background: var(--ground);
  color: var(--ink-faint);
  box-shadow: inset 0 0 0 1px var(--rule-soft);
}
.cell.missing { box-shadow: inset 0 0 0 1.5px rgba(54, 40, 56, .28); }

td.date { font-size: 11.5px; color: var(--ink); white-space: nowrap; font-variant-numeric: tabular-nums; }
td.date .soon { color: var(--raspberry); font-weight: 700; }
td.date .none { color: var(--ink-faint); }

/* Project state: a coloured dot and its name. Quiet on purpose — the status
   cells are the loud part of this table. */
.state {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 12.5px;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}
a.state:hover { color: var(--raspberry); text-decoration: none; }
.state-dot {
  flex: none;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  /* A ring keeps the amber and blue legible on the row hover tint. */
  box-shadow: inset 0 0 0 1px rgba(54, 40, 56, .18);
}

/* Feedback while a client logo is being chosen. */
.client-grid { display: grid; gap: var(--gap); grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); }
.client-card { display: flex; flex-direction: column; margin-bottom: 0; }
.client-card .cols { grid-template-columns: 1fr 88px; }
.client-actions { display: flex; align-items: center; gap: 12px; margin-top: 4px; flex-wrap: wrap; }
.client-remove { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--rule-soft); }

.logo-cell { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.logo-pick { position: relative; overflow: hidden; display: inline-block; }
.logo-pick input[type="file"] { position: absolute; inset: 0; opacity: 0; width: 100%; cursor: pointer; }
.logo-pick-label {
  display: inline-block;
  padding: 7px 13px;
  border: 1.5px solid var(--rule);
  border-radius: 999px;
  font-size: 12px;
  font-weight: 700;
  background: var(--surface);
  cursor: pointer;
  white-space: nowrap;
}
.logo-pick:hover .logo-pick-label { border-color: var(--mulberry); }
.logo-status { font-size: 11.5px; color: var(--ink-faint); }
.logo-status.ready { color: var(--raspberry); font-weight: 700; }
.logo-status.bad { color: var(--raspberry-deep); }

.overall { display: inline-flex; align-items: center; gap: 8px; font-size: 12.5px; white-space: nowrap; }
.swatch { display: inline-block; width: 11px; height: 11px; border-radius: 3px; flex: none; }

/* -------------------------------- slicers -------------------------------- */

.slicers { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.slicer-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-right: 2px;
}
.slicer {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 13px;
  border: 1.5px solid var(--rule);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink);
  font-size: 12.5px;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
}
.slicer:hover { border-color: var(--mulberry); text-decoration: none; }
.slicer.on { color: var(--white); font-weight: 700; background: var(--mulberry); border-color: var(--mulberry); }
.slicer.on .swatch { box-shadow: 0 0 0 1.5px rgba(255,255,255,.65); }
.slicer .n {
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  opacity: .7;
  padding-left: 2px;
}
.slicer.add { font-weight: 700; color: var(--ink-faint); padding: 7px 12px; }

.tag-picker { display: flex; flex-direction: column; gap: 2px; }
.tag-option {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  padding: 5px 8px;
  border-radius: var(--r-ctl);
  cursor: pointer;
}
.tag-option:hover { background: var(--peony); }
.tag-option input { width: auto; }

.chips { display: flex; gap: 4px; flex-wrap: wrap; margin-top: 4px; }
.chip {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .04em;
  text-decoration: none;
  white-space: nowrap;
}
.chip:hover { text-decoration: none; filter: brightness(1.08); }

/* Sortable column headings. Each one is a chip inside the dark header rather
   than a bare link, so it reads as something you can press and the sorted
   column is obvious at a glance. */
table.board thead th a.sort {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin: -4px -7px;
  padding: 4px 7px;
  border-radius: 6px;
  color: rgba(253, 229, 238, .82);
  text-decoration: none;
  white-space: nowrap;
}
table.board thead th.stage a.sort { justify-content: center; }
table.board thead th a.sort:hover {
  background: rgba(253, 229, 238, .14);
  color: var(--white);
  text-decoration: none;
}
table.board thead th a.sort .arrow {
  font-size: 9px;
  line-height: 1;
  opacity: 0;
  transform: translateY(-.5px);
}
table.board thead th a.sort:hover .arrow { opacity: .5; }
/* The column currently sorted keeps its chip filled and its arrow lit. */
table.board thead th a.sort.on {
  background: var(--raspberry);
  color: var(--white);
}
table.board thead th a.sort.on .arrow { opacity: 1; }
table.board thead th small { margin-top: 5px; }
table.board thead th small a.sort {
  font-size: 10px;
  font-weight: 400;
  letter-spacing: .02em;
  text-transform: none;
  color: rgba(253, 229, 238, .55);
}

/* ------------------------------- heat map -------------------------------- */

table.board.heat thead th.wk { width: 62px; text-align: center; padding: 11px 4px; }
table.board.heat thead th.wk.now { background: var(--raspberry); }
table.board.heat thead th.wk small { font-size: 9px; margin-top: 3px; }
table.board.heat td.wk { padding: 0 2px; text-align: center; }
table.board.heat td.wk.now { background: rgba(226, 23, 102, .05); }

.heat-cell {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 34px;
  border: 0;
  border-radius: var(--r-cell);
  background: var(--misty-grey);
  color: var(--mulberry);
  font: 700 11.5px/1 var(--sans);
  font-variant-numeric: tabular-nums;
  overflow: hidden;
  cursor: pointer;
  appearance: none;
}
.heat-cell .h { position: relative; z-index: 2; }
/* The fill rises with utilisation, so a glance down a column reads as a bar chart. */
.heat-cell .fill { position: absolute; left: 0; right: 0; bottom: 0; z-index: 1; background: rgba(54, 40, 56, .16); }
.heat-cell.free { background: var(--misty-grey); cursor: default; }
.heat-cell.booked { background: var(--cap-green); color: var(--white); }
.heat-cell.booked .fill { background: rgba(255, 255, 255, .2); }
.heat-cell.tight { background: var(--cap-amber); color: #3d2c07; }
.heat-cell.tight .fill { background: rgba(61, 44, 7, .16); }
.heat-cell.over { background: var(--cap-red); color: var(--white); }
.heat-cell.over .fill { background: rgba(255, 255, 255, .22); }
.heat-cell.off {
  background: repeating-linear-gradient(135deg, #f6f2f6, #f6f2f6 4px, #e9e2e9 4px, #e9e2e9 8px);
  color: var(--ink-faint);
  cursor: default;
}
button.heat-cell:hover { filter: brightness(1.06); }
button.heat-cell:focus-visible { outline: 2px solid var(--mulberry); outline-offset: 2px; }

.heat-key { display: flex; gap: 16px; align-items: center; flex-wrap: wrap; margin-top: 14px; font-size: 12px; color: var(--ink-soft); }
.heat-key > span { display: flex; align-items: center; gap: 6px; }
.heat-swatch { width: 14px; height: 14px; border-radius: 3px; display: inline-block; background: var(--misty-grey); }
.heat-swatch.booked { background: var(--cap-green); }
.heat-swatch.tight { background: var(--cap-amber); }
.heat-swatch.over { background: var(--cap-red); }
.heat-swatch.off { background: repeating-linear-gradient(135deg, #f6f2f6, #f6f2f6 4px, #e9e2e9 4px, #e9e2e9 8px); }

/* Template tasks: a group header row, and subtasks stepped in under a parent. */
table.data tr.group-row td {
  background: var(--peony);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  padding: 7px 10px;
}
table.data tr.sub-row td:first-child { padding-left: 22px; color: var(--ink-soft); }

/* ---------------------------------- my tasks ------------------------------ */
/* One card per task. The old table put a note box, the steps, the documents and
   six status buttons inside a single cell, which is what made it unreadable. Now
   the tick and the title lead, the dates sit right, and everything else is folded
   away beneath in a fixed order. */

.addown {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
  padding: 14px 16px;
}
.addown__title { flex: 1 1 320px; }
.addown__date { flex: 0 0 150px; }
.addown__project { flex: 0 0 180px; }

ul.tasklist { list-style: none; margin: 0; padding: 0; }

.taskcard {
  border: 1px solid var(--rule-soft);
  border-radius: var(--r-card);
  background: var(--white);
  padding: 13px 15px;
  margin-bottom: 9px;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
.taskcard:hover { border-color: var(--rule); box-shadow: 0 1px 4px rgba(54, 40, 56, .07); }
.taskcard:last-child { margin-bottom: 0; }
.taskcard.is-own { border-left: 3px solid var(--aquamarine); }
.taskcard.is-done { opacity: .6; }
.taskcard.is-done .taskcard__title strong { text-decoration: line-through; }

.taskcard__head { display: flex; align-items: flex-start; gap: 12px; }
.tick-form { flex: none; padding-top: 1px; }

/* A real tick box for a task that is mine to finish. */
.taskcard__tick {
  width: 19px;
  height: 19px;
  border: 1.5px solid var(--rule);
  border-radius: 5px;
  background: var(--white);
  cursor: pointer;
  padding: 0;
  display: block;
  transition: background 120ms ease, border-color 120ms ease;
}
.taskcard__tick:hover { border-color: var(--cap-green); }
.is-done .taskcard__tick {
  background: var(--cap-green);
  border-color: var(--cap-green);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6L9 17l-5-5'/%3E%3C/svg%3E");
  background-size: 13px;
  background-repeat: no-repeat;
  background-position: center;
}

/* A board task shows its status as a dot: the board owns that, not this page. */
.taskcard__dot {
  flex: none;
  width: 11px;
  height: 11px;
  margin-top: 5px;
  border-radius: 50%;
  box-shadow: inset 0 0 0 1px rgba(54, 40, 56, .18);
}

.taskcard__title { flex: 1; min-width: 0; }
.taskcard__title strong { font-size: 14.5px; }
.taskcard__meta {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 3px;
  font-size: 12px;
  color: var(--ink-soft);
}
.taskcard__meta a { color: var(--ink-soft); }
.taskcard__why { margin-top: 4px; font-size: 12px; color: var(--raspberry); }

.taskcard__when {
  flex: none;
  text-align: right;
  font-size: 12px;
  color: var(--ink-soft);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.taskcard__late { color: var(--raspberry); font-weight: 700; }
.taskcard__due { color: var(--cap-amber); font-weight: 700; }

/* Folded away until there is a reason to open it, and the summary says what is
   inside so it need not be opened to find out. */
.taskcard__foot { margin-top: 9px; padding-left: 31px; }
.task-more__body { padding-top: 12px; }
.own-edit { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 8px; }
.own-edit input[type="text"] { flex: 1 1 220px; }
.own-edit input[type="date"] { flex: 0 0 150px; }

@media (max-width: 720px) {
  .taskcard__head { flex-wrap: wrap; }
  .taskcard__when { text-align: left; flex-direction: row; gap: 10px; width: 100%; padding-left: 31px; }
  .taskcard__foot { padding-left: 0; }
}

/* My tasks: steps and documents, folded away until wanted. */
details.task-more { margin-top: 8px; }
details.task-more > summary {
  cursor: pointer;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--raspberry);
}
details.task-more[open] > summary { margin-bottom: 10px; }

ul.subtasks, ul.files { list-style: none; margin: 0 0 10px; padding: 0; }
ul.subtasks li, ul.files li {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
  border-bottom: 1px solid var(--rule-soft);
  font-size: 13px;
}
ul.subtasks li:last-child, ul.files li:last-child { border-bottom: 0; }
ul.subtasks li.done .what { text-decoration: line-through; color: var(--ink-faint); }
ul.subtasks .what, ul.files a { flex: 1; }
ul.subtasks form, ul.files form { display: inline; }
.tick, .drop {
  border: 0;
  background: none;
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  padding: 0 2px;
  color: var(--ink-faint);
}
.tick:hover { color: var(--cap-green); }
.drop:hover { color: var(--raspberry); }
li.done .tick { color: var(--cap-green); }

/* The note on a task: the first thing in the panel, as on a to-do card. */
form.task-note { margin-bottom: 14px; }
form.task-note textarea {
  width: 100%;
  min-height: 66px;
  padding: 9px 11px;
  border: 1.5px solid var(--rule);
  border-radius: var(--r-input);
  font: inherit;
  font-size: 13.5px;
  line-height: 1.5;
  resize: vertical;
  background: var(--white);
  color: var(--ink);
}
form.task-note textarea:focus {
  outline: none;
  border-color: var(--mulberry);
  box-shadow: 0 0 0 3px var(--peony);
}
.note-actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-top: 7px; }

form.add-sub, form.add-file {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: 8px;
}
form.add-sub input[type="text"] { flex: 1 1 180px; width: auto; }
.file-note.ready { color: var(--raspberry); font-weight: 700; }

/* Where a task sits in the suggested order. */
.rank {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--raspberry);
  color: var(--white);
  font-size: 10.5px;
  font-weight: 700;
  margin-right: 7px;
  vertical-align: 1px;
}
ol.suggested { margin: 0; padding-left: 22px; }
ol.suggested li { padding: 5px 0; font-size: 13.5px; }
ol.suggested li a { text-decoration: none; }
ol.suggested li a:hover { text-decoration: underline; }

/* Spellings a person also answers to. */
.alias-chips { display: flex; gap: 4px; flex-wrap: wrap; margin-top: 6px; }
.alias-chip {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  background: var(--peony);
  color: var(--ink);
  border-radius: 999px;
  padding: 2px 4px 2px 9px;
  font-size: 10.5px;
  font-family: var(--data);
}
.alias-chip button {
  border: 0;
  background: none;
  color: var(--ink-faint);
  cursor: pointer;
  font-size: 13px;
  line-height: 1;
  padding: 0 3px;
}
.alias-chip button:hover { color: var(--raspberry); }

/* ------------------------------- what if --------------------------------- */

/* Running a scenario changes what the grid means, so it is stated plainly above
   it rather than left to a subtle cue. */
.scenario-bar {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  background: var(--mulberry);
  color: var(--peony);
  border-radius: var(--r-card);
  padding: 12px 16px;
  margin-bottom: var(--gap);
}
.scenario-bar .note { color: rgba(253, 229, 238, .7); }
.scenario-tag {
  flex: none;
  background: var(--raspberry);
  color: var(--white);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  padding: 5px 11px;
  border-radius: 999px;
}
.scenario-what { display: flex; gap: 14px; flex-wrap: wrap; font-size: 13px; }
.scenario-move { color: var(--white); }
.scenario-bar .btn.ghost {
  margin-left: auto;
  border-color: rgba(253, 229, 238, .4);
  color: var(--peony);
}
.scenario-bar .btn.ghost:hover { background: rgba(253, 229, 238, .14); color: var(--white); }
.flag.scenario-flag { background: var(--mulberry); }

.wi-panel > summary {
  cursor: pointer;
  display: flex;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
}
.wi-panel > summary::marker { color: var(--raspberry); }
.wi-title { font-size: 16px; font-weight: 700; }
.wi-panel[open] > summary { margin-bottom: 4px; }

.swap-row {
  display: flex;
  gap: 12px;
  align-items: flex-end;
  flex-wrap: wrap;
  padding: 12px 0;
  border-bottom: 1px solid var(--rule-soft);
  margin-bottom: 12px;
}
.swap-row:last-of-type { border-bottom: 0; }
.swap-n {
  flex: none;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--peony);
  color: var(--raspberry);
  font-size: 11px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 9px;
}

/* The two rows for one person are banded together, so the eye pairs them. */
table.wi-table tbody tr.wi-before td { border-bottom: 0; padding-top: 8px; }
table.wi-table tbody tr.wi-after td { padding-bottom: 10px; }
table.wi-table tbody tr.wi-after { border-bottom: 2px solid var(--rule); }
table.wi-table tbody tr.wi-before:hover td, table.wi-table tbody tr.wi-after:hover td { background: transparent; }
table.wi-table td.wk, table.wi-table th.wk { width: 62px; text-align: center; padding: 0 3px; }

.heat-cell.wi-changed { box-shadow: 0 0 0 2px var(--mulberry); }
.wi-delta {
  position: absolute;
  right: 1px;
  top: 1px;
  z-index: 3;
  padding: 0 3px;
  border-radius: 4px;
  /* Its own backing, so it never fights the hours underneath it. */
  background: rgba(54, 40, 56, .26);
  color: inherit;
  font-size: 8.5px;
  font-weight: 700;
  line-height: 1.5;
}
.heat-cell.over .wi-delta, .heat-cell.booked .wi-delta { background: rgba(255, 255, 255, .28); }
.wi-bad { color: var(--cap-red); font-weight: 700; }

/* Hours read badly in capitals: "13.3H OF 37.5H". */
/* Two classes, equal specificity, and .pill comes later in the file — so this
   needs the extra class to win. */
.cell-panel .lp-sum.pill { text-transform: none; letter-spacing: .01em; font-size: 11px; }

.lp-body .lp-project { margin-bottom: 12px; }
.lp-body .lp-project:last-child { margin-bottom: 0; }
.lp-body .lp-project h4 {
  margin: 0 0 6px;
  font-size: 12.5px;
  display: flex;
  justify-content: space-between;
  gap: 10px;
}
.lp-body .lp-project h4 span { font-variant-numeric: tabular-nums; color: var(--ink-soft); font-weight: 400; }
.lp-body ul { margin: 0; padding-left: 18px; }
.lp-body li { font-size: 12px; color: var(--ink-soft); margin-bottom: 3px; }
.lp-body li b { color: var(--ink); font-weight: 500; }

/* --------------------------- the task panel ------------------------------ */

/* Fixed rather than absolute, and moved to the end of <body> by the script, so
   no scrolling container clips it and no sticky table cell can paint over it.
   Sticky cells create their own stacking contexts, and engines differ on how
   those order against an absolutely positioned sibling. */
.cell-panel {
  position: fixed;
  z-index: 1000;
  width: min(560px, calc(100vw - 24px));
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--r-card);
  box-shadow: 0 12px 32px rgba(54, 40, 56, .22);
  padding: 14px 16px 12px;
}
.cell-panel[hidden] { display: none; }
.cp-head { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; }
.cp-head .cp-stage { font-size: 15px; font-weight: 700; }
.cp-close {
  margin-left: auto;
  background: none;
  border: 0;
  font-size: 20px;
  line-height: 1;
  color: var(--ink-faint);
  cursor: pointer;
  padding: 0 2px;
}
.cp-close:hover { color: var(--raspberry); }
.cp-sub { font-size: 11.5px; color: var(--ink-soft); margin-bottom: 12px; }

table.cp-tasks { width: 100%; border-collapse: collapse; }
table.cp-tasks th {
  text-align: left;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  padding: 0 10px 6px 0;
  border-bottom: 1px solid var(--rule);
}
table.cp-tasks td {
  padding: 7px 10px 7px 0;
  border-bottom: 1px solid var(--rule-soft);
  font-size: 12.5px;
  vertical-align: middle;
}
table.cp-tasks tr:last-child td { border-bottom: 0; }
table.cp-tasks .cp-name { font-weight: 500; }
table.cp-tasks .cp-when { font-variant-numeric: tabular-nums; white-space: nowrap; font-size: 11.5px; }
.cp-dot {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 2px;
  margin-right: 6px;
  vertical-align: -1px;
  /* Peony and Misty Grey would otherwise vanish against a white row. */
  box-shadow: inset 0 0 0 1px rgba(54, 40, 56, .22);
}
.cp-none { color: var(--ink-faint); }
.cp-empty { padding: 6px 0 2px; }

/* the cell is now a button, so reset what that brings with it */
button.cell {
  width: 100%;
  border: 0;
  font-family: inherit;
  cursor: pointer;
  appearance: none;
}
/* Flat means hover needs to do the work: a ring in the cell's own colour. */
button.cell { transition: box-shadow .1s ease, filter .1s ease; }
button.cell:hover { filter: saturate(1.08) brightness(.96); box-shadow: 0 0 0 2px var(--peony-deep); }
button.cell:active { filter: brightness(.92); }
button.cell:focus-visible { outline: 2px solid var(--mulberry); outline-offset: 2px; }

/* -------------------------------- my tasks ------------------------------- */

/* One button per status, so a change is a single press rather than a dropdown
   and a save. The current one is filled in; the rest are quiet outlines. */
.status-set { display: flex; flex-wrap: wrap; gap: 4px; }
.status-btn {
  font: 700 9.5px/1 var(--sans);
  letter-spacing: .05em;
  text-transform: uppercase;
  padding: 6px 9px;
  border: 1px solid var(--rule);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink-soft);
  cursor: pointer;
  white-space: nowrap;
}
.status-btn:hover { border-color: var(--mulberry); color: var(--ink); }
.status-btn.on { cursor: default; }
.status-btn.on:hover { filter: none; }

table.my-tasks td { vertical-align: top; padding-top: 12px; padding-bottom: 12px; }

.who-option { align-items: flex-start; padding: 10px; border-bottom: 1px solid var(--rule-soft); }
.who-option:last-child { border-bottom: 0; }

.link-button {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: var(--raspberry);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}

.nav a .count.late {
  background: var(--raspberry);
  color: var(--white);
  padding: 2px 7px;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 700;
}

/* --------------------------- the sticky save bar ------------------------- */
/* Sits under the pulse strip while a long list scrolls past. */
.save-bar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin-bottom: var(--gap);
  padding: 12px 16px;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--r-card);
  box-shadow: 0 6px 18px rgba(54, 40, 56, .1);
}
.save-bar-count { font-size: 13px; font-weight: 700; }
.save-bar-note { margin-left: auto; }
.save-bar .btn { flex: none; }
/* Once something is edited the bar says so and the button leads. */
.save-bar.dirty { border-color: var(--raspberry); }
.save-bar.dirty .save-bar-count { color: var(--raspberry); }
@media (max-width: 640px) {
  .save-bar-note { display: none; }
  .save-bar { justify-content: space-between; }
}

/* ------------------------------ tally cards ------------------------------ */

.tallies { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 16px; }
.tally {
  background: var(--surface);
  border: 1px solid var(--rule);
  border-left-width: 5px;
  border-left-style: solid;
  border-radius: var(--r-card);
  padding: 12px 18px 12px 14px;
  min-width: 106px;
}
.tally b { display: block; font-size: 26px; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; }
.tally span {
  display: block;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-top: 6px;
}

/* --------------------------------- cards --------------------------------- */

.card {
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--r-card);
  padding: 20px;
  margin-bottom: var(--gap);
}
.card > h2, .card > h3 { margin: 0 0 5px; font-size: 18px; font-weight: 700; letter-spacing: -.01em; }
.card > h3 { font-size: 15px; }
.card > p.sub { margin: 0 0 18px; color: var(--ink-soft); font-size: 13px; }
.cols { display: grid; gap: var(--gap); grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.grid-2 { display: grid; gap: var(--gap); grid-template-columns: 1fr 1fr; align-items: start; }
@media (max-width: 900px) { .grid-2 { grid-template-columns: 1fr; } }

table.data { width: 100%; border-collapse: collapse; }
table.data th {
  text-align: left;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  padding: 0 10px 9px 0;
  border-bottom: 1px solid var(--rule);
}
table.data td { padding: 10px 10px 10px 0; border-bottom: 1px solid var(--rule-soft); vertical-align: middle; font-size: 13px; }
table.data td.mono, table.data th.mono { font-variant-numeric: tabular-nums; font-size: 12.5px; }
table.data tr:last-child td { border-bottom: 0; }
table.data td .row-actions { display: flex; gap: 6px; justify-content: flex-end; }

.pill {
  display: inline-block;
  padding: 4px 11px;
  border-radius: 999px;
  color: var(--white);
  background: var(--mulberry);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.pill.grey { background: var(--misty-grey); color: var(--ink); }
.pill.ok { background: var(--aquamarine); color: var(--mulberry); }
.pill.warn { background: var(--peony); color: var(--raspberry); box-shadow: inset 0 0 0 1px var(--raspberry); }
.pill.bad { background: var(--raspberry); }
.pill.outline { background: none; color: var(--ink-soft); box-shadow: inset 0 0 0 1px var(--rule); }

.flash {
  padding: 13px 16px;
  border-radius: var(--r-ctl);
  margin-bottom: var(--gap);
  background: var(--surface);
  border-left: 5px solid var(--mulberry);
  font-size: 13.5px;
}
.flash.ok { border-left-color: var(--aquamarine); }
.flash.warn { border-left-color: var(--raspberry); background: var(--peony); }
.flash.error { border-left-color: var(--raspberry); background: var(--peony); color: var(--raspberry-deep); }

.empty-state { text-align: center; padding: 56px 20px; }
.empty-state h2 { font-size: 22px; font-weight: 700; margin: 0 0 10px; }
.empty-state p { color: var(--ink-soft); max-width: 46ch; margin: 0 auto 22px; }

code {
  background: var(--peony);
  color: var(--raspberry-deep);
  padding: 2px 6px;
  border-radius: 5px;
  font-family: var(--data);
  font-size: .92em;
  font-weight: 700;
}

.note { font-size: 12.5px; color: var(--ink-soft); }
.right { text-align: right; }
.nowrap { white-space: nowrap; }
.sep { height: 1px; background: var(--rule-soft); margin: 20px 0; }

/* ------------------------------- auth pages ------------------------------ */

/* A centred card on peony, for the pages that are not the sign-in itself: the
   error page, and anything else that stands alone. Kept because those pages use
   it — deleting it silently broke both the first time. */
.auth-page { min-height: 100vh; display: grid; place-items: center; padding: 32px 20px; background: var(--peony); }
.auth-card { width: 100%; max-width: 400px; }
.auth-card .brand-block { margin-bottom: 22px; text-align: center; }
.auth-card .brand-block img { display: block; width: 100%; max-width: 268px; height: auto; margin: 0 auto; }
.auth-card .brand-block small { display: block; margin-top: 14px; font-size: 12.5px; color: var(--ink-soft); }

/* --------------------------------- sign in -------------------------------- */
/* Laid out like BFT OS's own sign-in: a mulberry panel carrying the line and the
   emblem, the form opposite on white, in the same 1.05fr / 1fr proportion. Moving
   between the two should not feel like moving between two products. */

.auth {
  min-height: 100vh;
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  background: var(--white);
}

.auth__panel {
  background: var(--mulberry);
  color: var(--peony);
  padding: 56px clamp(32px, 5vw, 76px);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 22px;
  position: relative;
  overflow: hidden;
}

/* The emblem, oversized and bled off the corner. At 8% it reads as texture
   rather than a second logo competing with the wordmark opposite. */
.auth__panel::after {
  content: '';
  position: absolute;
  right: -14%;
  bottom: -18%;
  width: 60%;
  aspect-ratio: 1;
  background: url('/static/img/plan-512.png') no-repeat center / contain;
  /* The plan icon rather than the app tile: it is an abstract mark, so it reads as
     texture where the lettered tile read as a second logo. That also means it can
     sit at BFT OS's own 8% instead of being faded almost away. */
  opacity: .08;
  pointer-events: none;
}

.auth__panel .eyebrow { color: var(--raspberry); position: relative; }

.auth__quote {
  font-size: clamp(1.4rem, 2.4vw, 2rem);
  font-weight: 500;
  line-height: 1.3;
  max-width: 20ch;
  margin: 0;
  position: relative;
}
.auth__quote em { font-style: normal; color: var(--raspberry); font-weight: 800; }

.auth__attrib {
  font-size: 12px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: rgba(253, 229, 238, .6);
  margin: 0;
  position: relative;
}

.auth__form {
  padding: 56px clamp(28px, 5vw, 68px);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 20px;
  max-width: 540px;
  width: 100%;
}
.auth__logo { width: min(230px, 62%); height: auto; }
.auth__head h1 { margin: 0 0 6px; font-size: 30px; }
.auth__form .field { margin: 0; }
.auth__form .flash { margin: 0; }
/* The first-run page nests its fields in a form inside the column, so the column's
   own gap does not reach them. */
.auth__form form {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* Stacked on a narrow screen, panel first — but the panel gives up most of its
   height, because the form is what you came for. */
@media (max-width: 860px) {
  .auth { grid-template-columns: 1fr; }
  .auth__panel { padding: 34px 24px; gap: 12px; }
  .auth__quote { font-size: 1.35rem; max-width: none; }
  .auth__panel::after { width: 46%; right: -10%; bottom: -22%; }
  .auth__form { padding: 32px 24px 44px; max-width: none; }
}

/* -------------------------------- detail --------------------------------- */

.item-row .st { display: inline-flex; align-items: center; gap: 8px; }

.stage-strip { display: flex; gap: 3px; margin-bottom: 6px; }
.stage-strip .seg { flex: 1; height: 9px; border-radius: 3px; }

details.raw summary {
  cursor: pointer;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--raspberry);
}
details.raw pre {
  background: var(--ground);
  border: 1px solid var(--rule-soft);
  padding: 14px;
  overflow: auto;
  font: 400 12px/1.5 var(--data);
  border-radius: var(--r-ctl);
}

@media (max-width: 780px) {
  .shell { grid-template-columns: 1fr; }
  .rail { position: static; height: auto; border-right: 0; border-bottom: 1px solid var(--peony-deep); }
  .nav { flex-direction: row; flex-wrap: wrap; }
  .nav-label { display: none; }
  .rail-foot { margin-top: 14px; }
  .board-wrap { max-height: none; }
  th.pin, td.pin { position: static; min-width: 180px; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}

@media print {
  .rail, .pulse, .filters, .btn { display: none !important; }
  .shell { grid-template-columns: 1fr; }
  .board-wrap { max-height: none; border: 0; }
  body { background: var(--white); }
}
