/* ClubDesk console — design system.
 *
 * Revision 4 — "monday", light and dark: the look the client asked for
 * (docs/Design-monday-style.md), now as a proper theme system — every colour
 * is a token on :root with an html.dark override, a toggle in the sidebar
 * foot, and the OS setting as the default. Poppins throughout; status as
 * fully-rounded pills with white text; cards and inputs 8px, buttons, tabs
 * and pills fully rounded. The rules are in CLAUDE.md.
 * Still finance software, read more than admired, so the original rules stand:
 *
 *   - The ground is quiet. Colour means something or it isn't there.
 *   - Figures are tabular and right-aligned, always, so columns compare by eye.
 *   - Status is a word as well as a colour, never colour alone.
 *   - Density over decoration: more rows visible beats more whitespace.
 *
 * The public pages a customer sees keep the club's navy and gold; this file
 * is the staff console only.
 */

@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap");

/* ---------- theme tokens ----------
   One set of names, two values each. Everything below reads var(--…); nothing
   in a component names a hex. Light lives on :root; dark is html.dark, which
   the toggle in the sidebar foot sets and the inline script in console.html
   applies before the first paint (localStorage 'theme', else the OS setting).
   The decisions are written down in CLAUDE.md. */

:root {
  color-scheme: light;

  /* Surfaces */
  --ground: #f6f7fb;          /* the canvas */
  --surface: #ffffff;         /* cards */
  --elevated: #ffffff;        /* side panel, dialogs, menus */
  --raised: #f6f7fb;          /* a well inside a card: table find rows, kanban columns */
  --hover: #eceef5;

  /* Text */
  --ink: #323338;
  --muted: #676879;
  --faint: #9698a6;
  --disabled: #c3c6d4;

  /* Borders */
  --line: #d0d4e4;
  --line-soft: #eceef5;
  --line-strong: #d0d4e4;

  /* Brand and links */
  --accent: #6161ff;
  --accent-hover: #5451e0;
  --accent-ink: #ffffff;
  --accent-wash: rgba(97, 97, 255, .12);
  --accent-wash-ink: #4a48d6;
  --link: #0073ea;
  /* Old names some of the kit still asks for; they point at the accent. */
  --gold: var(--accent);
  --gold-bright: var(--accent-hover);
  --gold-wash: var(--accent-wash);
  --gold-ink: var(--accent-wash-ink);

  /* Status as text (on a surface) */
  --good: #00a25f;
  --warn: #b26b00;
  --bad: #e2445c;

  /* Status pills: monday's hues, white text, the same in both themes. */
  --pill-good: #00c875;
  --pill-warn: #fdab3d;
  --pill-bad: #e2445c;
  --pill-info: #579bfc;
  --pill-purple: #a25ddc;
  --pill-pink: #ff158a;
  --pill-neutral: #c4c4c4;
  --pill-neutral-ink: #ffffff;
  --pill-ink: #ffffff;
  /* The kit's older names for the same fills. */
  --good-fill: var(--pill-good);   --good-fill-ink: var(--pill-ink);
  --warn-fill: var(--pill-warn);   --warn-fill-ink: var(--pill-ink);
  --bad-fill: var(--pill-bad);     --bad-fill-ink: var(--pill-ink);
  --info-fill: var(--pill-info);   --info-fill-ink: var(--pill-ink);
  --neutral-fill: var(--pill-neutral); --neutral-fill-ink: var(--pill-neutral-ink);
  --purple-fill: var(--pill-purple);
  --teal-fill: #037f4c;

  /* Alert boxes */
  --alert-bad-bg: #fdecef;
  --alert-bad-line: #f5c2ca;
  --alert-bad-head: #b3253c;
  --alert-bad-ink: #5c2430;
  --alert-warn-bg: #fff4e3;
  --alert-warn-line: #f7d9ad;
  --alert-warn-head: #8a5200;
  --alert-warn-ink: #5a3a10;
  --alert-good-bg: #e6f8ef;
  --alert-good-line: #b6e9d1;
  --alert-good-head: #0a7a4a;
  --alert-good-ink: #1d4d38;
  --good-wash: var(--alert-good-bg);
  --warn-wash: var(--alert-warn-bg);
  --bad-wash: var(--alert-bad-bg);

  /* Shadows: soft and tinted in the light; none in the dark. */
  --shadow-soft: 0 1px 2px rgba(41, 47, 76, .06);
  --shadow-float: 0 8px 24px rgba(41, 47, 76, .10);
  --shadow-drawer: -12px 0 40px rgba(41, 47, 76, .12);
  --backdrop: rgba(41, 47, 76, .22);

  /* Shape */
  --radius: 8px;              /* cards and inputs */
  --radius-card: 8px;
  --radius-pill: 999px;       /* buttons, tabs, pills */

  /* Type: Poppins — headings 600, body 400, labels 500. */
  --sans: "Poppins", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --serif: var(--sans);
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;

  /* The sidebar */
  --rail-bg: #ffffff;
  --rail-edge: #e6e9f0;
  --rail-ink: #323338;
  --rail-muted: #676879;
  --rail-active: var(--accent-wash);
  --rail-active-ink: var(--accent-wash-ink);

  /* Equistal brand marks — navy and gold. Used by the sign-in logo and any
     brand surface; the console's own accent stays as the theme system sets it. */
  --brand-navy: #1c2a44;
  --brand-gold: #c9a35c;
  --brand-mark: #1c2a44; /* the sign-in mark colour: navy on the light card */
}

html.dark {
  color-scheme: dark;

  --ground: #15161d;
  --surface: #1e1f29;
  --elevated: #262733;
  --raised: #24252f;
  --hover: #2a2b38;

  --ink: #e6e8ef;
  --muted: #9a9db2;
  --faint: #6c6f82;
  --disabled: #4b4e63;

  --line: #2e3040;
  --line-soft: #24252f;
  --line-strong: #383a4c;

  --accent: #6d6dff;
  --accent-hover: #8484ff;
  --accent-ink: #ffffff;
  --accent-wash: rgba(109, 109, 255, .18);
  --accent-wash-ink: #b3b3ff;
  --link: #7ab2ff;

  --good: #4fe0a0;
  --warn: #ffc46b;
  --bad: #ff5c72;

  --pill-bad: #ff5c72;
  --pill-neutral: #3a3c4a;
  --pill-neutral-ink: #c8cad6;

  --alert-bad-bg: rgba(226, 68, 92, .14);
  --alert-bad-line: rgba(226, 68, 92, .35);
  --alert-bad-head: #ff8b98;
  --alert-bad-ink: #f0c4ca;
  --alert-warn-bg: rgba(253, 171, 61, .14);
  --alert-warn-line: rgba(253, 171, 61, .35);
  --alert-warn-head: #ffc46b;
  --alert-warn-ink: #f3dcb8;
  --alert-good-bg: rgba(0, 200, 117, .14);
  --alert-good-line: rgba(0, 200, 117, .30);
  --alert-good-head: #4fe0a0;
  --alert-good-ink: #b8ecd2;

  --shadow-soft: none;
  --shadow-float: none;
  --shadow-drawer: none;
  --backdrop: rgba(0, 0, 0, .45);

  --rail-bg: #1a1b24;
  --rail-edge: #2e3040;
  --rail-ink: #e6e8ef;
  --rail-muted: #9a9db2;
  --brand-mark: #c9a35c; /* gold reads on the dark card where navy would not */
}

* { box-sizing: border-box; }

html, body { height: 100%; }

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

/* ---------- app frame ---------- */

/* One sidebar and the work. The menu used to be two columns — seven domains,
   then up to eighteen pages inside whichever one you picked — which made
   finding anything a guess about where it had been filed. Everything is now
   on screen at once, grouped, and the long document lists moved to tabs along
   the top of the page they belong to. */
.app {
  display: grid; grid-template-columns: 232px minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr);
  grid-template-areas: "rail top" "rail view"; min-height: 100vh;
}
.app > .rail { grid-area: rail; }
.app > .topbar { grid-area: top; }
.app > .view { grid-area: view; }

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

.topbar {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 28px; background: var(--surface); border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 30;
}
.topbar .search { position: relative; flex: 1; max-width: 560px; display: flex; align-items: center; }
.topbar .search > svg { position: absolute; left: 10px; color: var(--muted); pointer-events: none; }
.topbar .search input {
  width: 100%; padding: 7px 10px 7px 32px; border-radius: var(--radius); border: 1px solid var(--line);
  background: var(--raised); font-size: 13px;
}
.topbar .search input:focus { background: var(--surface); }
.topbar .results {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 35;
  background: var(--elevated); border: 1px solid var(--line); border-radius: var(--radius-card);
  box-shadow: var(--shadow-float); max-height: 60vh; overflow: auto; padding: 6px;
}
.topbar .results[hidden] { display: none; }
.topbar .results .hit {
  display: flex; flex-direction: column; gap: 1px; width: 100%; text-align: left;
  appearance: none; border: 0; background: transparent; font: inherit; color: var(--ink);
  padding: 8px 10px; border-radius: var(--radius); cursor: pointer;
}
.topbar .results .hit:hover, .topbar .results .hit[aria-selected="true"] { background: var(--accent-wash); }
.topbar .results .hit b { font-weight: 600; font-size: 13px; }
.topbar .results .hit span { font-size: 12px; color: var(--muted); }
.topbar .results .none { padding: 10px; color: var(--muted); font-size: 13px; }
.topbar .spacer { flex: 1; }
.topbar .bell {
  position: relative; appearance: none; border: 1px solid transparent; background: transparent; color: var(--muted);
  width: 36px; height: 36px; border-radius: var(--radius); cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
  margin-left: auto;
}
.topbar .bell:hover { background: var(--hover); color: var(--ink); }
.topbar .bell .count {
  position: absolute; top: 3px; right: 3px; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 8px;
  background: var(--bad-fill); color: #fff; font-size: 10px; font-weight: 700; line-height: 16px; text-align: center;
}
.topbar .bell .count[hidden] { display: none; }
/* Orange when everything waiting is routine; red when something is serious. */
.topbar .bell:not(.has-bad) .count { background: var(--warn-fill); color: var(--ink); }
.topbar .bell-menu {
  position: absolute; top: calc(100% - 4px); right: 28px; width: min(420px, 90vw); z-index: 35;
  background: var(--elevated); border: 1px solid var(--line); border-radius: var(--radius-card);
  box-shadow: var(--shadow-float); padding: 8px; max-height: 70vh; overflow: auto;
}
.topbar .bell-menu[hidden] { display: none; }
.topbar .bell-menu h4 { margin: 4px 8px 8px; font-size: 12px; font-weight: 600; color: var(--muted); }
.topbar .bell-menu .item {
  display: flex; gap: 10px; align-items: flex-start; width: 100%; text-align: left;
  appearance: none; border: 0; background: transparent; font: inherit; color: var(--ink);
  padding: 8px 10px; border-radius: var(--radius); cursor: pointer; font-size: 13px;
}
.topbar .bell-menu .item:hover { background: var(--hover); }
.topbar .bell-menu .item .dot { width: 8px; height: 8px; border-radius: 4px; margin-top: 6px; flex: none; background: var(--warn-fill); }
.topbar .bell-menu .item .dot.bad { background: var(--bad-fill); }
.topbar .bell-menu .item .dot.info { background: var(--info-fill); }
.topbar .bell-menu .quiet { padding: 10px; color: var(--muted); font-size: 13px; }
.topbar[hidden] { display: none; }
@media (max-width: 900px) {
  .app { grid-template-columns: 1fr; grid-template-rows: auto auto minmax(0, 1fr); grid-template-areas: "rail" "top" "view"; }
  .topbar { padding: 8px 12px; position: static; }
}
.app[hidden] { display: none; }

/* The menu stays put while the page moves under it.
   Without this the rail is simply a tall grid cell: on a long screen — the
   customer list, the audit trail — the row grows to the table's height, the
   spacer below the menu grows with it, and scrolling down to read the table
   carries the whole menu off the top of the window. What is left on screen is
   the tail of the menu, an acre of empty navy, and the account block stranded
   at the very bottom. Sticky with a viewport height pins it: the menu is
   always there, and when it is too long for the window it scrolls inside
   itself rather than dragging the page around. */
.rail {
  background: var(--rail-bg);
  border-right: 1px solid var(--rail-edge);
  display: flex;
  flex-direction: column;
  padding: 16px 10px 14px;
  gap: 2px;
  position: sticky;
  top: 0;
  align-self: start;
  height: 100vh;
}
.rail .mark {
  font-size: 15px; font-weight: 600; letter-spacing: -.01em;
  padding: 2px 8px 12px; margin-bottom: 6px;
  border-bottom: 1px solid var(--rail-edge); color: var(--rail-ink);
  position: relative;
}
.rail .mark small {
  display: block; font-weight: 500; font-size: 11px;
  color: var(--rail-muted); letter-spacing: .02em; text-transform: none; margin-top: 2px;
}

/* min-height:0 is what lets the menu scroll rather than growing past its
   parent and pushing Sign out off the bottom — the headings add height. */
.rail .rail-nav { display: flex; flex-direction: column; gap: 1px; min-height: 0; overflow-y: auto; }
/* On a short window the menu does not fit however tightly it is set, and it
   scrolls inside itself. A visible slim scrollbar is the only honest way to
   say so — otherwise Admin is simply missing and nobody knows to look. */
.rail .rail-nav { scrollbar-width: thin; scrollbar-color: var(--rail-edge) transparent; }
.rail .rail-nav::-webkit-scrollbar { width: 6px; }
.rail .rail-nav::-webkit-scrollbar-thumb { background: var(--rail-edge); border-radius: 3px; }
.rail .rail-nav::-webkit-scrollbar-track { background: transparent; }
.rail .grp {
  font-size: 11px; letter-spacing: .02em; text-transform: none;
  color: var(--rail-muted); font-weight: 600; padding: 12px 10px 3px;
}
.rail .rail-nav > .grp:first-child { padding-top: 0; }
.rail button {
  appearance: none; border: 0; background: transparent; color: var(--rail-muted);
  font: inherit; font-size: 13px; font-weight: 500; text-align: left; cursor: pointer;
  /* Tight enough that the whole menu — all twenty entries and five headings —
     fits a 900px-tall laptop window without the sidebar having to scroll
     inside itself. A menu you have to scroll to see is the problem this was
     meant to solve. */
  padding: 5px 10px; border-radius: var(--radius); width: 100%;
  display: flex; align-items: center; gap: 10px;
}
.rail button svg { flex: 0 0 auto; opacity: .8; }
.rail button .lbl { flex: 1; min-width: 0; }
.rail button:hover { background: var(--hover); color: var(--rail-ink); }
.rail button:hover svg { opacity: 1; }
.rail button[aria-current="true"] {
  background: var(--rail-active); color: var(--rail-active-ink); font-weight: 600;
}
.rail button[aria-current="true"] svg { opacity: 1; color: var(--rail-active-ink); }
.rail button .tally { font: 600 11px/1 var(--sans); color: var(--accent); }
.rail .spacer { flex: 1; }

/* The foot of the rail: your name is the button that opens your profile, with
   sign out beside it. One row, because a "My profile" link sitting above a
   plate with your name on it was the same thing written twice. */
.rail .account { display: flex; align-items: center; gap: 4px; padding-top: 10px; border-top: 1px solid var(--rail-edge); }
.rail .who { flex: 1; min-width: 0; font-size: 11px; line-height: 1.35; color: var(--rail-muted); }
.rail .who b { display: block; font-size: 13px; color: var(--rail-ink); font-weight: 600; }
.rail .who small { display: block; font-size: 11px; color: var(--rail-muted); }
.rail .who .lbl { overflow: hidden; }
.rail .who b, .rail .who small { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rail .leave { flex: 0 0 auto; width: 30px; padding: 7px 0; justify-content: center; color: var(--rail-muted); }
.rail .leave:hover { background: var(--hover); color: var(--rail-ink); }
/* The light/dark switch: a sun in the dark, a moon in the light — it shows
   what pressing it gives you. */
.rail .theme .sun, .rail .theme .moon { display: none; }
html:not(.dark) .rail .theme .moon { display: block; }
html.dark .rail .theme .sun { display: block; }
.rail .btn { background: transparent; border-color: var(--rail-edge); color: var(--rail-muted); }
.rail .btn:hover { background: var(--hover); color: var(--rail-ink); }

/* The documents inside a section, along the top of its page. Finance follows
   Bukku's order here, which is the reason it can be four links in the menu
   instead of eighteen. */
.tabs {
  display: flex; gap: 4px; flex-wrap: wrap;
  margin: 2px 0 14px; padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
}
.tabs button {
  appearance: none; background: transparent; border: 1px solid transparent;
  color: var(--muted); font: inherit; font-size: 13px; font-weight: 500; cursor: pointer;
  padding: 6px 14px; border-radius: var(--radius-pill);
}
.tabs button:hover { background: var(--hover); color: var(--ink); }
.tabs button[aria-current="true"] {
  background: var(--accent-wash); color: var(--accent-wash-ink); font-weight: 600; border-color: transparent;
}

/* Sections WITHIN one screen — the same control one level down, drawn lighter
   so the eye still reads the row above it as the outer one. Outlined rather
   than filled when current: two solid navy pills stacked would look like two
   competing answers to "where am I". */
.tabs.inner {
  border-bottom: none;
  margin: -4px 0 12px; padding-bottom: 0;
}
.tabs.inner button { font-size: 12.5px; padding: 4px 10px; border-color: var(--line); background: var(--surface); }
.tabs.inner button[aria-current="true"] {
  background: var(--surface); color: var(--accent-wash-ink); border-color: var(--accent);
}
/* How many are in a section, on the tab itself, so nobody opens an empty one
   to find out. */
.tabs .pill {
  display: inline-block; margin-left: 6px; padding: 0 6px;
  border-radius: 999px; background: var(--line); color: var(--muted);
  font-size: 11px; font-weight: 600; line-height: 17px; vertical-align: 1px;
}
.tabs button[aria-current="true"] .pill { background: var(--accent); color: #fff; }
.tabs.inner button[aria-current="true"] .pill { background: var(--accent); color: #fff; }

/* Content column. Capped: on a wide monitor an uncapped table flings its first
   and last columns to opposite edges of the screen and stops being readable as
   a row. Wider tables scroll inside their own panel instead. */
.view { min-width: 0; padding: 22px 28px 64px; overflow-x: hidden; }
.view > * { max-width: 1320px; }
.view > header { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-bottom: 4px; }
.view > header h1 {
  font-size: 24px; font-weight: 600; letter-spacing: -.01em; margin: 0; color: var(--ink);
}
.view > header .lede { color: var(--muted); font-size: 13px; margin: 0 0 16px; max-width: 78ch; }
.view > header .actions { margin-left: auto; display: flex; gap: 8px; }
.view > .lede { color: var(--muted); font-size: 13px; margin: 0 0 16px; max-width: 78ch; }

/* ---------- panels ---------- */

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  margin-bottom: 16px;
  min-width: 0;
}
/* A plain medium-weight title, the same colour as the text: hierarchy from
   size and space, as monday does it, not from colour or capitals. */
.card > h2 {
  font-size: 14px; font-weight: 600; letter-spacing: -.005em; text-transform: none;
  margin: 0; padding: 12px 16px; border-bottom: 1px solid var(--line);
  display: flex; align-items: center; gap: 10px; color: var(--ink);
}
.card > h2 .sub { font-weight: 400; color: var(--muted); font-size: 12px; text-transform: none; letter-spacing: 0; }
.card > h2 .right { margin-left: auto; display: flex; gap: 6px; align-items: center; }
.card .body { padding: 14px; }
.card .body > :first-child { margin-top: 0; }
.card .body > :last-child { margin-bottom: 0; }
.card .scroll { overflow-x: auto; }

.grid { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); align-items: start; }

/* ---------- tables ---------- */

table { border-collapse: collapse; width: 100%; font-size: 13px; }
thead th {
  text-align: left; font-size: 12px; font-weight: 500; letter-spacing: 0;
  text-transform: none; color: var(--muted);
  padding: 8px 14px; border-bottom: 1px solid var(--line); white-space: nowrap;
  background: var(--surface);
}
tbody td { padding: 8px 14px; border-bottom: 1px solid var(--line); vertical-align: middle; line-height: 1.35; }
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover td { background: var(--raised); }
td .note { display: block; color: var(--faint); font-size: 11px; margin-top: 1px; }

/* Money and any other figure: monospaced, right-aligned, so a wrong order of
   magnitude is visible without reading the digits. */
.num, td.num, th.num { text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; white-space: nowrap; }
thead th.num { text-align: right; }
.num.neg { color: var(--bad); }
.total td { border-top: 2px solid var(--line-strong); font-weight: 600; }

.empty { padding: 22px 14px; color: var(--faint); font-size: 13px; text-align: center; }
.empty b { display: block; color: var(--muted); font-weight: 600; margin-bottom: 2px; }

/* ---------- status ---------- */

/* A dot as well as colour, so status survives being printed or misread. */
/* monday's status block: a filled colour, white text, the word inside it.
   Neutral is the "not started" grey. Colour never stands alone — the word is
   always there — and every fill carries white text at 3:1 or better. */
.tag {
  display: inline-flex; align-items: center; justify-content: center; gap: 5px;
  font-size: 11px; font-weight: 700; white-space: nowrap; line-height: 1;
  padding: 5px 10px; border-radius: var(--radius-pill); min-width: 64px;
  background: var(--pill-neutral); color: var(--pill-neutral-ink); border: 0;
}
.tag.good { background: var(--pill-good); color: var(--pill-ink); }
.tag.warn { background: var(--pill-warn); color: var(--pill-ink); }
.tag.bad  { background: var(--pill-bad);  color: var(--pill-ink); }
.tag.info { background: var(--pill-info); color: var(--pill-ink); }
.tag.purple { background: var(--pill-purple); color: var(--pill-ink); }
.tag.pink { background: var(--pill-pink); color: var(--pill-ink); }

/* ---------- boards ---------- */

/* monday's board: groups stacked, each with a coloured title and a stripe
   down the left edge of its rows. The stripe is the group's colour and only
   that — status keeps its own colour in its own cell. */
.board { display: flex; flex-direction: column; gap: 22px; margin-bottom: 16px; }
.board-group h3 {
  display: flex; align-items: baseline; gap: 8px; margin: 0 0 6px 2px;
  font-size: 15px; font-weight: 600; color: var(--group); letter-spacing: -.005em;
}
.board-group h3 .swatch { width: 10px; height: 10px; border-radius: 3px; background: var(--group); align-self: center; }
.board-group h3 .count { font-size: 12px; font-weight: 500; color: var(--muted); }
.board-group h3 .sub { font-size: 12px; font-weight: 400; color: var(--muted); margin-left: 4px; }
.board-group .scroll { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-card); overflow: hidden; overflow-x: auto; }
.board-group table { border-collapse: separate; border-spacing: 0; }
.board-group thead th { background: var(--surface); }
.board-group tbody td:first-child, .board-group thead th:first-child { border-left: 6px solid var(--group); }
.board-group thead th:first-child { border-left-color: transparent; }
.board-group tbody tr:last-child td { border-bottom: 0; }
.board-empty {
  background: var(--surface); border: 1px dashed var(--line-strong); border-left: 6px solid var(--group);
  border-radius: var(--radius-card); padding: 10px 14px; color: var(--muted); font-size: 13px;
}

/* A status block that opens the change dialogue. */
button.tag.pillbtn { cursor: pointer; font: inherit; font-size: 11px; font-weight: 700; appearance: none; }
button.tag.pillbtn .chev { font-size: 11px; line-height: 0; margin-left: 2px; opacity: .8; }
button.tag.pillbtn:hover { filter: brightness(.94); }
button.tag.pillbtn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* ---------- the detail panel ---------- */

/* A record opens in a panel from the right, over the board, the way monday's
   item card does. The board stays put behind a light shade; the panel is
   the record and nothing else. The host is the page's own detail element,
   fixed to the right edge while it has content. */
.drawer-back { position: fixed; inset: 0; background: var(--backdrop); z-index: 40; }
.drawer-back[hidden] { display: none; }
.detail.open {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 41;
  width: min(760px, 92vw); background: var(--elevated); border-left: 1px solid var(--line);
  box-shadow: var(--shadow-drawer);
  overflow: auto; padding: 18px 20px 28px;
  animation: drawer-in .18s ease-out;
}
@keyframes drawer-in { from { transform: translateX(24px); opacity: .6; } to { transform: none; opacity: 1; } }
.drawer-close {
  position: absolute; top: 12px; right: 14px; z-index: 2;
  appearance: none; border: 1px solid transparent; background: transparent; color: var(--muted);
  font: inherit; font-size: 15px; line-height: 1; width: 32px; height: 32px; border-radius: var(--radius); cursor: pointer;
}
.drawer-close:hover { background: var(--hover); color: var(--ink); }
.detail:not(.open) > .drawer-close { display: none; }
/* Inside the panel a record's card is the panel: no second border. */
.detail.open > .card { border: 0; box-shadow: none; margin: 0; }
.detail.open > .card > h2 { padding-right: 44px; font-size: 17px; }
.detail.open .card .card { border: 1px solid var(--line); }
body.drawer-open { overflow: hidden; }
@media (max-width: 720px) { .detail.open { width: 100vw; border-left: 0; } }

/* ---------- key/value readouts ---------- */

.kv { display: flex; justify-content: space-between; gap: 16px; padding: 7px 0; border-bottom: 1px solid var(--line); font-size: 13px; }
.kv:last-child { border-bottom: 0; }
.kv > span { color: var(--muted); }
.kv > b { font-family: var(--mono); font-variant-numeric: tabular-nums; font-weight: 600; }
.kv.total { border-top: 2px solid var(--line-strong); border-bottom: 0; margin-top: 2px; padding-top: 9px; }
.kv .neg { color: var(--bad); }

.stats { display: grid; gap: 1px; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); background: var(--line); border-bottom: 1px solid var(--line); }
.stat { background: var(--surface); padding: 14px 16px; }
.stat .label { font-size: 12px; letter-spacing: 0; text-transform: none; color: var(--muted); font-weight: 500; }
.stat .value { color: var(--ink); font: 600 22px/1.2 var(--sans); font-variant-numeric: tabular-nums; letter-spacing: -.01em; margin-top: 3px; }
.stat .value.bad { color: var(--bad); }
.stat .value.good { color: var(--good); }
.stat .foot { font-size: 11px; color: var(--muted); margin-top: 2px; }


/* ---------- widgets: the Today dashboard ---------- */
.widgets { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 14px; align-items: start; }
.widgets .widget { grid-column: span var(--span, 6); margin: 0; min-width: 0; }
.widgets .widget .body { padding: 12px 14px; }
.widgets .widget .tablewrap { margin: -12px -14px; overflow-x: auto; }
.widgets .widget .tablewrap:not(:last-child) { margin-bottom: 12px; }
.widgets .widget .tablewrap > table { width: 100%; }
.widget > .foot { padding: 8px 14px; border-top: 1px solid var(--line); font-size: 12px; color: var(--muted); }
.widget.number { padding: 14px 16px; }
.widget.number .label { font-size: 12px; color: var(--muted); font-weight: 500; }
.widget.number .value { color: var(--ink); font: 600 26px/1.2 var(--sans); font-variant-numeric: tabular-nums; letter-spacing: -.01em; margin-top: 4px; }
.widget.number .value.bad { color: var(--bad); }
.widget.number .value.good { color: var(--good); }
.widget.number .foot { font-size: 11px; color: var(--muted); margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.widget .notice { margin: 0 0 6px; }
.widget .notice:last-child { margin-bottom: 0; }
.widget .list { list-style: none; margin: 0; padding: 0; }
.widget .list li { display: flex; justify-content: space-between; gap: 10px; align-items: center; padding: 7px 0; border-bottom: 1px solid var(--line); font-size: 13px; }
.widget .list li:last-child { border-bottom: 0; }
.widget .list li .note { display: block; }

.chart.bars { width: 100%; height: auto; display: block; }
.chart.bars .bar { fill: var(--accent); opacity: .55; }
.chart.bars .bar.today { opacity: 1; }
.chart.bars .axis { stroke: var(--line); }
.chart.bars .val { font: 500 12px var(--sans); fill: var(--ink); }
.chart.bars .lbl { font: 12px var(--sans); fill: var(--muted); }
.chart.bars .lbl.today { fill: var(--ink); font-weight: 600; }

.battery .bar { display: flex; height: 22px; border-radius: 4px; overflow: hidden; background: var(--ground); gap: 2px; }
.battery .bar span { display: block; min-width: 4px; }
.battery .bar .empty { flex: 1; background: var(--line); }
.battery .legend { display: flex; flex-wrap: wrap; gap: 6px 14px; margin-top: 10px; font-size: 12px; color: var(--muted); }
.battery .legend i { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: 6px; vertical-align: -1px; }
.battery .legend b { color: var(--ink); font-weight: 600; }

@media (max-width: 1100px) { .widgets .widget { grid-column: span 6; } .widgets .widget.number { grid-column: span 3; } .widgets .widget.wide { grid-column: span 12; } }
@media (max-width: 700px) { .widgets .widget, .widgets .widget.number { grid-column: span 12; } }


/* ---------- views: the Table / Kanban switch, and the kanban ---------- */
.views { display: inline-flex; gap: 2px; padding: 3px; background: var(--raised); border: 1px solid var(--line); border-radius: var(--radius-pill); margin: 0 0 12px; }
.views button {
  appearance: none; border: 0; background: transparent; color: var(--muted); font: 500 13px var(--sans);
  padding: 5px 12px; border-radius: var(--radius-pill); cursor: pointer; display: inline-flex; align-items: center; gap: 6px;
}
.views button:hover { color: var(--ink); }
.views button[aria-selected="true"] { background: var(--surface); color: var(--accent-wash-ink); box-shadow: var(--shadow-soft); }

.kanban { display: flex; gap: 14px; align-items: flex-start; overflow-x: auto; padding-bottom: 8px; }
.kanban-col { flex: 1 1 260px; min-width: 240px; max-width: 360px; background: var(--raised); border: 1px solid var(--line); border-radius: var(--radius-card); border-top: 4px solid var(--group); }
.kanban-col h3 { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 0; padding: 10px 12px 2px; font: 600 14px var(--sans); color: var(--ink); }
.kanban-col h3 .count { font-size: 12px; font-weight: 600; color: var(--group); background: var(--surface); border: 1px solid var(--line); border-radius: 10px; padding: 0 8px; line-height: 18px; }
.kanban-col .sub { margin: 0; padding: 0 12px 8px; font-size: 12px; color: var(--muted); }
.kanban-col .cards { display: flex; flex-direction: column; gap: 8px; padding: 6px 8px 8px; min-height: 60px; }
.kanban-empty { padding: 14px 6px; font-size: 13px; color: var(--muted); text-align: center; }
.kcard { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-card); padding: 10px 12px; box-shadow: var(--shadow-soft); }
.kcard:hover { border-color: var(--line-strong); box-shadow: var(--shadow-float); }
.kcard .head { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; }
.kcard .ttl { font-weight: 600; font-size: 13px; line-height: 1.3; }
.kcard .sub { font-size: 12px; color: var(--muted); margin-top: 2px; }
.kcard .lines { margin-top: 8px; display: flex; flex-direction: column; gap: 3px; font-size: 12px; color: var(--ink); }
.kcard .lines .note { display: inline; margin-left: 4px; }
.kcard .acts { display: flex; gap: 6px; margin-top: 10px; flex-wrap: wrap; }

/* ---------- forms ---------- */

.form { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end; }
.field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.field > label { font-size: 11px; color: var(--muted); font-weight: 500; }
.field.wide { flex: 1 1 260px; }
.field.mid { flex: 0 1 170px; }
.field.narrow { flex: 0 1 120px; }
/* A line of its own. Anything somebody writes a sentence into should not be
   sharing a row with two dropdowns — on the incident form that put "What
   happened" between a phone number and a tick-box. */
.field.full { flex: 1 0 100%; }

/* A tick-box is not a field with a label above it: the words belong beside
   the box, on one line. Left as a bare label in a wrapping row, "First aid
   given" broke across three lines and read as broken. */
.field.check {
  flex: 0 0 auto; flex-direction: row; align-items: center; gap: 7px;
  white-space: nowrap; font-size: 13px; color: var(--ink);
  padding: 6px 10px; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--raised); cursor: pointer; align-self: flex-end;
}
.field.check input[type="checkbox"] { width: 16px; height: 16px; min-width: 16px; margin: 0; accent-color: var(--accent); }
input[type="checkbox"], input[type="radio"] { width: auto; min-width: 0; }

input, select, textarea {
  font: inherit; font-size: 13px; color: var(--ink);
  background: var(--surface); border: 1px solid var(--line-strong);
  border-radius: var(--radius); padding: 6px 9px; width: 100%; min-width: 0;
}
input[type="date"], input[type="month"] { font-family: var(--mono); }
input:focus, select:focus, textarea:focus, button:focus-visible {
  /* Navy, not gold: the gold ring was 2.9:1 on cream, under the 3:1 a focus
     indicator needs. Navy reads at 14:1 (and is gold in dark mode, where that
     is the high-contrast colour). "Where am I" must never be a squint. */
  outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent);
}
input::placeholder { color: var(--faint); }
.hint { font-size: 12px; color: var(--muted); margin: 8px 0 0; max-width: 76ch; }
.hint.strong { color: var(--ink); }

/* Anchor "buttons" (Open counter screen, downloads) must look identical to
   real buttons — .btn covers both elements now. */
.btn {
  appearance: none; font: inherit; font-size: 13px; font-weight: 500;
  padding: 6px 14px; border-radius: var(--radius-pill); cursor: pointer;
  border: 1px solid var(--line-strong); background: var(--surface); color: var(--ink);
  white-space: nowrap; text-decoration: none; display: inline-block;
}
.btn:hover { background: var(--hover); border-color: var(--line-strong); }
.btn.primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.btn.primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.btn.danger { color: var(--bad); border-color: var(--line-strong); }
/* A link dressed as a button, opening WhatsApp with the message ready. */
a.btn { text-decoration: none; display: inline-flex; align-items: center; }
.btn.wa { background: #25d366; border-color: #25d366; color: #0b3d1f; }
.btn.wa:hover { background: #1fbf5b; border-color: #1fbf5b; }
.btn.danger:hover { background: var(--bad-wash); border-color: var(--bad); }
.btn.small { font-size: 12px; padding: 3px 10px; }
.btn:disabled { opacity: .5; cursor: not-allowed; }
a.btn { line-height: 1.45; }

/* A record's name, used as the way into it. Left unstyled these came out in
   the browser's default blue with an underline, which in a navy-and-gold
   console reads as something broken rather than as an invitation. */
a.drill {
  color: var(--link); font-weight: 500; text-decoration: none;
  border-bottom: 1px solid transparent; cursor: pointer;
}
a.drill:hover { border-bottom-color: var(--link); }

/* A column heading that sorts. It has to look like a heading first and a
   control second: this is a table somebody reads, not a toolbar. */
th button.sort {
  all: unset; cursor: pointer; display: inline-flex; align-items: baseline; gap: 2px;
  font: inherit; color: inherit; letter-spacing: inherit; text-transform: inherit;
}
th button.sort:hover { color: var(--accent); }
th button.sort:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }
th .arrow { font-size: 10px; color: var(--accent); }
th[aria-sort="ascending"], th[aria-sort="descending"] { color: var(--accent); }
th.num button.sort { justify-content: flex-end; }

/* Finding one row among many. Sits in the table's own head so it scrolls and
   sticks with the headings rather than floating above an unrelated card. */
thead tr.find th { padding: 8px 10px; background: var(--raised); border-bottom: 1px solid var(--line); }
.findbox { display: flex; align-items: center; gap: 10px; font-weight: 400; text-transform: none; letter-spacing: 0; }
.findbox input[type="search"] { max-width: 320px; font-size: 13px; }
.findbox .note { white-space: nowrap; }

/* An image shown at the size it will print, against paper. The white ground
   matters: a signature scanned on white looks quite different on the grey of
   a form, and it is the paper version somebody is judging. */
.imgpaper {
  background: #fff; border: 1px solid var(--line-strong); border-radius: 4px;
  padding: 10px 12px; margin-top: 8px; display: flex; align-items: center; justify-content: center;
  min-height: 56px; box-shadow: var(--shadow-soft);
}
/* Whatever is put inside has to fit the paper, not push past it: an
   attachment brings its own height and an 800px-wide logo at that height
   bled straight out of the card. */
.imgpaper img { max-width: 100%; max-height: 120px; width: auto; height: auto; object-fit: contain; }
.imgpaper a { display: block; max-width: 100%; }

/* ---------- dropping a file ---------- */

/* The browser's own file button is a dead grey rectangle you cannot drop on.
   This is a target: big enough to aim at with a file in hand, and obviously
   live the moment something is dragged over the window. */
.drop {
  border: 1.5px dashed var(--line-strong); border-radius: 8px;
  background: var(--raised); padding: 14px 16px;
  display: flex; flex-wrap: wrap; align-items: center; gap: 12px;
  cursor: pointer; width: 100%; box-sizing: border-box;
  transition: border-color .12s, background .12s;
}
.drop:hover { border-color: var(--gold); outline: none; }
.drop:focus-visible { border-color: var(--accent); outline: 2px solid var(--accent); outline-offset: 2px; }
.drop.over {
  border-color: var(--gold); border-style: solid;
  background: var(--gold-wash);
}
.drop .dropsay { display: flex; flex-direction: column; gap: 2px; }
.drop .dropsay b { font-size: 13px; }
.drop .dropfile { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; width: 100%; }
.drop .dropfile img {
  height: 52px; width: auto; max-width: 90px; border-radius: 4px;
  border: 1px solid var(--line); background: #fff; object-fit: contain;
}
.drop .dropicon {
  display: inline-flex; align-items: center; justify-content: center;
  height: 52px; width: 44px; border-radius: 4px; background: var(--surface);
  border: 1px solid var(--line); font-size: 11px; font-weight: 600; letter-spacing: .04em;
}
.drop .dropname { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.drop .dropname b { font-size: 13px; overflow-wrap: anywhere; }
/* Dropping onto the whole window, not only onto the target, is what people
   try first — so the page says plainly where the file has to go. */
body.dragging .drop { border-color: var(--gold); background: var(--gold-wash); }
.drop.busy { opacity: .55; pointer-events: none; }

/* What is already kept against a record. */
.filelist { display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px; }
.fileitem {
  display: flex; align-items: center; gap: 12px;
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 8px 12px; background: var(--surface);
}
.fileitem .imgpaper { flex: 0 0 auto; min-height: 0; }
.fileitem .imgpaper img { max-height: 56px; }
.fileitem .dropname { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.fileitem .dropname b { font-size: 13px; overflow-wrap: anywhere; }




/* ---------- messages ---------- */

.flash { position: fixed; right: 18px; bottom: 18px; z-index: 50; display: flex; flex-direction: column; gap: 8px; max-width: 420px; }
.flash div {
  background: var(--elevated); border: 1px solid var(--line); border-left-width: 3px;
  border-radius: var(--radius); padding: 10px 14px; font-size: 13px;
  box-shadow: var(--shadow-float);
}
.flash div.ok { border-left-color: var(--good); }
.flash div.err { border-left-color: var(--bad); }

/* Alert boxes: kept exactly where they are, with a dark variant each — a
   translucent tint of the hue over the card, a border of the same hue, a
   lighter heading and a paler body. The left stripe stays: colour and
   position both say what kind of box it is. */
.notice { border: 1px solid var(--line); border-left: 3px solid var(--muted); border-radius: var(--radius); padding: 10px 12px; font-size: 13px; margin-bottom: 14px; background: var(--surface); color: var(--ink); }
.notice b { font-weight: 600; }
.notice.good { border-color: var(--alert-good-line); border-left-color: var(--pill-good); background: var(--alert-good-bg); color: var(--alert-good-ink); }
.notice.good b { color: var(--alert-good-head); }
.notice.warn { border-color: var(--alert-warn-line); border-left-color: var(--pill-warn); background: var(--alert-warn-bg); color: var(--alert-warn-ink); }
.notice.warn b { color: var(--alert-warn-head); }
.notice.bad { border-color: var(--alert-bad-line); border-left-color: var(--pill-bad); background: var(--alert-bad-bg); color: var(--alert-bad-ink); }
.notice.bad b { color: var(--alert-bad-head); }
.notice .btn { color: var(--ink); background: var(--surface); }
.notice .hint { color: inherit; opacity: .85; }

/* ---------- sign in ---------- */

.signin { max-width: 380px; margin: 10vh auto 0; }
/* The Equistal horse, masked so it takes the brand colour in either theme. */
.signin .brand-logo {
  order: -1; width: 54px; height: 70px; margin: 0 auto 8px; background: var(--brand-mark);
  -webkit-mask: url(/logo-mark.svg) center / contain no-repeat;
  mask: url(/logo-mark.svg) center / contain no-repeat;
}
.signin::before {
  content: "Kelab Polo Selangor";
  display: block; text-align: center;
  font-size: 22px; font-weight: 600; letter-spacing: -.01em; color: var(--ink);
  margin-bottom: 4px;
}
.signin::after {
  content: "Equistal"; display: block; text-align: center; font-size: 12px; font-weight: 500; color: var(--muted);
  margin: 0 auto 18px;
}
.signin { display: flex; flex-direction: column; }
.signin[hidden] { display: none; }
.signin::before { order: 0; }
.signin::after { order: 1; }
.signin .card { order: 2; }
.signin .card .body { display: flex; flex-direction: column; gap: 10px; padding: 20px; }
.signin h1 { font-size: 17px; font-weight: 600; margin: 0 0 2px; color: var(--ink); }
.signin .hint { margin: 0; }


/* ---------- responsive ---------- */

/* Below this the two nav columns become one scrolling strip each, stacked
   above the content. Both need min-width:0 or they push the page sideways. */
@media (max-width: 1080px) {
  /* On a phone a 232px sidebar leaves too little for the work, so the menu
     becomes a scrolling strip above the page. The tabs already wrap. */
  .app { grid-template-columns: 1fr; }
  /* As a strip it is only as tall as its own contents, and it sticks to the
     top of the window rather than to a 100vh column. */
  .rail { min-width: 0; border-right: 0; border-bottom: 1px solid var(--rail-edge); padding: 10px 12px; gap: 6px; height: auto; z-index: 5; }
  .rail .mark { border: 0; padding: 0 0 6px; margin: 0; }
  .rail .mark::after { display: none; }
  .rail .rail-nav { flex-direction: row; gap: 4px; overflow-x: auto; padding-bottom: 2px; }
  .rail .grp { display: none; }
  .rail button { width: auto; white-space: nowrap; padding: 6px 10px; }
  .rail button[aria-current="true"] { box-shadow: none; }
  .rail .spacer { display: none; }
  .rail .account { border: 0; padding: 0; white-space: nowrap; }
  .rail .who { flex: 0 0 auto; }
  .rail .who b { display: inline; font-size: 12px; }
  .rail .who small { display: none; }
  .rail .btn { display: none; }
  .view { padding: 16px 14px 48px; }
}

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

/* ---------- the add dialogue ----------
   Adding something is occasional, so its form does not live on the page. The
   browser's own <dialog> handles focus, Escape and the backdrop; what is set
   here is only how it looks. */
dialog.sheet {
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: 0;
  width: min(520px, calc(100vw - 32px));
  max-height: calc(100vh - 64px);
  background: var(--elevated);
  color: var(--ink);
  box-shadow: var(--shadow-float);
  overflow: auto;
}
dialog.sheet.wide { width: min(760px, calc(100vw - 32px)); }
dialog.sheet::backdrop { background: var(--backdrop); }
dialog.sheet header { padding: 18px 20px 0; }
dialog.sheet h2 {
  font-size: 19px; font-weight: 600; letter-spacing: -.01em; margin: 0;
}
dialog.sheet header .hint { margin: 5px 0 0; }
dialog.sheet .form { padding: 16px 20px 4px; }
dialog.sheet .notice { margin: 0 20px; }
dialog.sheet footer {
  display: flex; justify-content: flex-end; gap: 8px;
  padding: 16px 20px 18px; position: sticky; bottom: 0;
  background: var(--elevated); border-top: 1px solid var(--line); margin-top: 12px;
}
@media (max-width: 560px) {
  dialog.sheet { width: 100vw; max-width: 100vw; max-height: 100vh; height: 100vh; border-radius: 0; border: 0; }
  dialog.sheet footer { padding-bottom: 22px; }
}

/* ---------- the organisation chart ----------
   Boxes with lines between them, which is what a chart is. Built as nested
   lists because a reporting line IS a nesting, and the connectors are drawn
   with borders on the list items rather than an SVG that would have to be
   laid out by hand and would not reflow when somebody is promoted. */
.org-chart { overflow-x: auto; padding: 6px 2px 10px; }
.org-tree, .org-tree ul { list-style: none; margin: 0; padding: 0; display: flex; justify-content: center; }
/* Centred while it fits, and scrollable — from its true left edge — once it
   does not. A centred flex row overflowing its container clips the start of
   itself and cannot be scrolled back to, which silently loses whoever sits
   furthest left on the chart: on this club, the Hon. Treasurer. */
.org-chart > .org-tree { width: max-content; min-width: 100%; margin: 0 auto; }
.org-tree ul { padding-top: 22px; }
.org-tree li {
  position: relative; padding: 0 10px;
  display: flex; flex-direction: column; align-items: center;
}
/* The stub down from a card to its children. */
.org-tree li > ul::before {
  content: ""; position: absolute; top: 0; left: 50%;
  width: 1px; height: 22px; background: var(--line-strong);
}
/* The horizontal rail joining siblings, and each sibling's drop onto it. */
.org-tree ul > li::before {
  content: ""; position: absolute; top: -22px; left: 50%;
  width: 1px; height: 22px; background: var(--line-strong);
}
.org-tree ul > li::after {
  content: ""; position: absolute; top: -22px; left: 0; right: 0;
  height: 1px; background: var(--line-strong);
}
.org-tree ul > li:first-child::after { left: 50%; }
.org-tree ul > li:last-child::after { right: 50%; }
.org-tree ul > li:only-child::after { display: none; }

.org-card {
  position: relative; display: flex; align-items: center; gap: 9px;
  width: 210px; padding: 8px 10px; cursor: pointer; text-align: left;
  background: var(--surface); border: 1px solid var(--line-strong); border-radius: 10px;
}
.org-card:hover, .org-card:focus-visible { border-color: var(--accent); outline: none; }
/* Engaged, not employed: dashed, and it says so on the card. A supplier drawn
   as staff is the one mistake this chart must not make. */
.org-card.engaged { border-style: dashed; background: transparent; }
.org-card .who { min-width: 0; display: flex; flex-direction: column; }
.org-card b { font-size: 13px; line-height: 1.25; }
.org-card .role { font-size: 11.5px; color: var(--muted); }
.org-card .engaged-mark { font-size: 10.5px; color: var(--muted); font-style: italic; }
.org-card .face {
  flex: 0 0 auto; width: 38px; height: 38px; border-radius: 50%;
  background: var(--line); color: var(--muted);
  display: grid; place-items: center; font-size: 13px; font-weight: 600;
  overflow: hidden;
}
.org-card .face img { width: 100%; height: 100%; object-fit: cover; display: block; }
.org-edit {
  position: absolute; top: 3px; right: 5px;
  appearance: none; background: transparent; border: 0; cursor: pointer;
  color: var(--muted); font-size: 15px; line-height: 1; padding: 2px 4px; border-radius: 6px;
}
.org-edit:hover { background: var(--line); color: var(--ink); }

.org-loose { margin-top: 18px; border-top: 1px dashed var(--line-strong); padding-top: 12px; }
.org-loose .loose-lede { margin: 0 0 10px; color: var(--muted); font-size: 12.5px; }
.org-row { display: flex; flex-wrap: wrap; gap: 10px; }

/* ---------- printing the chart ----------
   One sheet, A4 landscape. The tree is measured and scaled by the screen
   before the dialogue opens (printChart in talent.js), because a chart that
   spills onto a second page is two pages of nothing. */
@media print {
  body.printing-chart { background: #fff; }
  body.printing-chart .rail,
  body.printing-chart .tabs,
  body.printing-chart .actions,
  body.printing-chart .lede,
  body.printing-chart .flash,
  body.printing-chart .org-edit,
  body.printing-chart .hint { display: none !important; }
  body.printing-chart .view { padding: 0; }
  body.printing-chart .card { border: 0; box-shadow: none; }
  /* zoom rather than transform: a transform leaves the chart's original
     footprint behind as white space, so everything under it — the freelancers
     nobody has placed — got pushed down the sheet by a gap. zoom shrinks the
     layout itself. */
  body.printing-chart .org-chart {
    overflow: visible;
    zoom: var(--org-print-scale, 1);
  }
  body.printing-chart .org-card { break-inside: avoid; }
  @page { size: A4 landscape; margin: 10mm; }
}

/* ---------- the installed app ---------- */

/* A phone's notch and home bar: the frame keeps clear of them. */
.rail { padding-top: calc(16px + env(safe-area-inset-top, 0px)); padding-left: calc(10px + env(safe-area-inset-left, 0px)); padding-bottom: calc(14px + env(safe-area-inset-bottom, 0px)); }
.topbar { padding-right: calc(28px + env(safe-area-inset-right, 0px)); }
.view { padding-right: calc(28px + env(safe-area-inset-right, 0px)); padding-bottom: calc(64px + env(safe-area-inset-bottom, 0px)); }
@media (max-width: 1080px) {
  .rail { padding-top: calc(10px + env(safe-area-inset-top, 0px)); padding-left: calc(12px + env(safe-area-inset-left, 0px)); padding-bottom: 10px; }
  .view { padding-left: calc(14px + env(safe-area-inset-left, 0px)); padding-right: calc(14px + env(safe-area-inset-right, 0px)); padding-bottom: calc(48px + env(safe-area-inset-bottom, 0px)); }
}

/* "New version available — Refresh": small, bottom-left, out of the way. */
.pwa-toast {
  position: fixed; left: 16px; bottom: calc(16px + env(safe-area-inset-bottom, 0px)); z-index: 60;
  display: flex; align-items: center; gap: 10px; padding: 10px 12px 10px 14px;
  background: var(--elevated); color: var(--ink); border: 1px solid var(--line); border-radius: var(--radius-card);
  box-shadow: var(--shadow-float); font-size: 13px; font-weight: 500;
}
/* Offline: one line across the top, in the warning colours, until the network is back. */
.pwa-offline {
  position: sticky; top: 0; z-index: 45; padding: calc(7px + env(safe-area-inset-top, 0px)) 16px 7px;
  background: var(--alert-warn-bg); color: var(--alert-warn-ink); border-bottom: 1px solid var(--alert-warn-line);
  font-size: 13px; font-weight: 500; text-align: center;
}
