/* Gather UI — design tokens + components.
   Two skins: light (default) and dark via [data-theme="dark"] on <html>.
   Mark hues validated with the dataviz palette validator (chroma + contrast).

   Owner's colours are the Bears' — navy #0B162A and orange #C83803 — carried by
   the ink and the action hue against the same cream. Green stays green: on this
   screen it means a man is here, and a team colour can't say that. */

:root {
  --bg: #f6f1e7;
  --card: #fdfaf3;
  --ink: #0b162a;        /* Bears navy — so dark it reads as black in body text */
  --navy: #1b3f7a;       /* the same navy where it has to look blue */
  --muted: #5f6775;
  --line: #ddd9cf;
  --ember: #c83803;      /* Bears orange: action, single-series chart hue */
  --ember-soft: #c8380322;
  --pine: #2c7d4c;       /* present / good — a status, not a team colour */
  --pine-soft: #2c7d4c1f;
  --amber: #a8842c;      /* in-progress status */
  --rust: #9c3a24;       /* needs attention status */
  --shadow: 0 1px 3px rgba(11, 22, 42, 0.10);
  --radius: 10px;
}

[data-theme="dark"] {
  --bg: #201a14;
  --card: #2a231b;
  --ink: #efe6d6;
  --muted: #a1968a;
  --line: #3b332a;
  --ember: #e8672f;
  --ember-soft: #e8672f29;
  --navy: #7ea6e0;
  --pine: #67c186;
  --pine-soft: #67c18624;
  --amber: #cfa64e;
  --rust: #c96a52;
  --shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  font-size: 16px;
  line-height: 1.45;
}

.serif, h1, h2 {
  font-family: "Iowan Old Style", "Palatino Linotype", Georgia, serif;
  font-weight: 500;
  letter-spacing: -0.01em;
}

.mono { font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; }

a { color: var(--ember); }

/* Kiosk touch: no grey flash on tap, and a tap never selects the label text. */
button, g-card, [role="button"] {
  -webkit-tap-highlight-color: transparent;
}

button {
  font: inherit;
  cursor: pointer;
  border: 1px solid var(--line);
  background: var(--card);
  color: var(--ink);
  border-radius: 8px;
  padding: 0.4rem 0.9rem;
}
button.primary { background: var(--ember); border-color: var(--ember); color: #fff8f0; }
button:focus-visible, input:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--ember);
  outline-offset: 2px;
}

/* ---------- g-brand : app name line ---------- */
g-brand { display: inline-flex; align-items: baseline; gap: 0.4rem; white-space: nowrap; }
/* The parish and the app read as one masthead, at one size: the church in navy,
   GATHER in orange. It used to whisper the parish and shout the product. The
   Bears' own navy is nearly black at this size, so the masthead uses the lighter
   one — it has to look blue to be doing its job. */
g-brand .brand-org { font-weight: 600; letter-spacing: 0.02em; color: var(--navy); }
g-brand .brand-sep { color: var(--muted); }
g-brand .brand-app { font-weight: 600; letter-spacing: 0.08em; color: var(--ember); }
/* The masthead as a way home. It should read as the masthead, not as a link, until
   the pointer is on it — a underlined logo looks like a mistake. */
g-brand .brand-home {
  display: inline-flex; align-items: baseline; gap: 0.4rem;
  text-decoration: none; border-radius: 4px;
}
g-brand .brand-home:hover .brand-org { text-decoration: underline; }
g-brand .brand-home:focus-visible { outline: 2px solid var(--ember); outline-offset: 3px; }

/* ---------- g-count : live door count ---------- */
g-count { display: flex; align-items: baseline; gap: 0.9rem; }
g-count .nums { font-size: 3.2rem; line-height: 1; white-space: nowrap; }
g-count .nums .of { color: var(--muted); font-size: 1.6rem; }
g-count .meta { color: var(--muted); font-size: 0.85rem; }

/* Shared marks — used by more than one component, so not scoped to any of them. */
.first-badge {
  display: inline-block;
  background: var(--ember-soft);
  color: var(--ember);
  border-radius: 999px;
  padding: 0.1rem 0.6rem;
  font-weight: 600;
  font-size: 0.8rem;
  white-space: nowrap;
}
.kind-pill {
  display: inline-block;
  border-radius: 999px;
  border: 1px solid var(--line);
  color: var(--muted);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  padding: 0.08rem 0.55rem;
  vertical-align: 0.1em;
}
.kind-pill.kind-pancake { color: var(--amber); border-color: var(--amber); }
.kind-pill.kind-ranch { color: var(--pine); border-color: var(--pine); }
.kind-pill.kind-vols { color: var(--ember); border-color: var(--ember); }

/* ---------- g-card : roll-call card (the signature) ---------- */
g-card {
  display: block;
  background: var(--card);
  border: 1px solid var(--line);
  border-left: 4px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 0.85rem 1rem;
  cursor: pointer;
  user-select: none;
  transition: border-color 0.18s ease, background 0.18s ease, transform 0.06s ease;
}
g-card:active { transform: scale(0.985); }
g-card .name { font-size: 1.12rem; font-weight: 600; }
g-card .group { color: var(--muted); font-size: 0.8rem; margin-top: 0.1rem; }
g-card .state { margin-top: 0.45rem; font-size: 0.82rem; color: var(--muted); }
g-card[state="here"] { border-left-color: var(--pine); background: var(--pine-soft); }
g-card[state="here"] .state { color: var(--pine); font-weight: 600; }
g-card[first] .name::after {
  content: "first time";
  color: var(--ember);
  background: var(--ember-soft);
  font-size: 0.66rem;
  font-weight: 700;
  border-radius: 999px;
  padding: 0.08rem 0.5rem;
  margin-left: 0.5rem;
  vertical-align: 0.15em;
}
/* Faces mode: a photo (or initials) tile instead of a name row. Same tap target. */
g-card[avatar], g-card[photo] {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.6rem;
  padding: 1.1rem 0.8rem;
  border-left-width: 1px;
  border-top: 4px solid var(--line);
}
g-card[avatar][state="here"], g-card[photo][state="here"] { border-top-color: var(--pine); }
g-card .face {
  width: 4.6rem;
  height: 4.6rem;
  border-radius: 50%;
  overflow: hidden;
  background: var(--ember-soft);
  color: var(--ember);
  border: 1px solid var(--line);
  display: grid;
  place-items: center;
  flex: 0 0 auto;
}
g-card .face img { width: 100%; height: 100%; object-fit: cover; display: block; }
g-card .face-initials { font-size: 1.5rem; font-weight: 600; }
g-card[state="here"] .face { background: var(--pine-soft); color: var(--pine); }
g-card[avatar] .group, g-card[photo] .group { font-size: 0.76rem; }
/* In a face tile the badge gets its own line — it can't share one with a long name. */
g-card[avatar][first] .name::after, g-card[photo][first] .name::after {
  display: block;
  width: fit-content;
  margin: 0.3rem auto 0;
  vertical-align: baseline;
}

@media (prefers-reduced-motion: reduce) {
  g-card, g-card:active { transition: none; transform: none; }
}

/* ---------- g-search ---------- */
g-search { display: block; }
g-search input {
  width: 100%;
  font: inherit;
  font-size: 1.05rem;
  color: var(--ink);
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0.65rem 0.9rem;
}
g-search input::placeholder { color: var(--muted); }

/* ---------- g-kpi : stat tile ---------- */
g-kpi {
  display: block;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 0.9rem 1.1rem;
}
g-kpi .label { color: var(--muted); font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.06em; }
g-kpi .value { font-size: 2rem; line-height: 1.15; margin-top: 0.15rem; }
g-kpi .hint { color: var(--muted); font-size: 0.8rem; margin-top: 0.15rem; }
g-kpi[tone="alert"] .value { color: var(--rust); }
g-kpi[tone="good"] .value { color: var(--pine); }

/* ---------- g-trend : weekly attendance bars ---------- */
g-trend { display: block; position: relative; }
g-trend svg { display: block; width: 100%; height: auto; }
g-trend .bar { fill: var(--ember); }
g-trend .bar:hover { opacity: 0.82; }
g-trend .grid { stroke: var(--line); stroke-width: 1; }
g-trend .grid:not(.baseline) { opacity: 0.55; }
g-trend .axis-label { fill: var(--muted); font-size: 11px; font-family: inherit; }
g-trend .direct-label { fill: var(--ink); font-size: 12px; font-weight: 600; }
g-trend .tip {
  position: absolute;
  pointer-events: none;
  background: var(--ink);
  color: var(--bg);
  font-size: 0.78rem;
  border-radius: 6px;
  padding: 0.25rem 0.55rem;
  transform: translate(-50%, -120%);
  white-space: nowrap;
  opacity: 0;
  transition: opacity 0.1s;
}
g-trend .tip.show { opacity: 1; }

/* ---------- g-health : per-group bar ---------- */
/* The name column fits the real group names ("Lindale(W)/Hideaway"). */
g-health { display: grid; grid-template-columns: 11rem 1fr 3.5rem; gap: 0.7rem; align-items: center; }
g-health .gname { font-size: 0.9rem; overflow-wrap: anywhere; }
g-health .track {
  height: 10px;
  background: var(--line);
  border-radius: 5px;
  overflow: hidden;
}
g-health .fill { height: 100%; background: var(--pine); border-radius: 5px 4px 4px 5px; }
g-health .frac { color: var(--muted); font-size: 0.82rem; text-align: right; }

/* ---------- g-chip : outreach status ---------- */
g-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 600;
  padding: 0.15rem 0.65rem;
  border: 1px solid var(--line);
  color: var(--muted);
}
g-chip[status="flagged"] { color: var(--rust); border-color: var(--rust); }
g-chip[status="assigned"] { color: var(--amber); border-color: var(--amber); }
g-chip[status="contacted"] { color: var(--ember); border-color: var(--ember); }
g-chip[status="reconnected"] { color: var(--pine); border-color: var(--pine); }

/* ---------- g-outreach : call-list row ---------- */
g-outreach {
  display: grid;
  grid-template-columns: 1fr auto auto auto;
  gap: 0.9rem;
  align-items: center;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0.7rem 1rem;
}
g-outreach .who .name { font-weight: 600; }
g-outreach .who .seen { color: var(--muted); font-size: 0.8rem; }
g-outreach .days {
  font-size: 1.3rem;
  color: var(--rust);
  text-align: center;
}
g-outreach .days small { display: block; font-size: 0.65rem; color: var(--muted); }

/* ---------- g-meeting : meeting row ---------- */
g-meeting {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 0.55rem 0.2rem;
  border-bottom: 1px solid var(--line);
}
g-meeting .mwrap { display: flex; flex-direction: column; gap: 0.1rem; }
g-meeting .when { font-size: 0.95rem; }
g-meeting .where { color: var(--muted); font-size: 0.82rem; }
g-meeting .topic { font-weight: 600; font-size: 0.92rem; }
g-meeting .kind-pill { margin-left: 0.45rem; }
g-meeting .count { color: var(--muted); font-size: 0.85rem; }
g-meeting[upcoming] .when { color: var(--ember); font-weight: 600; }

/* ---------- g-intake : add-a-member form ---------- */
g-intake form.intake {
  display: grid;
  gap: 1.05rem;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.4rem;
}
g-intake [hidden] { display: none !important; }
g-intake .field label { display: block; font-size: 0.82rem; font-weight: 600; margin-bottom: 0.3rem; }
g-intake .field .why { color: var(--muted); font-weight: 400; }
g-intake .field input {
  width: 100%;
  font: inherit;
  font-size: 1.1rem;
  color: var(--ink);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0.65rem 0.8rem;
}
/* Above about 46rem the form goes two-up. On a tablet the keyboard eats the bottom
   half of the screen, and a single column of eight fields means the man at the door
   is scrolling a form he cannot see the end of. Laid out left-to-right the whole
   thing fits in what is left above the keys. Four tracks, not two, so the title can
   be narrow and the address can run the full width. */
@media (min-width: 46rem) {
  g-intake form.intake {
    grid-template-columns: repeat(4, 1fr);
    column-gap: 1rem;
  }
  g-intake .field { grid-column: span 2; }
  g-intake .field[data-f="title"] { grid-column: span 1; }
  g-intake .field[data-f="name"] { grid-column: span 3; }
  g-intake .field[data-f="address"] { grid-column: span 3; }
  g-intake .field[data-f="zip"] { grid-column: span 1; }
  g-intake .check, g-intake .actions, g-intake .done { grid-column: 1 / -1; }
}
g-intake .check { display: flex; gap: 0.6rem; align-items: flex-start; font-size: 0.9rem; }
g-intake .check input { width: 1.15rem; height: 1.15rem; margin-top: 0.1rem; accent-color: var(--ember); }
g-intake .check .sub { color: var(--muted); font-size: 0.8rem; }
g-intake .actions { display: flex; gap: 0.8rem; align-items: center; }
g-intake .actions button.primary { font-size: 1.05rem; padding: 0.6rem 1.4rem; }
g-intake .done {
  background: var(--pine-soft);
  border: 1px solid var(--pine);
  color: var(--pine);
  border-radius: 8px;
  padding: 0.8rem 1rem;
  font-weight: 600;
  display: none;
}
g-intake .done.show { display: block; }
g-intake .error { color: var(--rust); font-size: 0.88rem; display: none; }
g-intake .error.show { display: block; }

/* ---------- g-meeting-grid : excel-like schedule editor ---------- */
g-meeting-grid { display: block; }
g-meeting-grid .mg-head, g-meeting-grid .mg-row {
  display: grid;
  grid-template-columns: 8.6rem 5.4rem 9.5rem 10.5rem 1.2fr 1fr 3.6rem 4.6rem;
  gap: 0.45rem;
  align-items: center;
  padding: 0.3rem 0.5rem;
}
g-meeting-grid .mg-head {
  color: var(--muted);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
g-meeting-grid .mg-row {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 8px;
  margin-bottom: 0.35rem;
}
g-meeting-grid input, g-meeting-grid select {
  font: inherit;
  font-size: 0.9rem;
  color: var(--ink);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 0.3rem 0.45rem;
  width: 100%;
}
g-meeting-grid .mg-row.masked { opacity: 0.45; }
g-meeting-grid .mg-row.masked input, g-meeting-grid .mg-row.masked select {
  text-decoration: line-through;
}
g-meeting-grid .mask { font-size: 0.8rem; padding: 0.3rem 0.5rem; }
g-meeting-grid .mg-actions { margin-top: 0.6rem; text-align: right; }

/* ---------- g-quadrant : tap-your-part-of-town grid ---------- */
g-quadrant { display: block; max-width: 22rem; }
g-quadrant .quad-square {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  aspect-ratio: 1;
  border: 2px solid var(--ink);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--card);
}
g-quadrant .quad {
  border: 0;
  border-radius: 0;
  background: transparent;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.25rem;
  cursor: pointer;
  padding: 1rem;
}
/* The two perpendicular lines: right edge of left cells, bottom edge of top cells. */
g-quadrant .quad:nth-child(odd) { border-right: 2px solid var(--ink); }
g-quadrant .quad:nth-child(-n+2) { border-bottom: 2px solid var(--ink); }
g-quadrant .quad:hover { background: var(--ember-soft); }
g-quadrant .quad.picked { background: var(--pine-soft); }
g-quadrant .quad.picked .qlabel { color: var(--pine); }
g-quadrant .qlabel { font-weight: 700; font-size: 1.3rem; letter-spacing: 0.05em; }
g-quadrant .qgroup { color: var(--muted); font-size: 0.82rem; }
g-quadrant .quad.picked .qgroup { color: var(--pine); font-weight: 600; }
g-quadrant .quad-center {
  position: absolute;
  top: 50%; left: 50%;
  width: 12px; height: 12px;
  transform: translate(-50%, -50%);
  background: var(--ember);
  border-radius: 50%;
  pointer-events: none;
}

/* ---------- g-drawer : slide-in-from-the-right panel ---------- */
g-drawer { display: contents; }
g-drawer .scrim {
  position: fixed;
  inset: 0;
  background: rgba(23, 20, 15, 0.34);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.24s ease;
  z-index: 60;
}
g-drawer .panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(30rem, 92vw);
  background: var(--card);
  border-left: 1px solid var(--line);
  box-shadow: -0.6rem 0 2rem rgba(23, 20, 15, 0.22);
  transform: translateX(100%);
  transition: transform 0.28s cubic-bezier(0.32, 0.72, 0, 1);
  z-index: 61;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
g-drawer[open] .scrim { opacity: 1; pointer-events: auto; }
g-drawer[open] .panel { transform: translateX(0); }
g-drawer .drawer-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.2rem 1.3rem 1rem;
  border-bottom: 1px solid var(--line);
}
g-drawer .drawer-title { font-size: 1.25rem; line-height: 1.2; }
g-drawer .drawer-hint { color: var(--muted); font-size: 0.82rem; margin-top: 0.25rem; }
g-drawer .drawer-head .x {
  border: 0;
  background: transparent;
  font-size: 1.6rem;
  line-height: 1;
  padding: 0 0.4rem;
  color: var(--muted);
  flex: 0 0 auto;
}
g-drawer .drawer-body { padding: 1.2rem 1.3rem 2rem; overflow: auto; flex: 1; }
/* Inside a drawer the form is already on its own surface — drop the second card. */
g-drawer .drawer-body g-intake form.intake {
  background: transparent;
  border: 0;
  box-shadow: none;
  padding: 0;
}
/* On a tablet the side panel is the wrong shape. 30rem of a 768pt screen is a
   narrow column with its own scrollbar and fields too small to hit, which is what
   makes editing a man hard on the iPad. Below this width -- or on any touch screen
   -- the drawer takes the whole screen and comes up from the bottom instead of in
   from the side, and its body is centred so it doesn't sprawl on a big tablet. */
@media (max-width: 60rem), (pointer: coarse) {
  g-drawer .panel {
    top: var(--vv-top, 0px);
    left: 0;
    right: 0;
    bottom: auto;
    /* The visual viewport is what is left above the on-screen keyboard, published
       by the component. Without it the Save button sits under the keys. */
    height: var(--vv-height, 100dvh);
    width: 100%;
    border-left: 0;
    box-shadow: none;
    transform: translateY(100%);
  }
  g-drawer[open] .panel { transform: translateY(0); }
  g-drawer .drawer-head {
    padding: 1.1rem 1.4rem 0.9rem;
    padding-top: max(1.1rem, env(safe-area-inset-top));
  }
  g-drawer .drawer-title { font-size: 1.45rem; }
  g-drawer .drawer-hint { font-size: 0.9rem; }
  g-drawer .drawer-head .x { font-size: 2.1rem; padding: 0.2rem 0.6rem; }
  g-drawer .drawer-body {
    width: 100%;
    /* Wide enough for the four-track intake to breathe on a landscape tablet;
       46rem was a portrait-phone measurement applied to a 1024pt screen. */
    max-width: 62rem;
    margin: 0 auto;
    padding: 1.3rem 1.4rem max(2.5rem, env(safe-area-inset-bottom));
    /* Room to scroll the last field clear of the keyboard's top edge. */
    scroll-padding-bottom: 4rem;
    overscroll-behavior: contain;
  }
}

/* Touch targets. 1.02rem is the smallest font iOS will focus without zooming the
   whole page, which on a kiosk leaves the form scrolled somewhere nobody asked for. */
@media (pointer: coarse) {
  g-drawer .drawer-body input,
  g-drawer .drawer-body select,
  g-drawer .drawer-body button {
    min-height: 2.9rem;
    font-size: 1.02rem;
  }
  g-drawer .drawer-body label { font-size: 0.9rem; }
}

@media (prefers-reduced-motion: reduce) {
  g-drawer .scrim, g-drawer .panel { transition: none; }
}

/* ---------- g-login : console sign-in ---------- */
g-login { display: block; max-width: 24rem; }
g-login form.login {
  display: grid;
  gap: 0.95rem;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: var(--shadow);
  padding: 1.8rem;
}
g-login h1 { margin: 0.4rem 0 0; font-size: 1.7rem; }
g-login .sub { color: var(--muted); font-size: 0.85rem; margin: 0; }
g-login .field label { display: block; font-size: 0.82rem; font-weight: 600; margin-bottom: 0.3rem; }
g-login input {
  width: 100%;
  font: inherit;
  font-size: 1.1rem;
  color: var(--ink);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0.65rem 0.8rem;
}
g-login button.primary { width: 100%; font-size: 1.05rem; padding: 0.7rem 1rem; }
g-login button.primary:disabled { opacity: 0.6; cursor: progress; }
g-login .error { color: var(--rust); font-size: 0.88rem; display: none; }
g-login .error.show { display: block; }
g-login .hint {
  color: var(--muted);
  font-size: 0.75rem;
  margin: 0;
  border-top: 1px solid var(--line);
  padding-top: 0.8rem;
}
g-login .pwpath { display: grid; gap: 0.95rem; }
/* The `hidden` attribute has to beat every `display:` rule in this block, including
   the ones written after it -- `.pinpath` once won on source order and the keypad
   showed on every browser, not just the door iPad. */
g-login [hidden] { display: none !important; }
g-login .swap {
  border: 0;
  background: transparent;
  color: var(--ember);
  font-size: 0.85rem;
  padding: 0;
  text-align: center;
  text-decoration: underline;
}

/* PIN path: tap your name, then six digits. Keys are thumb-sized on purpose. */
g-login .pinpath { display: grid; gap: 0.9rem; }
g-login .pinlabel { font-size: 0.82rem; font-weight: 600; margin-bottom: -0.4rem; }
g-login .pinwho { display: flex; flex-wrap: wrap; gap: 0.4rem; }
g-login .pinuser {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  border: 1px solid var(--line);
  background: var(--bg);
  border-radius: 999px;
  padding: 0.25rem 0.7rem 0.25rem 0.3rem;
  font-size: 0.88rem;
}
g-login .pinuser.on { border-color: var(--ember); background: var(--ember-soft); font-weight: 600; }
g-login .pinuser .pavatar {
  width: 1.7rem;
  height: 1.7rem;
  border-radius: 50%;
  background: var(--ember);
  color: #fff8f0;
  display: grid;
  place-items: center;
  font-size: 0.75rem;
  font-weight: 600;
}
g-login .pindots { display: flex; gap: 0.6rem; justify-content: center; padding: 0.2rem 0; }
g-login .pindots .dot {
  width: 0.85rem;
  height: 0.85rem;
  border-radius: 50%;
  border: 1px solid var(--muted);
}
g-login .pindots .dot.on { background: var(--ember); border-color: var(--ember); }
g-login .pinpad { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.4rem; }
g-login .pinpad .key {
  font-size: 1.25rem;
  padding: 0.55rem 0;
  background: var(--bg);
  border-radius: 10px;
}
g-login .pinpad .key:active { background: var(--ember-soft); }
g-login .pinpad .key.wide { grid-column: span 2; }

/* ---------- g-nav : the left rail ---------- */
g-nav {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  flex: 0 0 15rem;
  width: 15rem;
  min-height: 100%;
  padding: 1.1rem 0.8rem 1rem;
  background: color-mix(in srgb, var(--card) 60%, var(--bg));
  border-right: 1px solid var(--line);
}
/* The brand is nowrap by default; in a 15rem rail it has to wrap instead of
   spilling over the content beside it. */
g-nav .navtop { padding: 0.2rem 0.5rem 0; overflow: hidden; }
g-nav .navtop g-brand { flex-wrap: wrap; white-space: normal; }
g-nav .navlist { display: grid; gap: 0.2rem; flex: 1; align-content: start; }
g-nav .navitem {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  width: 100%;
  text-align: left;
  border: 0;
  background: transparent;
  border-radius: 8px;
  padding: 0.62rem 0.7rem;
  font-size: 0.98rem;
  color: var(--ink);
}
g-nav .navitem:hover { background: var(--ember-soft); }
g-nav .navitem.on { background: var(--ember); color: #fff8f0; font-weight: 600; }
g-nav .navicon { width: 1.2rem; text-align: center; }
g-nav .navbadge {
  margin-left: auto;
  background: var(--rust);
  color: #fff8f0;
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 700;
  padding: 0.05rem 0.5rem;
}
g-nav .navitem.on .navbadge { background: #fff8f0; color: var(--ember); }

/* ---------- g-profile : account button + menu (bottom of the rail) ---------- */
g-profile { display: block; position: relative; }
g-profile .pbtn {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  text-align: left;
  border: 0;
  background: transparent;
  border-radius: 10px;
  padding: 0.5rem;
}
g-profile .pbtn:hover { background: var(--ember-soft); }
g-profile .pavatar {
  width: 2.2rem;
  height: 2.2rem;
  border-radius: 50%;
  background: var(--ember);
  color: #fff8f0;
  display: grid;
  place-items: center;
  font-size: 0.9rem;
  font-weight: 600;
  flex: 0 0 auto;
}
g-profile .pwho { display: grid; min-width: 0; }
g-profile .pname {
  font-size: 0.9rem;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
g-profile .prole {
  font-size: 0.7rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
g-profile .pcaret { margin-left: auto; color: var(--muted); font-size: 0.8rem; }
g-profile .pmenu {
  display: none;
  position: absolute;
  bottom: calc(100% + 0.35rem);
  left: 0;
  right: 0;
  min-width: 12rem;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.18);
  padding: 0.35rem;
  z-index: 40;
}
g-profile .pmenu.open { display: block; }
g-profile .pmenu-head {
  color: var(--muted);
  font-size: 0.72rem;
  padding: 0.4rem 0.6rem;
  border-bottom: 1px solid var(--line);
  margin-bottom: 0.25rem;
  overflow-wrap: anywhere;
}
g-profile .pmenu button {
  display: block;
  width: 100%;
  text-align: left;
  border: 0;
  background: transparent;
  border-radius: 7px;
  padding: 0.5rem 0.6rem;
  font-size: 0.9rem;
}
g-profile .pmenu button:hover { background: var(--ember-soft); }
g-profile .pmenu button[data-action="logout"] { color: var(--rust); }

/* ---------- g-meeting-now : what's happening, read from across the room ---------- */
g-meeting-now { display: block; }
g-meeting-now .eyebrow { display: flex; align-items: center; gap: 0.5rem; }
g-meeting-now .now-label {
  color: var(--muted);
  font-size: 0.74rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}
g-meeting-now .now-topic {
  font-size: clamp(1.45rem, 3vw, 2.2rem);
  line-height: 1.12;
  margin-top: 0.3rem;
}
g-meeting-now .now-where {
  margin-top: 0.45rem;
  display: flex;
  gap: 0.7rem;
  align-items: baseline;
  flex-wrap: wrap;
}
g-meeting-now .now-when { color: var(--muted); font-size: 1.02rem; }
g-meeting-now .now-place {
  color: var(--ember);
  background: var(--ember-soft);
  border-radius: 999px;
  padding: 0.14rem 0.75rem;
  font-size: 0.9rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
}

/* ---------- g-attendance-board : how the last meeting went ---------- */
g-attendance-board {
  display: block;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: var(--shadow);
  padding: 1.2rem 1.3rem;
}
g-attendance-board .board-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1rem;
  border-bottom: 1px solid var(--line);
  padding-bottom: 0.8rem;
}
g-attendance-board .board-when { font-size: 1.05rem; font-weight: 600; }
g-attendance-board .board-sub { color: var(--muted); font-size: 0.82rem; }
g-attendance-board .board-count { display: grid; gap: 0.3rem; justify-items: end; }
g-attendance-board .board-nums { font-size: 2.6rem; line-height: 1; }
g-attendance-board .board-nums .of { color: var(--muted); font-size: 1.3rem; }
g-attendance-board .board-groups { display: grid; gap: 0.6rem; margin-top: 0.95rem; }
g-attendance-board .board-row {
  display: grid;
  grid-template-columns: 1.7rem minmax(7rem, 11rem) 1fr 3.4rem;
  gap: 0.7rem;
  align-items: center;
}
g-attendance-board .board-num {
  width: 1.7rem;
  height: 1.7rem;
  border-radius: 6px;
  background: var(--ember-soft);
  color: var(--ember);
  font-size: 0.85rem;
  font-weight: 700;
  display: grid;
  place-items: center;
}
g-attendance-board .board-name {
  font-size: 0.92rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
g-attendance-board .track {
  display: block;
  height: 10px;
  background: var(--line);
  border-radius: 5px;
  overflow: hidden;
}
g-attendance-board .fill { display: block; height: 100%; background: var(--pine); border-radius: 5px; }
g-attendance-board .frac { color: var(--muted); font-size: 0.82rem; text-align: right; }
g-attendance-board .board-empty { color: var(--muted); font-size: 0.88rem; margin: 0; }

/* ---------- g-modes : how a man finds himself on the roster ---------- */
g-modes { display: block; }
g-modes .modewrap {
  display: inline-flex;
  gap: 0.25rem;
  background: color-mix(in srgb, var(--card) 70%, var(--bg));
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0.25rem;
}
g-modes .mode {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  border: 0;
  background: transparent;
  border-radius: 999px;
  padding: 0.45rem 1.05rem;
  font-size: 0.95rem;
  color: var(--muted);
}
g-modes .mode.on { background: var(--ember); color: #fff8f0; font-weight: 600; }

/* ---------- g-gate : token entry ---------- */
g-gate {
  display: block;
  max-width: 26rem;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.4rem;
}
g-gate h2 { margin: 0 0 0.2rem; font-size: 1.3rem; }
g-gate p { color: var(--muted); font-size: 0.88rem; margin: 0 0 0.9rem; }
g-gate form { display: flex; gap: 0.6rem; }
g-gate input {
  flex: 1;
  font: inherit;
  color: var(--ink);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0.5rem 0.7rem;
}

/* ---------- the grade: one vocabulary, both surfaces ----------
   A man's attendance band is a status, so it borrows the status hues rather than
   the team's: green is a man who is here, red is a man to ring. Grey is the
   fourth outcome and deliberately not a colour -- ungraded means there was
   nothing to measure him on, which is not the same as failing.

   Never colour alone: every place a band is shown carries the letter or the
   words too, because roughly one man in twelve cannot tell the green from the red. */
.grade {
  display: inline-grid;
  place-items: center;
  border-radius: 999px;
  padding: 0.12rem 0.6rem;
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.02em;
  white-space: nowrap;
  border: 1.5px solid currentColor;
  flex: 0 0 auto;
}
.grade-regular { color: var(--pine); background: var(--pine-soft); }
.grade-sometimes { color: var(--amber); background: #a8842c1f; }
.grade-rarely { color: var(--rust); background: #9c3a241f; }
.grade-none { color: var(--muted); background: transparent; border-style: dashed; }

/* The stacked band bar: a group's men, worst on the right. */
.bands { display: flex; height: 9px; border-radius: 5px; overflow: hidden; background: var(--line); }
.bands span { display: block; }
.bands .b-regular { background: var(--pine); }
.bands .b-sometimes { background: var(--amber); }
.bands .b-rarely { background: var(--rust); }
.bands .b-none { background: var(--line); }

.tag {
  display: inline-block;
  border-radius: 999px;
  border: 1px solid var(--line);
  color: var(--muted);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  padding: 0.08rem 0.55rem;
  white-space: nowrap;
}
.tag.new { color: var(--ember); border-color: var(--ember); background: var(--ember-soft); }
.tag.away { color: var(--muted); border-style: dashed; }
.tag.risk { color: var(--rust); border-color: var(--rust); }


/* ---------- .tip : the (i) beside a setting ----------
   Hover shows it on a desktop; a tap focuses the button, which shows it on the iPad,
   where a title= tooltip never appears at all. The bubble hangs off the whole label,
   not the (i): at the end of a long label a centred bubble ran off the drawer. */
label:has(> .tip), span:has(> .tip) { position: relative; display: block; }
/* `body button.tip` rather than `.tip`: the drawer's touch-target rule
   (g-drawer .drawer-body button) is more specific than a bare class and turned the
   (i) into a big square button nobody read as a hint. */
body button.tip {
  position: static;
  display: inline-grid;
  place-items: center;
  width: 1.15rem;
  height: 1.15rem;
  min-height: 0;
  margin-left: 0.25rem;
  padding: 0;
  border: 1px solid var(--muted);
  border-radius: 50%;
  background: transparent;
  color: var(--muted);
  font: italic 600 0.72rem/1 Georgia, serif;
  font-size: 0.72rem;
  vertical-align: 0.1em;
  cursor: help;
}
body button.tip:hover, body button.tip:focus { border-color: var(--ember); color: var(--ember); outline: none; }
body button.tip::after {
  content: attr(data-tip);
  position: absolute;
  left: 0;
  right: 0;
  top: calc(100% + 0.3rem);
  padding: 0.6rem 0.75rem;
  border-radius: 8px;
  background: var(--ink);
  color: var(--bg);
  font: normal 400 0.82rem/1.4 system-ui, sans-serif;
  text-align: left;
  white-space: normal;
  box-shadow: var(--shadow);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  z-index: 20;
}
body button.tip:hover::after, body button.tip:focus::after { opacity: 1; visibility: visible; }
@media (pointer: coarse) {
  body button.tip { width: 1.5rem; height: 1.5rem; min-height: 0; font-size: 0.85rem; }
}
