/* =====================================================================
   Project Management System : design system
   One stylesheet drives login, desktop shell, and mobile shell so the
   surfaces cannot drift apart. Layout reflows; components never change.
   ===================================================================== */

/* ------------------------------------------------------- 0. typefaces
   Self hosted woff2 from Fontsource. No external font hosts, so the CSP
   carries no Google entries and public pages make zero third party
   requests. Latin subset only, which covers the interface. */
@font-face {
  font-family: 'Archivo'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('../fonts/archivo-latin-400-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Archivo'; font-style: normal; font-weight: 500; font-display: swap;
  src: url('../fonts/archivo-latin-500-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Archivo'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('../fonts/archivo-latin-600-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Archivo'; font-style: normal; font-weight: 700; font-display: swap;
  src: url('../fonts/archivo-latin-700-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('../fonts/ibm-plex-mono-latin-400-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 500; font-display: swap;
  src: url('../fonts/ibm-plex-mono-latin-500-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('../fonts/ibm-plex-mono-latin-600-normal.woff2') format('woff2');
}

/* ---------------------------------------------------------- 1. tokens */
:root {
  --blue-50:  #EFF5FF;
  --blue-100: #DCE8FF;
  --blue-400: #5B93F7;
  --blue-500: #3B82F6;
  --blue-600: #2563EB;
  --blue-700: #1D4ED8;
  --blue-900: #16306E;

  --amber:  #F5A524;   /* trim, warnings, "attention" */
  --teal:   #14B8A6;   /* done, healthy */
  --violet: #7C5CFF;   /* automation, review */
  --rose:   #E5484D;   /* blocked, critical */
  --slate:  #64748B;

  --radius-sm: 6px;
  --radius:    10px;
  --radius-lg: 16px;
  --radius-pill: 999px;

  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;

  --font-ui: "Archivo", "Segoe UI", system-ui, -apple-system, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  --sidebar-w: 260px;
  --topbar-h: 60px;
  --bottomnav-h: 62px;

  --transition: 160ms cubic-bezier(.3, .7, .4, 1);
}

/* light is the default palette */
:root,
[data-theme="light"] {
  --bg:            #EEF3FA;
  --bg-grid:       rgba(37, 99, 235, .05);
  --surface:       #FFFFFF;
  --surface-2:     #F6F9FE;
  --surface-3:     #EAF1FB;
  --border:        #D7E1F0;
  --border-strong: #B9C9E2;
  --text:          #0F1B2D;
  --text-dim:      #55677F;
  --text-faint:    #8496AE;
  --primary:       var(--blue-600);
  --primary-hover: var(--blue-700);
  --primary-soft:  var(--blue-50);
  --on-primary:    #FFFFFF;
  --accent:        var(--amber);
  --shadow-1: 0 1px 2px rgba(15, 27, 45, .06), 0 1px 3px rgba(15, 27, 45, .05);
  --shadow-2: 0 6px 18px rgba(15, 27, 45, .10);
  --shadow-3: 0 18px 45px rgba(15, 27, 45, .18);
  --overlay: rgba(15, 27, 45, .45);
}

[data-theme="dark"] {
  --bg:            #0A1320;
  --bg-grid:       rgba(91, 147, 247, .07);
  --surface:       #111E31;
  --surface-2:     #16253B;
  --surface-3:     #1D2F49;
  --border:        #223148;
  --border-strong: #33475F;
  --text:          #E7EEF9;
  --text-dim:      #9BADC6;
  --text-faint:    #7589A5;
  --primary:       var(--blue-500);
  --primary-hover: var(--blue-400);
  --primary-soft:  rgba(59, 130, 246, .14);
  --on-primary:    #04101F;
  --accent:        var(--amber);
  --shadow-1: 0 1px 2px rgba(0, 0, 0, .4);
  --shadow-2: 0 8px 22px rgba(0, 0, 0, .45);
  --shadow-3: 0 20px 50px rgba(0, 0, 0, .55);
  --overlay: rgba(4, 10, 18, .65);
}

/* --------------------------------------------------------- 2. reset */
*, *::before, *::after { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  font-family: var(--font-ui);
  font-size: 15px;
  line-height: 1.55;
  color: var(--text);
  background-color: var(--bg);
  background-image:
    linear-gradient(var(--bg-grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--bg-grid) 1px, transparent 1px);
  background-size: 28px 28px, 28px 28px;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
  overflow-wrap: break-word;
}

h1, h2, h3, h4 { margin: 0; font-weight: 600; letter-spacing: -.01em; line-height: 1.25; }
h1 { font-size: 22px; }
h2 { font-size: 18px; }
h3 { font-size: 15px; }
p { margin: 0 0 var(--space-3); }
a { color: var(--primary); text-decoration: none; }
a:hover { text-decoration: underline; }
svg { flex: none; }

:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

.mono { font-family: var(--font-mono); }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.hidden { display: none !important; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

/* ---------------------------------------------------------- 3. brand */
.brand { display: flex; align-items: center; gap: 10px; min-width: 0; }
.brand-mark {
  width: 32px; height: 32px; border-radius: 9px; flex: none;
  background: linear-gradient(150deg, var(--blue-500), var(--blue-700) 70%);
  display: grid; place-items: center;
  box-shadow: 0 2px 8px rgba(37, 99, 235, .35);
}
.brand-mark svg { width: 20px; height: 20px; color: #fff; }
.brand-text { min-width: 0; display: flex; flex-direction: column; }
.brand-title {
  font-size: 15px; font-weight: 700; letter-spacing: -.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* The tagline sizes itself. It is wider than the name, so it sets the width of
   the brand block, which is what we want: the block is then wide enough for
   both lines wherever it appears, whether stretched in the sidebar or centred
   on the login card. The name above it keeps its ellipsis as a safety net if a
   longer app_name is ever configured. */
.brand-sub {
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-faint);
  white-space: nowrap;
}

/* --------------------------------------------------------- 4. buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 38px; padding: 0 14px;
  font-family: var(--font-ui); font-size: 14px; font-weight: 600;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  cursor: pointer;
  transition: background var(--transition), border-color var(--transition), transform var(--transition), color var(--transition);
  white-space: nowrap;
  text-decoration: none;
}
.btn svg { width: 17px; height: 17px; }
.btn:hover { background: var(--surface-2); border-color: var(--primary); text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn[disabled], .btn[aria-disabled="true"] { opacity: .55; cursor: not-allowed; transform: none; }

.btn-primary {
  color: var(--on-primary);
  background: linear-gradient(180deg, var(--primary), var(--primary-hover));
  border-color: var(--primary-hover);
  box-shadow: var(--shadow-1);
}
.btn-primary:hover { background: var(--primary-hover); border-color: var(--primary-hover); color: var(--on-primary); }

.btn-ghost { background: transparent; border-color: transparent; color: var(--text-dim); }
.btn-ghost:hover { background: var(--surface-2); border-color: var(--border); color: var(--text); }

.btn-danger { color: #fff; background: var(--rose); border-color: var(--rose); }
.btn-danger:hover { background: #C93B40; border-color: #C93B40; color: #fff; }

.btn-block { width: 100%; }
.btn-sm { height: 32px; padding: 0 10px; font-size: 13px; }
.btn-sm svg { width: 15px; height: 15px; }
.btn-lg { height: 46px; padding: 0 20px; font-size: 15px; }

.btn-icon { width: 38px; padding: 0; }
.btn-icon.btn-sm { width: 32px; }

.btn-row { display: flex; flex-wrap: wrap; gap: var(--space-2); }

/* ---------------------------------------------------------- 5. fields */
.field { display: grid; gap: 6px; margin-bottom: var(--space-4); }
.label { font-size: 13px; font-weight: 600; color: var(--text-dim); }
.hint { font-size: 12px; color: var(--text-faint); }

.input, .select, .textarea {
  width: 100%; min-height: 40px; padding: 9px 12px;
  font-family: var(--font-ui); font-size: 15px; color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  transition: border-color var(--transition), box-shadow var(--transition);
}
.textarea { min-height: 104px; resize: vertical; line-height: 1.5; }
.select { appearance: none; padding-right: 34px; background-image: none; cursor: pointer; }
.input:focus, .select:focus, .textarea:focus {
  outline: none; border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-soft);
}
.input::placeholder, .textarea::placeholder { color: var(--text-faint); }
.input[aria-invalid="true"] { border-color: var(--rose); }

.input-wrap { position: relative; display: flex; align-items: center; }
.input-wrap .input { padding-right: 42px; }
.input-affix {
  position: absolute; right: 4px;
  display: grid; place-items: center;
  width: 34px; height: 34px;
  color: var(--text-faint); background: transparent; border: 0; border-radius: var(--radius-sm);
  cursor: pointer;
}
.input-affix:hover { color: var(--primary); background: var(--surface-2); }
.input-affix svg { width: 17px; height: 17px; }

.select-wrap { position: relative; }
.select-wrap::after {
  content: ""; position: absolute; right: 14px; top: 50%; pointer-events: none;
  width: 7px; height: 7px; margin-top: -5px;
  border-right: 2px solid var(--text-faint); border-bottom: 2px solid var(--text-faint);
  transform: rotate(45deg);
}

.check { display: flex; align-items: flex-start; gap: 10px; font-size: 14px; cursor: pointer; }
.check input { width: 18px; height: 18px; margin: 1px 0 0; accent-color: var(--primary); cursor: pointer; }

.grid-2 { display: grid; gap: var(--space-4); grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { display: grid; gap: var(--space-4); grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 720px) {
  .grid-2, .grid-3 { grid-template-columns: minmax(0, 1fr); }
}

/* ----------------------------------------------------------- 6. cards */
.card {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  overflow: hidden;
}
.card-head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--border);
}
.card-title { display: flex; align-items: center; gap: 10px; font-size: 15px; font-weight: 600; }
.card-title svg { width: 18px; height: 18px; color: var(--primary); }
.card-body { padding: var(--space-5); }
.card-body > :last-child { margin-bottom: 0; }

/* Signature device: a status rail on the leading edge of cards and rows. */
.rail { position: relative; padding-left: calc(var(--space-5) + 4px); }
.rail::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
  background: var(--rail-color, var(--primary));
}
.rail-todo        { --rail-color: var(--slate); }
.rail-in_progress { --rail-color: var(--blue-500); }
.rail-review      { --rail-color: var(--violet); }
.rail-blocked     { --rail-color: var(--rose); }
.rail-done        { --rail-color: var(--teal); }
.rail-cancelled   { --rail-color: var(--border-strong); }

/* ------------------------------------------------------------ 7. KPIs */
.kpi-grid { display: grid; gap: var(--space-4); grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
.kpi { padding: var(--space-4) var(--space-5); }
.kpi-label {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--text-faint);
}
.kpi-value { font-family: var(--font-mono); font-size: 30px; font-weight: 600; line-height: 1.2; }
.kpi-foot { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-dim); }
.kpi-foot svg { width: 14px; height: 14px; }

/* ---------------------------------------------------------- 8. badges */
.badge {
  display: inline-flex; align-items: center; gap: 6px;
  height: 22px; padding: 0 9px;
  font-family: var(--font-mono); font-size: 11px; font-weight: 500; letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-dim);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  white-space: nowrap;
}
.badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.badge-plain::before { display: none; }
.badge-blue   { color: var(--blue-600); background: var(--primary-soft); border-color: transparent; }
.badge-teal   { color: #0F8C7F; background: rgba(20, 184, 166, .13); border-color: transparent; }
.badge-violet { color: #6247D9; background: rgba(124, 92, 255, .14); border-color: transparent; }
.badge-amber  { color: #A9700A; background: rgba(245, 165, 36, .18); border-color: transparent; }
.badge-rose   { color: #C93B40; background: rgba(229, 72, 77, .14); border-color: transparent; }
[data-theme="dark"] .badge-teal   { color: #4DD8C7; }
[data-theme="dark"] .badge-violet { color: #A895FF; }
[data-theme="dark"] .badge-amber  { color: #F7BC5C; }
[data-theme="dark"] .badge-rose   { color: #FF8C8F; }
[data-theme="dark"] .badge-blue   { color: #7FB0FF; }

.tag {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 8px; font-size: 12px;
  background: var(--surface-3); border-radius: var(--radius-sm); color: var(--text-dim);
}

/* --------------------------------------------------------- 9. avatars */
.avatar {
  display: grid; place-items: center; flex: none;
  width: 32px; height: 32px; border-radius: 50%;
  font-family: var(--font-mono); font-size: 12px; font-weight: 600; letter-spacing: .02em;
  color: #fff; background: var(--primary);
  border: 2px solid var(--surface);
}
.avatar-lg { width: 60px; height: 60px; font-size: 20px; }
.avatar-sm { width: 24px; height: 24px; font-size: 10px; }
.avatar-stack { display: flex; }
.avatar-stack .avatar + .avatar { margin-left: -8px; }

/* ---------------------------------------------------------- 10. table */
.table-wrap { width: 100%; overflow-x: auto; }
.table { width: 100%; border-collapse: collapse; font-size: 14px; min-width: 620px; }
.table th {
  padding: 10px var(--space-4);
  font-family: var(--font-mono); font-size: 11px; font-weight: 500; letter-spacing: .1em;
  text-transform: uppercase; text-align: left; color: var(--text-faint);
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.table td { padding: 11px var(--space-4); border-bottom: 1px solid var(--border); vertical-align: middle; }
.table tbody tr:hover td { background: var(--surface-2); }
.table tbody tr:last-child td { border-bottom: 0; }
.cell-strong { font-weight: 600; }
.cell-dim { color: var(--text-dim); }
.cell-key { font-family: var(--font-mono); font-size: 12px; color: var(--text-faint); }
.cell-actions { display: flex; gap: 6px; justify-content: flex-end; }

/* ----------------------------------------------------------- 11. misc */
.banner {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 12px 14px; margin-bottom: var(--space-4);
  font-size: 14px;
  border: 1px solid var(--border); border-left-width: 4px;
  border-radius: var(--radius);
  background: var(--surface-2);
}
.banner svg { width: 18px; height: 18px; margin-top: 1px; }
.banner-error { border-left-color: var(--rose); color: #B4373C; background: rgba(229, 72, 77, .09); }
.banner-warn  { border-left-color: var(--amber); color: #9A6708; background: rgba(245, 165, 36, .12); }
.banner-info  { border-left-color: var(--primary); color: var(--text); }
.banner-ok    { border-left-color: var(--teal); color: #0C7F73; background: rgba(20, 184, 166, .11); }
[data-theme="dark"] .banner-error { color: #FF9497; }
[data-theme="dark"] .banner-warn  { color: #F8C471; }
[data-theme="dark"] .banner-ok    { color: #5FDCCB; }

.empty { padding: var(--space-7) var(--space-5); text-align: center; color: var(--text-dim); }
/* Direct child only. This sized every svg inside an empty state, including the
   icon inside a button placed there, which blew it up to 34px and pushed it off
   centre by the trailing margin. */
.empty > svg { width: 34px; height: 34px; margin-bottom: var(--space-3); color: var(--text-faint); }
.empty .btn svg { width: 16px; height: 16px; margin: 0; color: inherit; }
.empty h3 { margin-bottom: 6px; color: var(--text); }

.divider { height: 1px; background: var(--border); border: 0; margin: var(--space-5) 0; }

.spinner {
  width: 18px; height: 18px; border-radius: 50%;
  border: 2px solid var(--border-strong); border-top-color: var(--primary);
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.segmented {
  display: inline-flex; padding: 3px; gap: 2px;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius);
}
.segmented button {
  display: inline-flex; align-items: center; gap: 6px;
  height: 30px; padding: 0 11px;
  font-family: var(--font-ui); font-size: 13px; font-weight: 600;
  color: var(--text-dim); background: transparent; border: 0; border-radius: 7px; cursor: pointer;
}
.segmented button svg { width: 15px; height: 15px; }
.segmented button[aria-pressed="true"] { color: var(--on-primary); background: var(--primary); }

/* --------------------------------------------------------- 12. toasts */
.toast-stack {
  position: fixed; z-index: 90; right: var(--space-4); bottom: var(--space-4);
  display: grid; gap: 10px; max-width: min(360px, calc(100vw - 32px));
}
.toast {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 12px 14px;
  font-size: 14px;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-left: 4px solid var(--primary);
  border-radius: var(--radius); box-shadow: var(--shadow-2);
  animation: toast-in 200ms ease-out;
}
.toast svg { width: 18px; height: 18px; margin-top: 1px; }
.toast-ok { border-left-color: var(--teal); }
.toast-error { border-left-color: var(--rose); }
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@media (max-width: 720px) {
  .toast-stack { right: var(--space-3); left: var(--space-3); bottom: calc(var(--bottomnav-h) + var(--space-3)); max-width: none; }
}

/* ---------------------------------------------------------- 13. login */
.auth-page { display: grid; place-items: center; min-height: 100vh; padding: var(--space-5); }
.auth-card {
  width: 100%; max-width: 420px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-3);
  overflow: hidden;
}
.auth-top {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  padding: var(--space-5);
  border-bottom: 1px solid var(--border);
  background:
    radial-gradient(circle at 100% 0%, var(--primary-soft), transparent 60%),
    var(--surface);
}
.auth-body { padding: var(--space-5); }
.auth-head { margin-bottom: var(--space-5); }
.auth-head h1 { font-size: 20px; margin-bottom: 4px; }
.auth-head p { color: var(--text-dim); font-size: 14px; margin: 0; }
.auth-foot {
  padding: var(--space-4) var(--space-5);
  border-top: 1px solid var(--border);
  background: var(--surface-2);
  font-size: 12px; color: var(--text-faint);
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
}
.auth-meta { font-family: var(--font-mono); font-size: 11px; letter-spacing: .06em; }

/* ----------------------------------------------------------- 14. shell */
.shell { display: grid; grid-template-columns: var(--sidebar-w) minmax(0, 1fr); min-height: 100vh; }

.sidebar {
  position: sticky; top: 0; align-self: start;
  display: flex; flex-direction: column; gap: var(--space-4);
  height: 100vh; padding: var(--space-4);
  background: var(--surface);
  border-right: 1px solid var(--border);
}
.sidebar-brand { padding: var(--space-2) 4px var(--space-3); }
.nav { display: grid; gap: 2px; overflow-y: auto; }
.nav-section {
  padding: var(--space-4) var(--space-2) 6px;
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--text-faint);
}
.nav-item {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 11px;
  font-size: 14px; font-weight: 500; color: var(--text-dim);
  border: 1px solid transparent; border-radius: var(--radius);
  cursor: pointer; text-decoration: none;
  transition: background var(--transition), color var(--transition);
}
.nav-item svg { width: 18px; height: 18px; }
.nav-item:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }
.nav-item.is-active { color: var(--primary); background: var(--primary-soft); border-color: color-mix(in srgb, var(--primary) 25%, transparent); font-weight: 600; }
.nav-count {
  margin-left: auto; min-width: 20px; padding: 0 6px;
  font-family: var(--font-mono); font-size: 11px; text-align: center;
  color: var(--on-primary); background: var(--primary); border-radius: var(--radius-pill);
}
.sidebar-foot { margin-top: auto; display: grid; gap: var(--space-3); }
.sidebar-user {
  display: flex; align-items: center; gap: 10px;
  padding: 8px; border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface-2); min-width: 0;
}
.sidebar-user-name { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sidebar-user-role { font-family: var(--font-mono); font-size: 10px; color: var(--text-faint); text-transform: uppercase; letter-spacing: .1em; }

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

.topbar {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; gap: var(--space-3);
  height: var(--topbar-h); padding: 0 var(--space-5);
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}
.topbar-title { display: grid; min-width: 0; }
.topbar-title h1 { font-size: 17px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar-crumb {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--text-faint);
}
.topbar-actions { display: flex; align-items: center; gap: var(--space-2); margin-left: auto; }
.topbar-brand { display: none; }

/* The badge is positioned against the button. Belt and braces: the id is
   targeted as well as the class, because when neither applied the badge
   positioned itself against the page and floated into the corner of the
   window. */
.bell, #notifyBtn { position: relative; }
.bell-dot {
  position: absolute; top: 2px; right: 2px;
  min-width: 16px; height: 16px; padding: 0 4px;
  font-family: var(--font-mono); font-size: 10px; line-height: 16px; text-align: center;
  color: #fff; background: var(--rose); border-radius: var(--radius-pill);
}

.content { padding: var(--space-5); display: grid; gap: var(--space-5); align-content: start; }
.page-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap; }
.page-head p { color: var(--text-dim); margin: 4px 0 0; font-size: 14px; }

.bottomnav { display: none; }

/* ------------------------------------------------------- 15. overlays */
.overlay {
  position: fixed; inset: 0; z-index: 60;
  background: var(--overlay);
  display: grid; place-items: center; padding: var(--space-4);
}
.modal {
  width: 100%; max-width: 520px; max-height: calc(100vh - 48px); overflow-y: auto;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-3);
}
.modal-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--border); }
.modal-body { padding: var(--space-5); }
.modal-foot { display: flex; justify-content: flex-end; gap: var(--space-2); padding: var(--space-4) var(--space-5); border-top: 1px solid var(--border); background: var(--surface-2); }

.panel {
  position: fixed; z-index: 55; top: var(--topbar-h); right: var(--space-4);
  width: min(400px, calc(100vw - 32px)); max-height: min(560px, calc(100vh - 120px));
  display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-3); overflow: hidden;
}
.panel-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-4); border-bottom: 1px solid var(--border); }
.panel-list { overflow-y: auto; }
.panel-item {
  display: flex; gap: 10px; padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border); font-size: 14px; cursor: pointer;
}
.panel-item:hover { background: var(--surface-2); }
.panel-item.is-unread { background: var(--primary-soft); }
.panel-item-title { font-weight: 600; }
.panel-item-meta { font-family: var(--font-mono); font-size: 11px; color: var(--text-faint); }

/* ------------------------------------------------- 16. mobile reflow */
/* Only the arrangement changes below this width. Components, icons,
   borders, radii, and colors are identical to the desktop rendering. */
@media (max-width: 900px) {
  .shell { grid-template-columns: minmax(0, 1fr); }
  .sidebar { display: none; }
  .topbar { padding: 0 var(--space-4); }
  .topbar-brand { display: flex; }
  .topbar-title { display: none; }
  .content { padding: var(--space-4); padding-bottom: calc(var(--bottomnav-h) + var(--space-5)); }
  .panel { top: auto; bottom: calc(var(--bottomnav-h) + var(--space-2)); right: var(--space-3); left: var(--space-3); width: auto; }

  .bottomnav {
    position: fixed; z-index: 40; bottom: 0; left: 0; right: 0;
    display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
    height: calc(var(--bottomnav-h) + env(safe-area-inset-bottom));
    padding-bottom: env(safe-area-inset-bottom);
    background: color-mix(in srgb, var(--surface) 94%, transparent);
    backdrop-filter: blur(10px);
    border-top: 1px solid var(--border);
  }
  .bottomnav .nav-item {
    flex-direction: column; gap: 3px; justify-content: center;
    padding: 0; font-size: 10.5px; font-weight: 600; border-radius: 0; border: 0;
    letter-spacing: .01em;
  }
  .bottomnav .nav-item.is-active { background: transparent; color: var(--primary); }
  .bottomnav .nav-item.is-active svg { transform: translateY(-1px); }
  .bottomnav .nav-count {
    position: absolute; transform: translate(14px, -12px);
  }
  .bottomnav .nav-item { position: relative; }
}

@media (display-mode: standalone) {
  /* Installed app: the OS provides the chrome, so reclaim the top inset. */
  .topbar { padding-top: env(safe-area-inset-top); height: calc(var(--topbar-h) + env(safe-area-inset-top)); }
}

@media print {
  .sidebar, .topbar, .bottomnav, .toast-stack { display: none !important; }
  body { background: #fff; }
}

/* ------------------------------------------------------- 17. icon base */
/* Every icon in the app comes from one sprite, so the login page, the
   desktop shell, and the mobile shell always draw the same glyphs. */
.icon {
  width: 18px; height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.icon-fill { fill: currentColor; stroke: none; }
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.brand-glyph { width: 20px; height: 20px; color: #fff; fill: currentColor; stroke: none; }

/* ------------------------------------------------------ 18. checklist */
.check-row {
  display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-3);
  padding: 9px 0; border-bottom: 1px solid var(--border);
}
.check-row:last-child { border-bottom: 0; }
.check-row .check { flex: 1; }

/* ---------------------------------------------------- 19. work (phase 2) */
/* Projects, task grids, and detail panels. Everything here reuses the tokens
   and components above: same radii, same borders, same rail treatment, so a
   task row and an admin row are visibly the same family. */

.toolbar {
  display: flex; align-items: center; gap: var(--space-3);
  margin-bottom: var(--space-4);
}
.toolbar-wrap { flex-wrap: wrap; }

.input-sm { padding: 6px 10px; font-size: 13px; height: 34px; }
.input-color { padding: 2px; width: 56px; height: 34px; cursor: pointer; }

.check { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text-dim); }
.check input { width: 16px; height: 16px; accent-color: var(--primary); }

.field-row { display: grid; gap: var(--space-3); grid-template-columns: 1fr 1fr; }
.mt { margin-top: var(--space-4); }
.sub { margin: var(--space-4) 0 var(--space-2); font-size: 12px; text-transform: uppercase;
       letter-spacing: .08em; color: var(--text-faint); font-family: var(--font-mono); }
.text-rose { color: var(--rose); font-weight: 600; }

.two-col { display: grid; gap: var(--space-4); grid-template-columns: 3fr 2fr; margin-bottom: var(--space-4); }

.badge-dim { --badge-color: var(--text-faint); }

/* Definition rows, used by the project and task summaries */
.deflist { display: grid; gap: 2px; }
.def { display: grid; grid-template-columns: 130px minmax(0, 1fr); gap: var(--space-3);
       padding: 7px 0; border-bottom: 1px solid var(--border); align-items: center; }
.def:last-child { border-bottom: none; }
.def dt { font-size: 12.5px; color: var(--text-dim); }
.def dd { margin: 0; font-size: 13.5px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* Progress meter */
.meter { display: inline-block; width: 100px; height: 6px; border-radius: 99px;
         background: var(--surface-3); overflow: hidden; vertical-align: middle; }
.meter-fill { display: block; height: 100%; border-radius: 99px; transition: width var(--transition); }

/* Project cards */
.grid-cards { display: grid; gap: var(--space-4); grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
.pcard {
  display: block; position: relative; overflow: hidden;
  padding: var(--space-4) var(--space-5); text-decoration: none; color: inherit;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  transition: border-color var(--transition), transform var(--transition), box-shadow var(--transition);
}
.pcard:hover { border-color: var(--border-strong); transform: translateY(-1px); box-shadow: var(--shadow-1); }
.pcard-top { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
.pcard-key { font-size: 11px; letter-spacing: .08em; color: var(--text-faint); }
.pcard-name { margin: 8px 0 4px; font-size: 16px; font-weight: 700; line-height: 1.3; }
.pcard-desc { margin: 0 0 var(--space-3); font-size: 13px; color: var(--text-dim);
              display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.pcard-meta { display: flex; align-items: center; gap: 8px; font-size: 12px; margin-bottom: var(--space-3); }
.pcard-progress { display: flex; align-items: center; gap: 10px; font-size: 12px; }
.pcard-flags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: var(--space-3); }

/* Task table */
.table-wrap { overflow-x: auto; }
.table-tasks { min-width: 760px; }
.task-row td { vertical-align: middle; }
.task-row.is-child .col-title { padding-left: 34px; }
.task-row.is-child .col-key a { opacity: .75; }
.col-key { width: 92px; }
.col-status { width: 150px; }
.col-person { width: 170px; }
.col-date { width: 150px; }
.col-pri { width: 120px; }
.col-act { width: 84px; text-align: right; white-space: nowrap; }
.task-title { cursor: pointer; }
.task-title:hover { color: var(--primary); text-decoration: underline; }

/* Inline editors inside table cells: quiet until touched, so the grid still
   reads as data rather than as a wall of form controls. */
.cell-select, .cell-input {
  width: 100%; max-width: 100%; padding: 5px 8px; font: inherit; font-size: 13px;
  color: var(--text); background: transparent;
  border: 1px solid transparent; border-radius: 8px;
  transition: border-color var(--transition), background var(--transition);
}
.cell-select:hover, .cell-input:hover { border-color: var(--border); background: var(--surface-2); }
.cell-select:focus, .cell-input:focus { border-color: var(--primary); background: var(--surface-2); outline: none; }
.cell-select.is-saving, .cell-input.is-saving { border-color: var(--amber); opacity: .7; }
.cell-select.is-saved, .cell-input.is-saved { border-color: var(--teal); }

.row-toggle {
  display: inline-grid; place-items: center; width: 22px; height: 22px; margin-right: 4px;
  background: none; border: 0; border-radius: 6px; color: var(--text-faint); cursor: pointer;
}
.row-toggle:hover { background: var(--surface-3); color: var(--text); }
.row-toggle svg { width: 16px; height: 16px; transition: transform var(--transition); }
.row-toggle svg.is-open { transform: rotate(90deg); }

.chip { display: inline-flex; align-items: center; margin-right: 6px; }
.chip svg { width: 15px; height: 15px; }
.chip-blocked { color: var(--rose); }

/* Lists used on the task detail page */
.sublist, .deplist { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.sublist li, .deplist li {
  position: relative; overflow: hidden;
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 9px 12px; font-size: 13.5px;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 10px;
}
.deplist li .btn { margin-left: auto; }

.member-strip { display: flex; flex-wrap: wrap; gap: 8px; }
.member-chip {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 5px 10px 5px 5px; font-size: 13px;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 99px;
}

@media (max-width: 900px) {
  .two-col { grid-template-columns: 1fr; }
  .field-row { grid-template-columns: 1fr; }
  .grid-cards { grid-template-columns: 1fr; }
  .toolbar { flex-wrap: wrap; }
  .toolbar .input, .toolbar select { flex: 1 1 140px; min-width: 0; }
  .def { grid-template-columns: 110px minmax(0, 1fr); }
}

/* Breadcrumbs. Shown above the page head on detail views so there is always a
   way back up without relying on the browser button. */
.crumbs {
  display: flex; align-items: center; flex-wrap: wrap; gap: 4px;
  margin-bottom: var(--space-3); font-size: 12.5px;
}
.crumb {
  display: inline-flex; align-items: center; padding: 3px 8px; border-radius: 7px;
  color: var(--text-dim); text-decoration: none; max-width: 260px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
a.crumb:hover { color: var(--text); background: var(--surface-2); }
.crumb.is-current { color: var(--text); font-weight: 600; }
.crumb-sep { display: inline-flex; color: var(--text-faint); }
.crumb-sep svg { width: 14px; height: 14px; }

/* --------------------------------------- 20. toolbar sizing and mobile work */

/* Controls in a toolbar size to their content. The base .input rule is
   width:100%, which in a flex row makes every control claim a full line, so
   six filters became six stacked rows across the whole screen. */
.toolbar .input,
.toolbar select.input,
.toolbar input.input {
  width: auto;
  flex: 0 0 auto;
  min-width: 0;
}
.toolbar select.input { min-width: 120px; max-width: 190px; }
.toolbar input#tq    { flex: 1 1 220px; min-width: 160px; max-width: 340px; }
.toolbar .check      { flex: 0 0 auto; white-space: nowrap; }
.toolbar .btn        { flex: 0 0 auto; }

/* Mobile: the task grid becomes stacked cards instead of a table that has to
   be dragged sideways. Same rows, same data, same rail colour, reflowed. */
@media (max-width: 900px) {
  /* Any table marked table-stack stops being a table on a narrow screen and
     becomes one card per row, with each cell labelled from its data-label.
     Same markup, no horizontal scrolling, nothing cut off. */
  .table-wrap { overflow-x: visible; }
  .table-tasks, .table-stack { min-width: 0; display: block; }
  .table-tasks thead, .table-stack thead { display: none; }
  .table-tasks tbody, .table-tasks tr, .table-tasks td,
  .table-stack tbody, .table-stack tr, .table-stack td { display: block; width: auto; }

  .table-stack tr {
    position: relative; overflow: hidden;
    margin-bottom: var(--space-3); padding: var(--space-3) var(--space-4);
    background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius);
  }
  .table-stack tr:last-child { margin-bottom: 0; }
  .table-stack td {
    display: grid; grid-template-columns: 96px minmax(0, 1fr);
    align-items: center; gap: var(--space-3);
    padding: 5px 0; border: 0; min-width: 0;
  }
  .table-stack td::before {
    content: attr(data-label);
    font-size: 11px; text-transform: uppercase; letter-spacing: .06em;
    color: var(--text-faint); font-family: var(--font-mono);
  }
  /* The first cell reads as the card heading. */
  .table-stack td:first-child { grid-template-columns: minmax(0, 1fr); font-size: 15px; }
  .table-stack td:first-child::before { display: none; }
  /* A cell with no label is an action row: full width, buttons at the end. */
  .table-stack td[data-label=""] {
    grid-template-columns: minmax(0, 1fr); justify-items: end;
    margin-top: var(--space-2); padding-top: var(--space-3);
    border-top: 1px solid var(--border);
  }
  .table-stack td[data-label=""]::before { display: none; }
  .table-stack .cell-actions { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
  .table-stack .cell-dim { overflow-wrap: anywhere; }

  .table-tasks tr.task-row {
    position: relative; overflow: hidden;
    margin-bottom: var(--space-3); padding: var(--space-3) var(--space-4) var(--space-3) var(--space-5);
    background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius);
  }
  .table-tasks tr.task-row:last-child { margin-bottom: 0; }

  .table-tasks td {
    display: grid; grid-template-columns: 88px minmax(0, 1fr);
    align-items: center; gap: var(--space-3);
    padding: 5px 0; border: 0;
  }
  .table-tasks td::before {
    content: attr(data-label);
    font-size: 11px; text-transform: uppercase; letter-spacing: .06em;
    color: var(--text-faint); font-family: var(--font-mono);
  }
  /* Key and title read as the card heading, so they skip the label column. */
  .table-tasks td.col-key,
  .table-tasks td.col-title { grid-template-columns: minmax(0, 1fr); }
  .table-tasks td.col-key::before,
  .table-tasks td.col-title::before { display: none; }
  .table-tasks td.col-key { font-size: 11.5px; letter-spacing: .06em; }
  .table-tasks td.col-title { font-size: 15px; font-weight: 600; padding-bottom: var(--space-3); }
  .table-tasks tr.task-row.is-child .col-title { padding-left: 0; }
  .table-tasks tr.task-row.is-child { margin-left: var(--space-4); }

  .table-tasks td.col-act {
    grid-template-columns: minmax(0, 1fr); justify-items: end;
    margin-top: var(--space-2); padding-top: var(--space-3);
    border-top: 1px solid var(--border);
  }
  .table-tasks td.col-act::before { display: none; }
  .table-tasks .cell-select, .table-tasks .cell-input {
    border-color: var(--border); background: var(--surface);
  }

  /* Nothing on a project page may push the viewport sideways. */
  .content, .page-head, .card, .card-body { max-width: 100%; min-width: 0; }
  .kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .kpi-value { font-size: 24px; }
  .crumb { max-width: 150px; }
}

@media (max-width: 420px) {
  .table-tasks td { grid-template-columns: 76px minmax(0, 1fr); }
  .toolbar select.input { flex: 1 1 130px; max-width: none; }
}

/* ------------------------------------- 21. board, timeline, calendar (p3) */

.hint-line { display: flex; align-items: center; gap: 8px; margin-top: var(--space-4);
             font-size: 12.5px; color: var(--text-faint); }
.hint-line svg { width: 15px; height: 15px; }
.icon.flip { transform: rotate(180deg); }

/* ---------------------------------------------------------------- board */
.board { display: flex; gap: var(--space-4); align-items: flex-start; overflow-x: auto; padding-bottom: var(--space-3); }
.bcol {
  flex: 0 0 288px; display: flex; flex-direction: column; max-height: 72vh;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius);
}
.bcol-head {
  position: relative; overflow: hidden;
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  padding: var(--space-3) var(--space-4) var(--space-3) var(--space-5);
  border-bottom: 1px solid var(--border);
}
.bcol-head h3 { margin: 0; font-size: 13px; font-weight: 700; }
.bcol-count { font-size: 12px; color: var(--text-faint); }
.bcol-body {
  display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-3); overflow-y: auto; min-height: 90px;
  transition: background var(--transition);
}
.bcol-body.is-over { background: var(--primary-soft); }
.bcol-empty { margin: 0; padding: var(--space-4) 0; text-align: center; font-size: 12.5px; color: var(--text-faint); }

.bcard {
  position: relative; overflow: hidden; cursor: grab;
  padding: var(--space-3) var(--space-3) var(--space-3) var(--space-4);
  background: var(--surface); border: 1px solid var(--border); border-radius: 10px;
  transition: border-color var(--transition), box-shadow var(--transition), opacity var(--transition);
}
.bcard:hover { border-color: var(--border-strong); box-shadow: var(--shadow-1); }
.bcard.is-dragging { opacity: .45; cursor: grabbing; }
.bcard-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.bcard-key { font-size: 11px; letter-spacing: .05em; text-decoration: none; color: var(--text-faint); }
.bcard-key:hover { color: var(--primary); }
.bcard-title { margin: 6px 0 8px; font-size: 13.5px; line-height: 1.4; cursor: pointer; }
.bcard-title:hover { color: var(--primary); }
.bcard-foot { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; font-size: 11.5px; }

/* ------------------------------------------------------------- timeline */
.tl { display: flex; align-items: flex-start; }
.tl-labels { flex: 0 0 210px; border-right: 1px solid var(--border); }
.tl-label {
  display: flex; align-items: center; gap: 8px; padding: 0 var(--space-3);
  font-size: 12.5px; white-space: nowrap; overflow: hidden;
}
.tl-label a { font-size: 11px; text-decoration: none; color: var(--text-faint); }
.tl-label-title { overflow: hidden; text-overflow: ellipsis; }
.tl-scroll { flex: 1 1 auto; overflow-x: auto; }
.tl-canvas { position: relative; }

.tl-bands { position: absolute; top: 0; left: 0; right: 0; height: 26px; }
.tl-band {
  position: absolute; top: 0; height: 26px;
  border-left: 1px solid var(--border); display: flex; align-items: center;
}
.tl-band span { padding-left: 6px; font-family: var(--font-mono); font-size: 10.5px;
                letter-spacing: .06em; text-transform: uppercase; color: var(--text-faint); }

.tl-grid { position: absolute; left: 0; right: 0; }
/* Row bands first, then day shading over them, so a bar always reads as
   sitting on the row its label is on. */
.tl-row { position: absolute; left: 0; right: 0; }
.tl-row.is-alt { background: var(--surface-2); opacity: .45; }
.tl-weekend { position: absolute; top: 0; bottom: 0; background: var(--text); opacity: .035; }
.tl-weekline { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--border); opacity: .6; }
.tl-today { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--amber); opacity: .9; }

.tl-arrows { position: absolute; left: 0; pointer-events: none; overflow: visible; }
.tl-arrows .tl-link { fill: none; stroke: var(--text-faint); stroke-width: 1.3; opacity: .75; }
.tl-arrows .tl-head { fill: var(--text-faint); opacity: .9; stroke: none; }

.tl-bars { position: absolute; left: 0; right: 0; }
.tl-bar {
  position: absolute; overflow: hidden;
  display: flex; align-items: center;
  padding-left: 10px; border-radius: 5px;
  background: var(--surface-3); border: 1px solid var(--border-strong);
}
.tl-bar::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
                  background: var(--rail-color, var(--primary)); }
.tl-bar-label { font-size: 11.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* A square turned 45 degrees, so it reads as a diamond centred on its day. */
.tl-diamond {
  position: absolute; border-radius: 2px; transform: rotate(45deg);
  background: var(--rail-color, var(--primary));
  border: 1px solid var(--surface);
}

/* Label for a bar too narrow to hold one. */
.tl-outside {
  position: absolute; display: flex; align-items: center; height: 20px;
  font-size: 11.5px; color: var(--text-dim); white-space: nowrap; pointer-events: none;
}

.tl-legend { display: flex; align-items: center; gap: var(--space-3); font-size: 11.5px; color: var(--text-faint); }
.tl-legend span { display: inline-flex; align-items: center; gap: 5px; }
.tl-legend i { display: inline-block; width: 11px; height: 11px; border-radius: 2px; }
.tl-key-today { background: var(--amber); width: 3px !important; height: 13px !important; border-radius: 0; }
.tl-key-weekend { background: var(--text); opacity: .12; }
.tl-key-link { border-bottom: 1.5px solid var(--text-faint); height: 1px !important; border-radius: 0; }

/* ------------------------------------------------------------- calendar */
.cal-head, .cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); }
.cal-head { gap: 1px; margin-bottom: 6px; }
.cal-head span { padding: 4px 6px; font-family: var(--font-mono); font-size: 10.5px;
                 letter-spacing: .08em; text-transform: uppercase; color: var(--text-faint); }
.cal-grid { gap: 1px; background: var(--border); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.cal-cell { min-height: 106px; padding: 6px; background: var(--surface); }
.cal-cell.is-outside { background: var(--surface-2); }
.cal-cell.is-outside .cal-date { opacity: .45; }
.cal-cell.is-today { box-shadow: inset 0 0 0 2px var(--primary); }
.cal-date { display: flex; align-items: center; justify-content: space-between; font-size: 12px; margin-bottom: 4px; }
.cal-more { font-size: 10px; color: var(--text-faint); }
.cal-items { display: flex; flex-direction: column; gap: 3px; }
.cal-item {
  position: relative; overflow: hidden;
  display: flex; align-items: center; gap: 5px;
  padding: 3px 6px 3px 9px; border-radius: 6px; text-decoration: none;
  background: var(--surface-2); border: 1px solid var(--border);
  font-size: 11px; color: var(--text); white-space: nowrap;
}
.cal-item:hover { border-color: var(--border-strong); }
.cal-item span:last-child { overflow: hidden; text-overflow: ellipsis; }
.cal-item .mono { font-size: 10px; color: var(--text-faint); }
.cal-item.is-milestone { padding-left: 6px; border-color: var(--amber); }
.cal-item.is-milestone svg { width: 12px; height: 12px; color: var(--amber); }
.cal-overflow { font-size: 10.5px; color: var(--text-faint); padding-left: 4px; }

@media (max-width: 900px) {
  /* Columns stack rather than scrolling sideways. */
  .board { flex-direction: column; overflow-x: visible; }
  .bcol { flex: 1 1 auto; width: 100%; max-height: none; }
  .bcol-body { max-height: 60vh; }
  .bcard { cursor: default; }

  .tl-labels { flex: 0 0 132px; }
  .tl-label-title { display: none; }

  /* The month grid becomes a list of the days that actually have something on
     them, so a phone gets an agenda instead of 42 cramped boxes. */
  .cal-head { display: none; }
  .cal-grid { display: block; background: none; border: 0; }
  .cal-cell { min-height: 0; margin-bottom: 6px; border: 1px solid var(--border); border-radius: 10px; }
  .cal-cell:not(:has(.cal-item)) { display: none; }
  .cal-cell.is-outside { display: none; }
  .cal-date { font-size: 13px; font-weight: 600; }
  .cal-item { white-space: normal; }
}

/* Board card move button: quiet until the card is hovered or the button is
   focused, so the card stays readable, but always present for touch and for
   keyboard users who never produce a hover. */
.cal { display: block; }
.bcard-move { opacity: 0; transition: opacity var(--transition); }
.bcard:hover .bcard-move, .bcard-move:focus-visible { opacity: 1; }
@media (hover: none) { .bcard-move { opacity: 1; } }

/* The content region is focused after every navigation so screen readers
   announce the new page. It is a container, not a control, and browsers treat
   that programmatic focus as keyboard focus, which drew the global focus ring
   around the entire page. Suppress it here only: every real control keeps its
   ring, so keyboard navigation is unaffected. */
#view:focus,
#view:focus-visible { outline: none; }

/* ------------------------------------------- 22. collaboration (phase 4) */

/* Comments */
.cmt-list { list-style: none; margin: 0 0 var(--space-4); padding: 0; display: grid; gap: var(--space-3); }
.cmt { padding: var(--space-3) var(--space-4); background: var(--surface-2);
       border: 1px solid var(--border); border-radius: var(--radius); }
.cmt-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 6px; }
.cmt-who { font-weight: 600; font-size: 13.5px; }
.cmt-when { font-size: 11px; color: var(--text-faint); }
.cmt-tools { margin-left: auto; display: flex; gap: 2px; opacity: 0; transition: opacity var(--transition); }
.cmt:hover .cmt-tools, .cmt-tools:focus-within { opacity: 1; }
@media (hover: none) { .cmt-tools { opacity: 1; } }
.cmt-body { font-size: 14px; line-height: 1.6; word-break: break-word; }
.cmt-body textarea { margin-bottom: var(--space-3); }
.mention { color: var(--primary); background: var(--primary-soft); padding: 1px 5px; border-radius: 5px; font-weight: 600; }

.cmt-composer { position: relative; }
.cmt-actions { display: flex; align-items: center; justify-content: space-between;
               gap: var(--space-3); margin-top: var(--space-3); }
.cmt-actions .cell-dim { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; }
.cmt-actions .cell-dim svg { width: 14px; height: 14px; }

.mention-menu {
  position: absolute; left: 0; right: 0; top: 100%; z-index: 30;
  margin-top: 4px; padding: 4px; max-height: 220px; overflow-y: auto;
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: var(--radius); box-shadow: var(--shadow-2);
}
.mention-option {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 7px 8px; font: inherit; font-size: 13.5px; text-align: left; color: var(--text);
  background: none; border: 0; border-radius: 8px; cursor: pointer;
}
.mention-option:hover, .mention-option:focus-visible { background: var(--surface-3); }

/* Attachments */
.att-list { list-style: none; margin: 0 0 var(--space-3); padding: 0; display: grid; gap: 6px; }
.att { display: flex; align-items: center; gap: 8px; padding: 7px 10px; font-size: 13px;
       background: var(--surface-2); border: 1px solid var(--border); border-radius: 10px; }
.att-link { display: flex; align-items: center; gap: 8px; min-width: 0; text-decoration: none; color: var(--text); }
.att-link svg { width: 16px; height: 16px; color: var(--text-faint); }
.att-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.att-link:hover .att-name { color: var(--primary); }
.att-meta { margin-left: auto; font-size: 11px; color: var(--text-faint); white-space: nowrap; }

.dropzone {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: var(--space-5) var(--space-4); text-align: center; font-size: 13px;
  color: var(--text-dim);
  border: 1px dashed var(--border-strong); border-radius: var(--radius);
  transition: border-color var(--transition), background var(--transition);
}
.dropzone svg { width: 22px; height: 22px; color: var(--text-faint); }
.dropzone.is-over { border-color: var(--primary); background: var(--primary-soft); }
.dropzone.is-busy { opacity: .6; pointer-events: none; }
.linkish { background: none; border: 0; padding: 0; font: inherit; color: var(--primary);
           cursor: pointer; text-decoration: underline; }

/* Time */
.time-summary { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: var(--space-3); }
.time-total { font-size: 20px; font-weight: 600; }
.time-list { list-style: none; margin: 0 0 var(--space-3); padding: 0; display: grid; gap: 4px; }
.time-list li { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
                padding: 6px 10px; font-size: 12.5px;
                background: var(--surface-2); border: 1px solid var(--border); border-radius: 9px; }
.time-amt { font-weight: 600; min-width: 54px; }
.time-who { color: var(--text); }
.time-note { color: var(--text-dim); }
.time-list li .btn { margin-left: auto; }
.time-form { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.time-form .input:nth-child(3), .time-form .btn { grid-column: 1 / -1; }

/* Activity */
.act-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.act-list li { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
               padding: 7px 0; font-size: 13px; border-bottom: 1px solid var(--border); }
.act-list li:last-child { border-bottom: none; }
.act-who { font-weight: 600; }
.act-what { color: var(--text-dim); overflow: hidden; text-overflow: ellipsis; }
.act-when { margin-left: auto; font-size: 11px; white-space: nowrap; }
.act-dot { width: 24px; height: 24px; border-radius: 50%; background: var(--surface-3); }

@media (max-width: 900px) {
  .time-form { grid-template-columns: 1fr; }
  .act-when { margin-left: 0; width: 100%; }
}

.build-stamp { margin: 6px 2px 0; font-family: var(--font-mono); font-size: 10px;
               letter-spacing: .06em; color: var(--text-faint); opacity: .7; }

.role-warn { margin-top: 8px; font-size: 12.5px; align-items: flex-start; }
.role-warn svg { flex: none; margin-top: 2px; }
.role-warn-slot:empty { display: none; }

/* A class that sets a display value beats the browser's own [hidden] rule, so
   anything marked hidden must be forced off regardless of what else styles it.
   This is what left a hidden warning banner sitting on screen. */
[hidden] { display: none !important; }

/* Activity counts on task rows and board cards. Quiet by default: they are a
   hint that something is there, not a headline. */
.tchips { display: inline-flex; align-items: center; gap: 8px; margin-left: 8px; vertical-align: middle; }
.tchip {
  display: inline-flex; align-items: center; gap: 3px;
  font-family: var(--font-mono); font-size: 11px; color: var(--text-faint);
}
.tchip svg { width: 13px; height: 13px; }
.task-row:hover .tchip, .bcard:hover .tchip { color: var(--text-dim); }

/* --------------------------------------------------- 23. automation (p5) */
.rule-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; }
.rule-row .input { flex: 1 1 130px; min-width: 0; width: auto; }
.rule-row .btn { flex: none; }
.rule-row-text { margin-top: -2px; }
.rule-block {
  padding: var(--space-3); margin-bottom: 8px;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 10px;
}
.rule-block .rule-row:last-child { margin-bottom: 0; }
tr.is-off { opacity: .55; }
tr.is-off strong { text-decoration: line-through; }

@media (max-width: 900px) {
  .rule-row .input { flex: 1 1 100%; }
}

/* ----------------------------------------------------- 24. reports (p6) */

.chart { width: 100%; height: auto; display: block; overflow: visible; }
.ch-grid { stroke: var(--border); stroke-width: 1; }
.ch-line { fill: none; stroke: var(--primary); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.ch-area { fill: var(--primary); opacity: .12; }
.ch-dot  { fill: var(--primary); stroke: var(--surface); stroke-width: 1.5; }
.ch-bar  { fill: var(--teal); }
.ch-bar:hover { fill: var(--primary); }
.ch-lab  { fill: var(--text-faint); font-family: var(--font-mono); font-size: 10px; }
.ch-lab-y { text-anchor: end; }
.ch-lab-x { text-anchor: middle; }

/* Proportional bar with its own key */
.sbar { display: flex; height: 14px; border-radius: var(--radius-pill); overflow: hidden;
        background: var(--surface-3); margin-bottom: var(--space-4); }
.sbar-seg { height: 100%; transition: filter var(--transition); }
.sbar-seg:hover { filter: brightness(1.15); }
.chart-key { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px 16px; }
.chart-key li { display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--text-dim); }
.chart-key i { width: 10px; height: 10px; border-radius: 3px; flex: none; }
.chart-key .mono { color: var(--text); font-weight: 600; }

/* Horizontal comparison bars */
.hbars { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.hbars li { display: grid; grid-template-columns: 190px minmax(80px, 1fr) 44px; gap: 10px;
            align-items: center; font-size: 13px; }
.hbar-label { display: flex; align-items: center; gap: 8px; min-width: 0; }
.hbar-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hbar-track { height: 10px; border-radius: var(--radius-pill); background: var(--surface-3); overflow: hidden; }
.hbar-fill { display: block; height: 100%; border-radius: var(--radius-pill); }
.hbar-value { text-align: right; font-weight: 600; }
.hbar-note { grid-column: 2 / -1; font-size: 11.5px; color: var(--text-dim); margin-top: -4px; }

/* Attention lists */
.att-rows { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.att-rows li { display: grid; grid-template-columns: 74px minmax(0, 2fr) 1fr 1fr 70px;
               gap: 10px; align-items: center; padding: 7px 0; font-size: 13px;
               border-bottom: 1px solid var(--border); }
.att-rows li:last-child { border-bottom: none; }
.att-rows .att-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.att-rows li .mono:last-child { text-align: right; }

@media (max-width: 900px) {
  .hbars li { grid-template-columns: minmax(0, 1fr) 40px; }
  .hbar-track { grid-column: 1 / -1; }
  .att-rows li { grid-template-columns: 70px minmax(0, 1fr) 62px; }
  .att-rows li .cell-dim:nth-child(3), .att-rows li .cell-dim:nth-child(4) { display: none; }
}

@media print {
  .sidebar, .topbar, .bottom-nav, .toolbar, .page-head .btn { display: none !important; }
  .content { padding: 0; }
  .two-col { grid-template-columns: 1fr 1fr; }
  .card { break-inside: avoid; border-color: #bbb; }
  .chart { max-height: 220px; }
}

/* A dialog that holds a table needs more room than a dialog that holds a form.
   Widening every modal would leave short forms stretched across the screen, so
   the wide frame is opt in. */
.modal-wide { max-width: 820px; }

/* Members dialog: name over email rather than side by side, and a role control
   that sizes to its content instead of claiming the whole column. That
   combination is what pushed the table past the dialog and produced a
   sideways scrollbar. */
.table-members { width: 100%; table-layout: auto; }
.table-members td, .table-members th { padding: 10px 12px; }
.member-cell { display: flex; align-items: center; gap: 10px; min-width: 0; }
.member-who { display: flex; flex-direction: column; min-width: 0; line-height: 1.35; }
.member-name { font-weight: 600; }
.member-email { font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.table-members .cell-select { width: auto; min-width: 130px; max-width: 100%; }
.table-members td:last-child { width: 44px; text-align: right; }

/* Safety net: nothing inside a dialog may scroll the dialog sideways. */
.modal-body { overflow-x: hidden; }
.modal-body .table-wrap { overflow-x: auto; }

@media (max-width: 640px) {
  .member-email { display: none; }
  .table-members .cell-select { min-width: 110px; }
}

/* Icon-only buttons get a text label once they are on their own in a stacked
   card, where there is room and no column header to explain them. */
.btn-label { display: none; }

@media (max-width: 900px) {
  .btn-label { display: inline; }

  /* A stacked cell with no data-label has nothing to put in the label column,
     so it spans the full width instead of leaving a blank gutter. */
  .table-stack td:not([data-label]) { grid-template-columns: minmax(0, 1fr); }
  .table-stack td:not([data-label])::before { display: none; }
}

/* ------------------------------------------------- 25. templates (p7) */
.btn-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: var(--space-3); }
.tpl-card { display: flex; flex-direction: column; }
.tpl-card .pcard-desc { flex: 1 1 auto; }

.toolbar-sep { width: 1px; height: 22px; background: var(--border); flex: none; margin: 0 2px; }
@media (max-width: 900px) { .toolbar-sep { display: none; } }

/* ================================================================
   Mind maps (phase M2)
   ================================================================ */
.map-toolbar {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  padding: 8px 10px; margin-bottom: 10px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow-1);
}
.map-toolbar .chip {
  padding: 3px 9px; border-radius: var(--radius-pill);
  background: var(--surface-3); font-size: 12.5px; font-weight: 600; gap: 5px;
}
.map-toolbar-gap { width: 6px; border-left: 1px solid var(--border); align-self: stretch; margin: 2px 4px; }
.map-zoom { min-width: 44px; text-align: center; font-size: 12.5px; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.map-save { margin-left: auto; display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; color: var(--text-dim); }
.map-save svg { width: 14px; height: 14px; color: var(--teal); }
.map-save.is-busy { color: var(--text-faint); }
.spinner-sm { width: 13px; height: 13px; border-width: 2px; }

.map-canvas-wrap {
  position: relative;
  height: calc(100vh - 210px);
  min-height: 380px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); overflow: hidden;
}
.map-svg { width: 100%; height: 100%; display: block; cursor: grab; touch-action: none; }
.map-svg:active { cursor: grabbing; }
.map-hint {
  position: absolute; left: 12px; bottom: 8px; margin: 0;
  font-size: 11.5px; color: var(--text-faint); pointer-events: none;
}

.map-edge { fill: none; stroke-width: 2; opacity: 0.55; }
.map-node { cursor: pointer; }
.map-node rect {
  fill: var(--surface); stroke-width: 1.6;
  filter: drop-shadow(0 1px 2px rgba(15, 23, 42, 0.12));
}
.map-node text {
  font: 600 14px Archivo, system-ui, sans-serif;
  fill: var(--text); text-anchor: middle; user-select: none; pointer-events: none;
}
.map-node.is-root rect { stroke: none; }
.map-node.is-root text { fill: #fff; font: 700 16px Archivo, system-ui, sans-serif; }
.map-node.is-selected rect { stroke-width: 3; }
.map-node.is-rel-from rect { stroke-dasharray: 5 4; stroke-width: 3; }
.map-node.is-dragging { opacity: 0.65; pointer-events: none; }
.map-node.is-drop-target rect { stroke-width: 3.5; stroke: var(--amber); }
.map-note-dot { fill: var(--amber); }

.map-chip { cursor: pointer; }
.map-chip circle { fill: var(--surface-2); stroke: var(--border-strong); stroke-width: 1.4; }
.map-chip text { font: 700 11px Archivo, sans-serif; fill: var(--text-dim); text-anchor: middle; user-select: none; }
.map-chip:hover circle { fill: var(--surface-3); }

.map-rel-line { fill: none; stroke: var(--violet); stroke-width: 1.8; stroke-dasharray: 6 5; opacity: 0.8; }
.map-rel-hit { fill: none; stroke: transparent; stroke-width: 14; cursor: pointer; }
.map-rel-label {
  font: 600 12px Archivo, sans-serif; fill: var(--violet);
  text-anchor: middle; paint-order: stroke; stroke: var(--surface); stroke-width: 4;
}

.map-inline-edit {
  position: absolute; z-index: 30; text-align: center;
  border: 2px solid var(--blue-500); border-radius: 8px;
  background: var(--surface); color: var(--text);
  font-family: Archivo, system-ui, sans-serif; font-weight: 600;
  padding: 0 8px; outline: none; box-shadow: var(--shadow-2);
}

.map-color-wrap { position: relative; }
.map-palette {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 40;
  display: flex; gap: 6px; align-items: center; padding: 8px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow-2);
}
.map-swatch {
  width: 22px; height: 22px; border-radius: 50%; border: 2px solid transparent; cursor: pointer;
}
.map-swatch[aria-pressed="true"] { border-color: var(--text); }

#mapRelBtn.is-on { background: var(--violet); border-color: var(--violet); color: #fff; }

.map-card-list { display: grid; gap: 8px; }
.map-card {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px; border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface); color: inherit; text-decoration: none;
  transition: border-color var(--transition), box-shadow var(--transition);
}
.map-card:hover { border-color: var(--blue-400); box-shadow: var(--shadow-1); }
.map-card-dot { width: 12px; height: 12px; border-radius: 50%; flex: none; }
.map-card-body { display: grid; gap: 2px; min-width: 0; flex: 1; }
.map-card-body strong { font-size: 14.5px; }
.map-card .chip {
  padding: 3px 9px; border-radius: var(--radius-pill);
  background: var(--surface-3); font-size: 12px; font-weight: 600; flex: none;
}
.map-card > svg { width: 16px; height: 16px; color: var(--text-faint); flex: none; }

.rule { border: 0; border-top: 1px solid var(--border); margin: 14px 0; }

@media (max-width: 760px) {
  .map-canvas-wrap { height: calc(100vh - 300px); }
  .map-hint { display: none; }
  .map-save { flex-basis: 100%; justify-content: flex-end; }
}

/* Mind maps: task bridge (phase M3) */
.map-node text.map-task-meta {
  font: 600 10.5px "IBM Plex Mono", ui-monospace, monospace;
  text-anchor: start;
}
.map-bar-track { opacity: 0.22; }
.map-bar-fill { opacity: 0.95; }
.map-bar-track.is-roll { fill: var(--text-faint); opacity: 0.28; }
.map-bar-fill.is-roll { fill: var(--text-dim); opacity: 0.7; }
.map-blocked-dot { fill: var(--rose); }
.map-node.is-dim { opacity: 0.22; }
.map-rel.is-dep .map-rel-line { stroke-dasharray: none; stroke-width: 2.2; }
.map-inbox-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 17px; height: 17px; padding: 0 4px; margin-left: 4px;
  border-radius: var(--radius-pill); background: var(--amber); color: #fff;
  font-size: 10.5px; font-weight: 700;
}
.map-filter { width: auto; padding: 4px 8px; font-size: 12.5px; height: 30px; }

/* Mind maps: styling, boundaries, floating, export (phase M4) */
.map-boundary {
  stroke-width: 1.4; stroke-dasharray: 7 5;
  fill-opacity: 0.05; stroke-opacity: 0.55;
  pointer-events: none;
}
.map-marker { pointer-events: none; }
.map-marker use { stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.map-style-pop { flex-direction: column; align-items: stretch; gap: 8px; min-width: 240px; }
.map-style-row { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.map-style-row .btn[aria-pressed="true"] { background: var(--primary); border-color: var(--primary); color: #fff; }

/* Two factor authentication (2.4.0) */
.twofa-qr { display: flex; justify-content: center; margin: 10px 0; }
.twofa-qr svg { width: 200px; height: 200px; border: 1px solid var(--border); border-radius: 8px; background: #fff; }
.twofa-codes { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px 18px; margin: 12px 0; padding: 12px; border: 1px dashed var(--border); border-radius: 8px; }
.btn-row { display: flex; gap: 8px; flex-wrap: wrap; }
