/* ste-pping — application chrome.
   Design language borrowed from SOURCES/prototype-gantt/shared/proto_chrome.css
   (same palette and type stack) but owned by the app: no dependency on the
   prototype files. */

:root {
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, "Helvetica Neue", sans-serif;
  --ink: #1c2333;
  --muted: #7a8194;
  --line: #e9ecf2;
  --bg: #fafbfd;
  --accent: #4453e8;
  --accent-soft: #eef0fd;
  --card: #ffffff;
  --danger: #c23b3b;
  --danger-soft: #fdeeee;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  min-height: 100%;
  font-family: var(--font);
  background: var(--bg);
  color: var(--ink);
}

/* ---------- Header ---------- */

.site_header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 24px;
  background: #fff;
  border-bottom: 1px solid var(--tl-line-app, var(--line));
}

.brand {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 650;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink);
  text-decoration: none;
}

/* the brand, then the tabs: the dashboard and one per project */
/* the version beside the name: the same line, quieter — small, muted,
   and not shouted in capitals like the name */
.brand_version {
  font-size: 11px; font-weight: 600; letter-spacing: .02em;
  text-transform: none; color: var(--muted); margin-left: -2px;
}
.brand_group { display: flex; align-items: center; gap: 16px; min-width: 0; }
.nav_tabs { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; min-width: 0; }
.nav_tab {
  display: inline-flex; align-items: center; gap: 7px;
  font: 650 12px var(--font); letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink); background: #fff;
  border: 1px solid var(--line); border-radius: 8px;
  padding: 5px 12px; text-decoration: none; white-space: nowrap;
}
.nav_tab:hover { border-color: var(--accent); color: var(--accent); }
/* "Projects:" before the project tabs: the tabs' own type, as a caption —
   no frame, the muted colour, a little air before the first tab */
.nav_label {
  font: 650 12px var(--font); letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted); white-space: nowrap; margin-left: 6px;
}
/* the page being looked at */
.nav_tab.is_active {
  background: var(--accent); border-color: var(--accent); color: #fff;
}

.brand_dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--accent);
  display: inline-block;
}

.header_right {
  display: flex;
  align-items: center;
  gap: 14px;
}

/* Language switcher: two buttons posting to set_language. */
.lang_switcher {
  display: inline-flex;
  margin: 0;
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
}

.lang_btn {
  font: 600 12px var(--font);
  color: var(--muted);
  background: #fff;
  border: none;
  padding: 5px 11px;
  cursor: pointer;
}

.lang_btn + .lang_btn { border-left: 1px solid var(--line); }

.lang_btn:hover { color: var(--accent); }

.lang_btn.is_active {
  color: var(--accent);
  background: var(--accent-soft);
}

.user_chip {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--muted);
}

.logout_form { margin: 0; display: inline-flex; }

.ghost_btn {
  font: 600 12px var(--font);
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 5px 12px;
  cursor: pointer;
}

.ghost_btn:hover {
  border-color: var(--accent);
  color: var(--accent);
}

/* On its own section, a header button reads as the tabs do: filled blue.
   `.user_chip` sets its own colour, so both selectors are spelled out. */
.ghost_btn.is_active,
.user_chip.is_active,
a.ghost_btn.nav_link.is_active,
a.user_chip.is_active {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

/* ---------- Page + cards ---------- */

.page {
  max-width: 720px;
  margin: 0 auto;
  padding: 32px 24px 48px;
}

.page.page_wide { max-width: 980px; }
.page.page_dash { max-width: 1280px; }

/* Rights and access: one row per account, two columns of checkboxes */
.access_table { width: 100%; border-collapse: collapse; margin: 4px 0 10px; }
.access_table th {
  text-align: left; padding: 6px 8px; border-bottom: 1px solid var(--line);
  color: var(--muted); font-size: 11.5px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .03em;
}
.access_table th:not(:first-child), .access_box { text-align: center; width: 22%; }
.access_table td { padding: 7px 8px; border-bottom: 1px solid #f1f3f7; font-size: 13.5px; }
.access_table tr:last-child td { border-bottom: none; }
.access_name { font-weight: 600; }
.access_note { color: var(--muted); font-weight: 500; font-size: 12px; }
/* what they do here, under their name */
.access_desc { display: block; color: var(--muted); font-weight: 500; font-size: 12.5px; }
.access_always { color: var(--accent); font-weight: 700; }
/* the group someone reaches the project through */
.access_via { display: block; color: var(--accent); font-weight: 500; font-size: 12px; }
/* the groups the project includes, above the list of people */
.access_groups { border: none; margin: 0 0 14px; padding: 0; }
.access_groups legend { padding: 0; font-weight: 650; font-size: 13.5px; }
.access_groups > div { display: flex; flex-wrap: wrap; gap: 6px 18px; margin-top: 6px; }
.access_groups label { display: flex; align-items: center; gap: 6px; font-size: 13.5px; }
/* out of reach until the project access next to it is ticked */
.access_table input:disabled { opacity: .3; cursor: not-allowed; }

/* the address, cut short: readable enough to tell two apart, click to copy */
.feed_url {
  display: block; margin-top: 3px; cursor: pointer;
  font: 12.5px ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--muted); word-break: break-all;
}
.feed_url:hover { color: var(--accent); }
.feed_url.is_copied { color: #1d7a4f; font-family: var(--font); }

/* what a calendar publishes, as neutral chips under its name */
.kind_tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
.kind_tag_plain { color: var(--muted); background: var(--accent-soft); }
/* the projects it draws from: outlined, apart from the kinds */
.project_tag { color: var(--ink); background: #fff; border: 1px solid var(--line); }

/* a button that is only a glyph: the copy icon, and its "done" tick */
.icon_btn { display: inline-flex; align-items: center; justify-content: center; padding: 5px 8px; }
.icon_btn .icon_check { display: none; }
.icon_btn.is_copied { color: #1d7a4f; border-color: #1d7a4f; }
.icon_btn.is_copied .icon_copy { display: none; }
.icon_btn.is_copied .icon_check { display: block; }

/* ---------- contacts: the team, as a table ---------- */
/* a narrow window scrolls the table sideways rather than squeezing it */
.contact_scroll { overflow-x: auto; margin: 0 -4px; }
.contact_table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.contact_table th {
  text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--line);
  color: var(--muted); font-size: 11.5px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .03em; white-space: nowrap;
}
.contact_table td { padding: 9px 10px; border-bottom: 1px solid #f1f3f7; vertical-align: middle; }
.contact_table tr:last-child td { border-bottom: none; }
.contact_name { font-weight: 600; white-space: nowrap; }
.contact_reach { white-space: nowrap; }
.contact_reach a { color: var(--ink); text-decoration: none; }
.contact_reach a:hover { color: var(--accent); text-decoration: underline; }
/* the copy button of a table cell: a glyph, no frame, beside what it copies */
.copy_mini {
  padding: 2px 4px; margin-left: 2px; vertical-align: middle;
  border: none; background: none; color: var(--muted); cursor: pointer; border-radius: 6px;
}
.copy_mini:hover { color: var(--accent); background: var(--accent-soft); }
.copy_mini.is_copied { color: #1d7a4f; }

/* ---------- contact lists: the sheet ---------- */
/* To read, a list is the team's table (.contact_table) whose headers sort;
   one line a contact, an address may wrap.  Edit turns it into .sheet. */
.sheet_read th { padding: 0; }
.sheet_read .sheet_sort { padding: 8px 10px; }
.sheet_read td { white-space: pre; }
.sheet_read td[data-field="address"] { white-space: pre-line; }
.sheet_bar { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
.sheet_filter {
  flex: 0 1 280px; font: 13px var(--font); color: var(--ink);
  background: #fff; border: 1px solid var(--line); border-radius: 8px; padding: 6px 10px;
}
.sheet_filter:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.sheet_count { color: var(--muted); font-size: 12.5px; }
.sheet_scroll { overflow-x: auto; margin: 0 -4px; }
/* never narrower than its nine columns can bear: a narrow window scrolls it sideways */
.sheet { width: 100%; min-width: 1080px; border-collapse: collapse; font-size: 13px; table-layout: fixed; }
.sheet th { padding: 0; border-bottom: 1px solid var(--line); text-align: left; white-space: nowrap; overflow: hidden; }
.sheet_sort {
  width: 100%; text-align: left; padding: 8px 8px; border: none; background: none; cursor: pointer;
  color: var(--muted); font: 600 11.5px var(--font); text-transform: uppercase; letter-spacing: .03em;
}
.sheet_sort:hover { color: var(--accent); }
/* A cell is 32px tall for one line, grows with its line breaks, and keeps
   its column's width, open or not: the editor takes exactly the room the
   text had. */
.sheet td {
  position: relative; height: 32px; box-sizing: border-box; padding: 6px 8px; line-height: 18px;
  border-bottom: 1px solid #f1f3f7; border-right: 1px solid #f1f3f7;
  vertical-align: top; overflow: hidden; white-space: pre; text-overflow: ellipsis; outline: none;
}
.sheet td:first-child { border-left: 1px solid #f1f3f7; }
.sheet td a { color: var(--ink); text-decoration: none; }
.sheet td a:hover { color: var(--accent); text-decoration: underline; }
.sheet.can_write td[data-field] { cursor: cell; }
/* The cell the keyboard is on, and the one being written in: a frame drawn
   with an outline, which sits on top of everything — an inset shadow was
   hidden left and right by the neighbours' borders, and by the input. */
.sheet td.sheet_sel, .sheet td.sheet_editing { outline: 2px solid var(--accent); outline-offset: -2px; z-index: 2; }
.sheet_input {
  display: block; width: 100%; height: 18px; box-sizing: border-box; margin: 0;
  font: 13px var(--font); line-height: 18px; color: var(--ink); background: #fff; border: none; padding: 0; outline: none;
  resize: none; overflow: hidden; white-space: pre;
}
.sheet_input[type="date"] { padding-right: 4px; }
/* changed under one's hand, or refused as somebody else was here first: orange */
.sheet td.sheet_conflict { outline: 2px solid #e08a00; outline-offset: -2px; background: #fff7e6; z-index: 2; }
/* refused by the server (an e-mail that is not one…): red, the draft still in it */
.sheet td.sheet_refused { outline: 2px solid #c23b3b; outline-offset: -2px; background: #fdeaea; z-index: 2; }
/* somebody else's cursor: their colour round the cell, their name in the corner */
.sheet td.sheet_taken { outline: 2px solid var(--who); outline-offset: -2px; z-index: 1; }
.sheet_who {
  position: absolute; right: 0; top: 0; padding: 0 5px; border-radius: 0 0 0 5px;
  font: 600 9.5px var(--font); color: #fff; background: var(--who); pointer-events: none;
}
.sheet_hint { color: var(--muted); font-style: italic; }
.sheet_acts { text-align: right; white-space: nowrap; padding: 0 4px !important; line-height: 30px; }
.sheet_del, .sheet_grip {
  border: none; background: none; color: var(--muted); cursor: pointer; padding: 2px 5px;
  font: 600 12px var(--font); border-radius: 6px;
}
.sheet_del:hover { color: var(--danger, #c23b3b); background: #fdeaea; }
.sheet_grip { cursor: grab; letter-spacing: -3px; }
.sheet tr.sheet_over td { border-top: 2px solid var(--accent); }
.sheet tr.sheet_new td { background: #fbfbfd; }
/* who else is here, and the toast and card the sheet borrows from the timeline */
.watchers { display: inline-flex; align-items: center; margin-right: 6px; }
.watcher {
  width: 24px; height: 24px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font: 650 11px var(--font); color: #fff; background: var(--accent);
  border: 2px solid #fff; box-sizing: border-box; margin-left: -8px;
}
.watcher:first-child { margin-left: 0; }
.tl_toast {
  position: fixed; left: 50%; top: 12px; transform: translateX(-50%); max-width: 70vw;
  background: #2a3040; color: #fff; font-size: 13px; padding: 10px 16px; border-radius: 10px;
  box-shadow: 0 6px 20px rgba(28, 35, 51, .25); z-index: 70;
}
.tl_tip {
  position: fixed; z-index: 60; pointer-events: none;
  background: #2a3040; color: #fff; font-size: 12px; line-height: 1.35;
  padding: 6px 9px; border-radius: 7px; box-shadow: 0 4px 14px rgba(28, 35, 51, .28);
}
/* the access rules of a list: three tables of radio buttons */
.rules_title { margin: 14px 0 4px; font-size: 12px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.rules_table th:not(:first-child), .rules_table .access_box { width: 16%; }

/* "Edit": a disclosure that opens the row's own form, full width */
.feed_edit { flex-basis: 100%; }
.feed_edit summary {
  display: inline-block; cursor: pointer; color: var(--muted);
  font-size: 12.5px; font-weight: 600; padding: 4px 0;
}
.feed_edit summary:hover { color: var(--accent); }
.feed_edit[open] summary { margin-bottom: 6px; }

/* the "what it publishes" checkboxes of a calendar feed, side by side */
.feed_form { margin-top: 6px; }
.feed_form .field > div { display: flex; flex-wrap: wrap; gap: 4px 18px; }
.feed_form .field > div label {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 13.5px; font-weight: 500; color: var(--ink);
}
/* "all my projects" ticked: the project list under it has no say */
.feed_form .field.is_off { opacity: .45; }

/* The cards of what is on my plate: one column, or two at the touch of the
   button in the strip (meetings + tasks left, deadlines + milestones right).
   Column flow with two rows is what fills a column before moving on. */
.plate { display: grid; gap: 18px; align-items: start; }
.plate .card + .card { margin-top: 0; }
@media (min-width: 1040px) {
  .plate.is_split {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-rows: auto auto;
    grid-auto-flow: column;
  }
}
/* the switch itself: a square split down the middle, blue once it is on */
.split_btn { margin-left: auto; display: inline-flex; align-items: center; padding: 6px 9px; }
.split_btn.is_active {
  background: var(--accent); border-color: var(--accent); color: #fff;
}

/* "experimental": a format that works but has not earned full trust yet */
.pill_beta {
  display: inline-block; margin-left: 8px; vertical-align: 2px;
  font: 600 10.5px var(--font); letter-spacing: .04em; text-transform: uppercase;
  color: #8a6100; background: #fdf3dc; border-radius: 999px; padding: 2px 8px;
}

/* Geneva calendar: one slim strip across the top, its facts side by side */
.cal_strip {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 10px 30px;
  padding: 14px 20px; margin-bottom: 18px; font-size: 13.5px;
}
.cal_fact { display: inline-flex; align-items: baseline; gap: 8px; }
.cal_label {
  color: var(--muted); font-size: 11.5px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .03em;
}
.cal_note { color: var(--muted); }

/* The contacts, top right of the dashboard: the team, then each list, as
   the tabs the contact pages show — the header keeps the projects only.
   Many lists wrap onto a second row rather than push. */
.contact_tabs { flex-wrap: wrap; justify-content: flex-end; }
/* on a narrow screen they go under the greeting, still to the right,
   instead of being cut off */
.dash_head { flex-wrap: wrap; row-gap: 10px; }

.page_head {
  display: flex;
  align-items: baseline;
  gap: 14px;
  margin-bottom: 20px;
}

.page_head h1 {
  margin: 0;
  font-size: 22px;
  font-weight: 650;
  letter-spacing: -0.01em;
}

.role_badge {
  font-size: 12px;
  font-weight: 600;
  color: var(--accent);
  background: var(--accent-soft);
  border-radius: 999px;
  padding: 3px 10px;
}

.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 22px 24px;
}

.card h2 {
  margin: 0 0 14px;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--ink);
}

.card + .card { margin-top: 18px; }

.muted { color: var(--muted); }

/* Countdown to day zero, e.g. J-33 / J0 / J+2. */

.empty_state {
  margin: 0;
  font-size: 13.5px;
  color: var(--muted);
}

/* Definition rows in the proof-of-life card. */

.fact_list { margin: 0; }

.fact_row {
  display: flex;
  justify-content: space-between;
  gap: 18px;
  padding: 9px 0;
  border-bottom: 1px solid var(--line);
  font-size: 14px;
}

.fact_row:last-child { border-bottom: none; }

.fact_row dt { color: var(--muted); }

.fact_row dd { margin: 0; font-weight: 600; text-align: right; }

.tag_yes { color: #1d7a4f; }

.tag_no { color: var(--danger); }

/* ---------- Auth card ---------- */

.auth_card {
  max-width: 380px;
  margin: 8vh auto 0;
}

.auth_card h1 {
  margin: 0 0 6px;
  font-size: 20px;
  font-weight: 650;
  letter-spacing: -0.01em;
}

.auth_card .muted {
  margin: 0 0 18px;
  font-size: 13.5px;
}

.field { margin-bottom: 14px; }

.field label {
  display: block;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--muted);
  margin-bottom: 5px;
}

.field input {
  width: 100%;
  font: 400 14px var(--font);
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 9px 11px;
}

.field input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.primary_btn {
  width: 100%;
  font: 600 14px var(--font);
  color: #fff;
  background: var(--accent);
  border: none;
  border-radius: 8px;
  padding: 10px 14px;
  cursor: pointer;
  margin-top: 4px;
}

.primary_btn:hover { background: #3543c9; }

.form_errors {
  background: var(--danger-soft);
  border: 1px solid #f3cfcf;
  border-radius: 8px;
  padding: 10px 12px;
  margin-bottom: 14px;
}

.form_errors p {
  margin: 0;
  font-size: 13px;
  color: var(--danger);
}

/* ---------- Pages: project create + settings (étape 6, append-only) ---- */

/* Card header row: title + action button side by side. */

.card_head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}

.card_head h2 { margin: 0; }

/* Generic buttons (the existing .primary_btn is full-width for auth). */

.btn {
  display: inline-block;
  font: 600 13px var(--font);
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 8px 14px;
  cursor: pointer;
  text-decoration: none;
}

.btn:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.btn_primary {
  color: #fff;
  background: var(--accent);
  border-color: var(--accent);
}

.btn_primary:hover {
  color: #fff;
  background: #3543c9;
  border-color: #3543c9;
}

.btn_small {
  font-size: 12px;
  padding: 5px 11px;
}

.btn_danger {
  color: var(--danger);
  background: var(--danger-soft);
  border-color: #f3cfcf;
}

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

/* The settings button on the home project rows is a plain .btn.btn_small
   (the old tiny .gear_link was too easy to miss). */

/* The red bar administrators see while the site is closed for maintenance. */
.maint_bar {
  display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 6px 16px;
  padding: 8px 16px; background: var(--danger, #c23b3b); color: #fff;
  font: 600 13px var(--font);
}
.maint_bar form { margin: 0; }
.maint_bar .btn { padding: 4px 10px; }
/* the "back soon" page: the sign-in card, with the notice in it */
.maint_card .muted { font-size: 15px; color: var(--ink); white-space: pre-line; }

/* Flash messages (django.contrib.messages). */

.messages {
  list-style: none;
  margin: 0 0 18px;
  padding: 0;
}

.message {
  font-size: 13.5px;
  font-weight: 600;
  border-radius: 8px;
  padding: 10px 14px;
  margin-bottom: 8px;
  color: var(--accent);
  background: var(--accent-soft);
  border: 1px solid #d9defb;
}

.message.success {
  color: #1d7a4f;
  background: #eaf7f0;
  border-color: #cfe9db;
}

.message.error, .message.warning {
  color: var(--danger);
  background: var(--danger-soft);
  border-color: #f3cfcf;
}

/* Security tab: the two lists of what the brute-force guard is holding —
   accounts and addresses — share one row shape. */
.lock_list { list-style: none; margin: 10px 0 0; padding: 0; }

.lock_row {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 11px 2px;
  border-bottom: 1px solid #f1f3f7;
}
.lock_row:last-child { border-bottom: none; }
.lock_row form { margin: 0; }

.lock_id { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.lock_key {
  display: flex; align-items: center; gap: 8px;
  font-size: 13.5px; font-weight: 600; color: var(--ink);
}
/* an address is read digit by digit, so it gets a fixed pitch */
.lock_key.is_address { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.lock_name { font-weight: 400; color: var(--muted); }
.lock_sub { font-size: 12px; color: var(--muted); }
.lock_note { font-size: 12px; color: var(--muted); white-space: nowrap; }

/* a username nobody owns: someone is guessing, not locked out */
.badge_probe {
  font-size: 11px; font-weight: 600;
  color: #6a7186; background: #f1f3f7; border-radius: 8px; padding: 1px 7px;
}

.empty_note { font-size: 13px; color: var(--muted); margin: 10px 0 0; }

/* A password field one can look at: the button sits inside the input's
   right edge, and the input keeps clear of it. */
.password_field { position: relative; }
.password_field input { padding-right: 40px; }

.password_reveal {
  position: absolute; top: 0; right: 0;
  display: flex; align-items: center; justify-content: center;
  width: 38px; height: 100%;
  padding: 0; border: none; background: none;
  color: var(--muted); cursor: pointer; border-radius: 0 8px 8px 0;
}
.password_reveal:hover { color: var(--ink); }
.password_reveal:focus-visible {
  outline: none; color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
/* one icon per state: an open eye offers to show, a struck one to hide */
.password_reveal .eye_off { display: none; }
.password_reveal[aria-pressed="true"] .eye_on { display: none; }
.password_reveal[aria-pressed="true"] .eye_off { display: block; }
.password_reveal[aria-pressed="true"] { color: var(--accent); }

/* Form extensions (the auth card already styles .field input). */

.field textarea,
.field select {
  width: 100%;
  font: 400 14px var(--font);
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 9px 11px;
}

.field textarea:focus,
.field select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.field input[type="color"] {
  width: 52px;
  height: 34px;
  padding: 2px;
  cursor: pointer;
}

.field input[type="checkbox"] {
  width: auto;
  accent-color: var(--accent);
}

.field_row {
  display: flex;
  gap: 14px;
}

.field_row .field { flex: 1; }

.field_error {
  margin: 5px 0 0;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--danger);
}

.form_hint {
  margin: 0 0 6px;
  font-size: 12px;
  color: var(--muted);
}

/* Members checkbox list (CheckboxSelectMultiple output). */

.member_choices div {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 18px;
}

.member_choices label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--ink);
  margin: 0;
}

/* a row of buttons pushed against the right edge of its card */
.page_actions.actions_right { justify-content: flex-end; }
/* an action sitting on the title line, at the far right */
.head_action { margin-left: auto; }
.head_tools { margin-left: auto; display: flex; align-items: center; gap: 12px; }

/* Tabs inside a page (administration: accounts / backup).  Same shape as the
   header tabs; `align-self` keeps them centred in a page_head that aligns its
   children on the text baseline. */
.section_tabs { display: flex; align-items: center; gap: 8px; align-self: center; }

/* the way back, an arrow on its own */
.back_btn { display: inline-flex; align-items: center; padding: 6px 10px; }

.page_actions {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 6px;
}

/* Missions management rows. */

.mission_list {
  list-style: none;
  margin: 0 0 16px;
  padding: 0;
}

.mission_row {
  display: flex;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: 10px;
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
}

.mission_row:last-child { border-bottom: none; }

.inline_form {
  display: flex;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: 10px;
  flex: 1;
  margin: 0;
}

/* The name input is the dominant field: it grows with the row and never
   shrinks below a comfortable typing width. */

.inline_form .field {
  margin-bottom: 0;
  flex: 1 1 280px;
  min-width: 280px;
}

.inline_form .field_color,
.inline_form .field_position {
  flex: 0 0 auto;
  min-width: 0;
}

/* Keep the auto-color hint from squeezing the name input: narrow enough
   that name + color + button share one line inside the 720px page. */

.inline_form .form_hint { max-width: 170px; }

/* Must out-rank the generic `.field input { width: 100% }` rule, otherwise
   the number input falls back to its ~180px intrinsic width and squeezes
   the name input of the row. */

.field input.position_input { width: 72px; }

.checkbox_label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--muted);
  margin-bottom: 5px;
}

.delete_form { margin: 0; }

.add_mission_form {
  padding-top: 14px;
  border-top: 1px solid var(--line);
}

/* Danger zone card. */

.danger_zone { border-color: #f3cfcf; }

.danger_zone h2 { color: var(--danger); }

.danger_text {
  margin: 0 0 12px;
  font-size: 13.5px;
  color: var(--muted);
}

/* ---------- Users management ---------- */

.users_card { padding: 6px 18px; }

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

.user_row {
  display: grid;
  grid-template-columns: auto 1fr auto minmax(150px, auto) auto;
  align-items: center;
  gap: 16px;
  padding: 13px 2px;
  border-bottom: 1px solid #f1f3f7;
}

.user_row:last-child { border-bottom: none; }
/* a group's row has no role pill: one column fewer */
.user_row.group_row { grid-template-columns: auto 1fr minmax(150px, auto) auto; }
/* "＋ Add a group": under the card's title, above the list it adds to */
.card_add { margin: -4px 0 10px; }
/* the members and projects listed on a group's card */
.group_links { margin: 0; padding-left: 18px; line-height: 1.9; }

.user_avatar {
  width: 38px; height: 38px; border-radius: 50%;
  background: #eceefc; color: #4453e8;
  display: flex; align-items: center; justify-content: center;
  font-size: 16px; font-weight: 700;
}

.user_id { min-width: 0; }

.user_name { font-weight: 600; }

.user_desc { color: var(--muted); font-weight: 500; font-size: 13px; }

.user_sub {
  display: block; color: var(--muted); font-size: 13px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.page_head .role_pill { align-self: center; }

.role_pill {
  font-size: 12px; font-weight: 600;
  border-radius: 999px; padding: 3px 11px; white-space: nowrap;
}

.role_admin { background: #eceefc; color: #3a48c9; }

.role_user  { background: #e7f5ee; color: #1d7a4f; }

.role_guest { background: #f1f3f7; color: #5d6474; }

.user_meta { color: var(--muted); font-size: 12.5px; text-align: right; line-height: 1.45; }

.user_meta span { display: block; white-space: nowrap; }

.user_row.inactive .user_avatar,
.user_row.inactive .user_id,
.user_row.inactive .role_pill,
.user_row.inactive .user_meta { opacity: .5; }

.badge_off {
  display: inline-block; font-size: 11px; font-weight: 600;
  color: #b3261e; background: #fdecea; border-radius: 8px; padding: 1px 7px;
  margin-left: 6px;
}

/* held by django-axes after failed logins — amber, because it wears off,
   unlike the red "inactive" an administrator chose */
.badge_locked {
  display: inline-block; font-size: 11px; font-weight: 600;
  color: #9a5b00; background: #fff3e0; border-radius: 8px; padding: 1px 7px;
  margin-left: 6px;
  text-decoration: none; /* it links to the Security tab, which manages it */
}
a.badge_locked:hover { background: #ffe8c2; }

/* last cell of a user row: the unblock form rides beside the edit link */
.user_actions { display: flex; align-items: center; gap: 8px; }
.user_actions form { margin: 0; }

@media (max-width: 640px) {
  .user_row { grid-template-columns: auto 1fr auto; }
  .user_meta { display: none; }
}

a.ghost_btn.nav_link { text-decoration: none; display: inline-flex; align-items: center; }

a.user_chip { text-decoration: none; }

a.user_chip:hover { text-decoration: none; }

/* ---------- the settings wheel (timeline header) ---------- */

/* The ⚙ glyph, blown up to the height of the text beside it: its ink fills
   only the upper part of the em box, so the box is squeezed AND the glyph is
   lifted by the gap measurement showed between ink centre and box centre. */
.gear_btn {
  display: inline-block; font-size: 46px; line-height: 27px; height: 27px;
  position: relative; top: -3px;
  color: var(--accent); text-decoration: none;
}
.gear_btn:hover { filter: brightness(1.15); }

/* ---------- "My tasks" card (home) ---------- */
.task_list { list-style: none; margin: 0; padding: 0; }
.task_row {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 2px; border-bottom: 1px solid #f1f3f7;
}
.task_row:last-child { border-bottom: none; }
.task_dot { width: 12px; height: 12px; border-radius: 50%; flex: none; }
/* per-kind glyph (milestone / deadline / meeting), same shapes as the timeline */
.kind_icon { flex: none; display: block; width: 18px; height: 18px; }
.task_link { flex: 1; min-width: 0; text-decoration: none; color: inherit; }
.task_link:hover .task_name { text-decoration: underline; }
/* the name is what matters: it wraps rather than being cut, and the chips
   drop under it when the column gets narrow */
.task_head { display: flex; align-items: baseline; gap: 4px 8px; min-width: 0; flex-wrap: wrap; }
.task_name { font-weight: 600; min-width: 0; }
/* Where the item lives: its project, then its mission in the mission's
   colour — said, not clickable: the row itself is the door. */
.kind_tag {
  flex: none; font-size: 11px; font-weight: 650; line-height: 1.6;
  padding: 0 8px; border-radius: 999px; white-space: nowrap;
}
.task_project {
  display: block; color: var(--muted); font-size: 12.5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* dates and figures: right-aligned, capped so a long date cannot squeeze
   the name out of its own row */
.task_side { display: flex; flex-direction: column; align-items: flex-end; gap: 1px;
  max-width: 47%; text-align: right; }
.task_due { color: var(--muted); font-size: 13px; }
/* second line: progress for a task, countdown for a dated point */
.task_meta { color: var(--muted); font-size: 12px; opacity: .85; }
.task_due.overdue { color: #b3261e; font-weight: 600; }
/* The post-its of a row: "3", or "3 (1)" when some are new to this reader.
   A door of its own — it opens the notes where the item lives. */
.task_notes {
  display: inline-flex; align-items: center; gap: 4px;
  margin-top: 2px; padding: 1px 7px 1px 5px; border-radius: 999px;
  font: 650 11.5px var(--font); color: var(--muted);
  background: #f4f5f8; text-decoration: none;
}
.task_notes:hover { color: var(--ink); }
.task_notes.has_new { color: var(--ink); background: var(--tl-note-paper, #fdf6d3); }
.note_glyph { flex: none; display: block; }

/* ---------- Project history ---------- */
.hist_list { list-style: none; margin: 0; padding: 0; }
.hist_row {
  display: grid; grid-template-columns: 128px 92px 1fr;
  gap: 14px; align-items: baseline;
  padding: 9px 2px; border-bottom: 1px solid #f1f3f7;
  font-size: 13.5px;
}
.hist_row:last-child { border-bottom: none; }
.hist_when { color: var(--muted); font-size: 12.5px; white-space: nowrap; }
.hist_actor { font-weight: 600; overflow: hidden; text-overflow: ellipsis; }
.act_badge {
  display: inline-block; font-size: 11.5px; font-weight: 700;
  border-radius: 8px; padding: 1px 8px; margin-right: 4px;
}
.act_0 { background: #eaf7f0; color: #1d7a4f; }  /* created */
.act_1 { background: #eef1f8; color: #4a5266; }  /* modified */
.act_2 { background: #fdecea; color: #b3261e; }  /* deleted */
.hist_kind { color: var(--muted); }
.hist_name { font-weight: 600; }
.hist_changes { display: block; color: var(--muted); font-size: 12.5px; margin-top: 2px; }
.hist_change { display: inline-block; margin-right: 14px; }
@media (max-width: 640px) { .hist_row { grid-template-columns: 1fr; gap: 2px; } }

/* ---------- Project export page ---------- */
.export_list { list-style: none; margin: 0; padding: 0; }
.export_row {
  display: flex; align-items: center; gap: 18px;
  padding: 14px 2px; border-bottom: 1px solid #f1f3f7;
}
.export_row:last-child { border-bottom: none; }
.export_text { flex: 1; min-width: 0; }
.export_title { display: block; font-weight: 650; }
.export_desc { display: block; color: var(--muted); font-size: 13px; margin-top: 2px; }

/* ---------- Share links & calendar feeds ---------- */
.share_new {
  background: var(--accent-soft); border: 1px solid #d9defb; border-radius: 10px;
  padding: 12px 14px; margin-bottom: 14px;
}
.share_new_title { margin: 0 0 8px; font-weight: 600; font-size: 13.5px; }
.share_url_row { display: flex; gap: 8px; }
.share_url {
  flex: 1; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px;
  padding: 7px 9px; border: 1px solid #d9defb; border-radius: 8px; background: #fff;
}
.share_list { list-style: none; margin: 0 0 14px; padding: 0; }
.share_row { display: flex; align-items: center; flex-wrap: wrap; gap: 12px; padding: 9px 2px; border-bottom: 1px solid #f1f3f7; }
.share_row:last-child { border-bottom: none; }
.share_main { flex: 1; min-width: 0; }
.share_label { font-weight: 600; display: block; }
.share_meta { display: block; color: var(--muted); font-size: 12.5px; }
.share_status {
  font-size: 12px; font-weight: 600; border-radius: 999px; padding: 2px 9px;
  background: #eaf7f0; color: #1d7a4f; white-space: nowrap;
}
.status_revoked .share_status, .status_expired .share_status { background: #f1f3f7; color: #5d6474; }
.status_revoked .share_main, .status_expired .share_main { opacity: .55; }
.share_form { margin-top: 6px; }
.share_form ul { list-style: none; margin: 0; padding: 0; }
.share_form ul li { margin: 4px 0; }


/* ---- Design page: the shadow and line settings ---------------------- */
.design_grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 22px; }
.design_group h3 {
  margin: 0 0 10px; font-size: 11.5px; font-weight: 700; color: var(--muted);
  text-transform: uppercase; letter-spacing: .04em;
}
.design_row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 5px 0; font-size: 13px;
}
.design_row input[type="color"] {
  width: 46px; height: 26px; padding: 2px; cursor: pointer;
  background: #fff; border: 1px solid var(--line); border-radius: 6px;
}
.design_row input.num_input {
  width: 72px; text-align: right;
  font: 13px var(--font); color: var(--ink);
  background: #fff; border: 1px solid var(--line); border-radius: 6px; padding: 4px 7px;
}
.design_row .field_error { flex: 1 0 100%; color: var(--danger); font-size: 12px; font-style: normal; }

/* A corner of the timeline, built from the same custom properties as the
   real one, so a change is seen without leaving the page. */
.design_preview {
  position: relative;
  display: flex; height: 148px; overflow: hidden;
  background: #fff; border: 1px solid var(--tl-line-frame, var(--line)); border-radius: 8px;
}
/* the inspector, lying on that corner of chart: the opacity and the blur
   under it are the ones being set right above */
.dp_panel {
  position: absolute; top: 0; right: 0; bottom: 0; width: 88px;
  display: flex; flex-direction: column; gap: 7px;
  padding: 12px 10px;
  background: var(--tl-panel-bg, #fff);
  backdrop-filter: var(--tl-panel-blur, none);
  -webkit-backdrop-filter: var(--tl-panel-blur, none);
  border-left: 1px solid var(--tl-line-frame, var(--line));
  box-shadow: var(--tl-shadow-drawer, -8px 0 28px rgba(28, 35, 51, .10));
}
.dp_panel i { display: block; height: 7px; border-radius: 3px; background: var(--line); }
.dp_panel i.dp_title { width: 62%; height: 9px; background: var(--muted); }
.dp_panel i.dp_box { height: 18px; background: #fff; border: 1px solid var(--line); }
.dp_left {
  position: relative; flex: 0 0 92px;
  border-right: 1px solid var(--tl-line-split, var(--line));
}
.dp_head {
  height: 30px; display: flex; align-items: center; padding: 0 8px;
  font-size: 10px; font-weight: 700; color: var(--muted); text-transform: uppercase;
  border-bottom: 1px solid var(--tl-line-scale, #e2e6ee);
  box-shadow: var(--tl-shadow-band, 0 10px 24px -8px rgba(28, 35, 51, .22));
}
.dp_row { height: 26px; border-bottom: 1px solid var(--tl-line-list-row, #f1f3f7); }
.dp_shade {
  position: absolute; top: 30px; bottom: 0; right: calc(-1 * var(--tl-shade-width, 28px));
  width: var(--tl-shade-width, 28px);
  background: linear-gradient(to right, var(--tl-shade-color, rgba(28, 35, 51, .20)), transparent);
}
.dp_chart { flex: 1; min-width: 0; }
.dp_band {
  display: flex; height: 30px;
  border-bottom: 1px solid var(--tl-line-scale, #e2e6ee);
  box-shadow: var(--tl-shadow-band, 0 10px 24px -8px rgba(28, 35, 51, .22));
}
.dp_band span { flex: 1; border-right: 1px solid var(--tl-line-month, #e9ecf2); }
.dp_rows { position: relative; }
.dp_rows i { display: block; height: 26px; border-bottom: 1px solid var(--tl-line-chart-row, #f1f3f7); }
.dp_weekend {
  position: absolute; top: 0; bottom: 0; right: 14%; width: 16%;
  background: var(--tl-weekend-fill, rgba(28, 35, 51, .04));
}
.dp_rows::after {
  content: ""; position: absolute; inset: 0;
  background: repeating-linear-gradient(to right,
    var(--tl-line-day, #f8f9fc) 0 1px, transparent 1px 22px);
}
