/*
  Enki Teams portal stylesheet. TP1 reference, applied to the live portal by TP2.

  Two color palettes. Light is the default on :root, even when the system is
  dark, because Merl asked for light by default. The dark palette sits under
  :root[data-theme="dark"] and is TP1's look, unchanged. A small script in
  each page's head sets data-theme from localStorage before first paint; when
  storage fails the attribute stays "light".

  Both palettes use the same token names. The names come from the website's
  dark palette (website/index.html), so read them by role, not by shade: in
  light mode --ink is the near-white page, and --text is the dark ink.

  Every color in this file is a custom property in one of the two token
  blocks. Nothing below them writes a color literal.

  Plain CSS: no framework, no build step, no external font. The font stack
  is the website's own.
*/

/* ---------- Light palette (default) ---------- */

:root {
  color-scheme: light;

  /* Base. Measured ratios are in README.md. */
  --ink: #F4F6F8;                      /* page background */
  --panel: #FFFFFF;                    /* cards, tables */
  --surface: #EEF2F5;                  /* raised panels, meter track */
  --gold: #F0C040;                     /* primary button fill, same gold as dark */
  --teal: #2E7D8C;                     /* secondary button border: 4.7:1 on white */
  --teal-bright: #1F6B79;              /* links, kicker: 6.1:1 on white, 5.6:1 on the page */
  --text: #0A1520;                     /* the Enki navy as ink: 18.4:1 on white */
  --mist: #56666F;                     /* secondary text: 6.0:1 on white, 5.3:1 on --surface */
  --line: rgba(10, 21, 32, .10);

  --gold-ink: #14262E;                 /* text on gold: 9.2:1 */
  --topbar-bg: rgba(255, 255, 255, .92);

  /* Gold on white is only 1.7:1, so light mode splits gold by job. */
  --gold-text: #8A6410;                /* gold words (Owner, Waiting for review): 5.4:1 on white */
  --gold-line: #A97C10;                /* gold marks (active tab, focus, dots): 3.8:1 on white */
  --gold-edge: #D9A62A;                /* hairline around the gold button so it holds its shape on white */
  --meter-fill: #D9A62A;

  --gold-hover: #E8B52F;
  --gold-tint: rgba(240, 192, 64, .16);
  --gold-border: rgba(169, 124, 16, .45);
  --teal-tint: rgba(46, 125, 140, .10);
  --line-strong: rgba(10, 21, 32, .16);
  --line-input: #7D8B93;               /* 3.5:1 on white, 3.2:1 on the page */
  --placeholder: #66757E;              /* 4.8:1 on white */
  --row-hover: rgba(10, 21, 32, .035);
  --input-bg: #FFFFFF;
  --input-readonly-bg: var(--surface);
  --track-bg: var(--surface);          /* segmented control track */
  --selected-bg: #FFFFFF;              /* the chosen segment */
  --shadow: 0 1px 2px rgba(10, 21, 32, .05);
  --danger: #E05252;                   /* dots and borders: 3.8:1 on white */
  --danger-text: #B93A3A;              /* 5.6:1 on white */
  --danger-tint: rgba(224, 82, 82, .08);
  --danger-border: rgba(185, 58, 58, .45);
  --success: #1E7A47;                  /* text and dots: 5.3:1 on white */
  --success-tint: rgba(30, 122, 71, .08);
  --success-border: rgba(30, 122, 71, .40);
  --focus: var(--gold-line);

  /* Sign-in provider buttons, matched to Google's light "outline" button */
  --provider-bg: #FFFFFF;
  --provider-border: #747775;
  --provider-text: #1F1F1F;
}

/* ---------- Dark palette (TP1, unchanged) ---------- */

:root[data-theme="dark"] {
  color-scheme: dark;

  /* Website tokens, verbatim from website/index.html */
  --ink: #0A1520;
  --panel: #0E1E2C;
  --surface: #152A3B;
  --gold: #F0C040;
  --teal: #2E7D8C;
  --teal-bright: #4A9AAD;
  --text: #F5F7F8;
  --mist: #9DAEB6;
  --line: rgba(157, 174, 182, .16);

  /* Values the website writes inline, named here */
  --gold-ink: #14262E;                 /* text on gold, website .cta and .badge */
  --topbar-bg: rgba(10, 21, 32, .94);  /* website sticky nav */

  /* On the dark page one gold does every job. */
  --gold-text: var(--gold);
  --gold-line: var(--gold);
  --gold-edge: transparent;           /* TP1's border: none needed on the dark page */
  --meter-fill: var(--gold);

  /* Portal additions. Danger and success come from the Enki app tokens. */
  --gold-hover: #F5CF63;
  --gold-tint: rgba(240, 192, 64, .08);
  --gold-border: rgba(240, 192, 64, .5);
  --teal-tint: rgba(46, 125, 140, .16);
  --line-strong: rgba(157, 174, 182, .28);
  --line-input: #62727B;               /* 3:1 against --ink and --panel, for form controls */
  --placeholder: #7F9099;              /* 5.5:1 on --ink */
  --row-hover: rgba(157, 174, 182, .05);
  --input-bg: var(--ink);
  --input-readonly-bg: var(--panel);
  --track-bg: var(--ink);
  --selected-bg: var(--surface);
  --shadow: none;
  --danger: #E05252;
  --danger-text: #F07A7A;              /* #E05252 is 4.4:1 on --panel; this is 6.3:1 */
  --danger-tint: rgba(224, 82, 82, .12);
  --danger-border: rgba(224, 82, 82, .55);
  --success: #4CAF76;
  --success-tint: rgba(76, 175, 118, .12);
  --success-border: rgba(76, 175, 118, .45);
  --focus: var(--gold);

  /* Sign-in provider buttons, matched to Google's filled_black button */
  --provider-bg: #131314;
  --provider-border: #8E918F;
  --provider-text: #E3E3E3;
}

/* ---------- Type, shape, space (both themes) ---------- */

:root {
  --font: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text", Inter, system-ui, sans-serif;
  --radius-sm: 8px;
  --radius: 11px;
  --radius-lg: 16px;
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --page-max: 1120px;
  --gutter: 20px;
}

@media (max-width: 480px) {
  :root { --gutter: 16px; }
}

/* ---------- Base ---------- */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--ink);
  color: var(--text);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.55;
}

main { flex: 1 0 auto; }

a { color: var(--teal-bright); text-underline-offset: 3px; }
a:hover { color: var(--text); }

h1, h2, h3 { margin: 0; line-height: 1.2; letter-spacing: -.3px; }
p { margin: 0; }

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

.skip-link {
  position: absolute;
  left: -9999px;
  top: 12px;
  z-index: 100;
  padding: 8px 14px;
  border-radius: var(--radius-sm);
  background: var(--gold);
  color: var(--gold-ink);
  font-weight: 700;
  text-decoration: none;
}
.skip-link:focus { left: 16px; }

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ---------- Type ---------- */

.kicker {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 2.2px;
  text-transform: uppercase;
  color: var(--teal-bright);
}

.label {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--mist);
}

.page-title { font-size: 26px; font-weight: 700; letter-spacing: -.5px; }
.section-title { font-size: 17px; font-weight: 650; }
.muted { color: var(--mist); }
.small { font-size: 13.5px; }
.num { font-variant-numeric: tabular-nums; }
.hint { font-size: 13px; color: var(--mist); }

/* Spacing helpers */
.mt-2 { margin-top: var(--space-2); }
.mt-3 { margin-top: var(--space-3); }
.mt-4 { margin-top: var(--space-4); }
.mt-5 { margin-top: var(--space-5); }

/* ---------- Top bar and tabs ---------- */

.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  background: var(--topbar-bg);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}

.topbar-inner {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 12px var(--gutter) 2px;
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 52px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
  color: var(--text);
  text-decoration: none;
  font-size: 16px;
  font-weight: 700;
  letter-spacing: -.2px;
}
.brand:hover { color: var(--text); }
.brand img { display: block; width: 29px; height: 22px; }
/* On the narrowest phones the mark alone carries the brand, so the team name
   has room. The word stays in the accessibility tree as the link's name. */
@media (max-width: 400px) {
  .brand > span {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
}

.brand-sep { flex: none; width: 1px; height: 20px; background: var(--line-strong); }

.team-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 15px;
  font-weight: 600;
}

.account {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 10px;
  flex: none;
}
.account-email { font-size: 13px; color: var(--mist); }

@media (max-width: 640px) {
  .account-email { display: none; }
}

/*
  Theme toggle. The script in each page's head flips data-theme on <html>,
  stores the choice, and rewrites the button's label. CSS shows the icon of
  the theme the button switches TO: a moon on the light page, a sun on the
  dark page. With no script the button shows a moon and does nothing, and
  the page stays light.
*/
.theme-toggle {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 34px;
  height: 34px;
  padding: 0;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--mist);
  cursor: pointer;
  transition: background-color .15s, color .15s;
}
.theme-toggle:hover { background: var(--row-hover); color: var(--text); }
.theme-toggle svg { display: block; width: 18px; height: 18px; }
.theme-toggle .icon-sun { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-sun { display: block; }
:root[data-theme="dark"] .theme-toggle .icon-moon { display: none; }

/* Sign-in and join have no top bar, so the toggle sits alone at the top right. */
.auth-top {
  display: flex;
  justify-content: flex-end;
  width: 100%;
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 12px var(--gutter) 0;
}

.tabs-inner {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 0 var(--gutter);
  display: flex;
  gap: 24px;
  overflow-x: auto;
  scrollbar-width: none;
}
.tabs-inner::-webkit-scrollbar { display: none; }

.tabs a {
  flex: none;
  padding: 12px 0 11px;
  border-bottom: 2px solid transparent;
  color: var(--mist);
  font-size: 14px;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
}
.tabs a:hover { color: var(--text); }
.tabs a:focus-visible { outline-offset: -2px; }
/* aria-current="page" marks the tab's own page; aria-current="true" marks the parent tab of a detail page (member.html). */
.tabs a[aria-current] { color: var(--text); border-bottom-color: var(--gold-line); }

/* Six tabs fit a 375 px phone at this size. Narrower phones scroll the strip
   sideways; the fade on the right edge says there is more. */
@media (max-width: 480px) {
  .tabs { position: relative; }
  .tabs-inner { gap: 10px; }
  .tabs a { font-size: 13px; }
  .tabs::after {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: var(--gutter);
    background: linear-gradient(to right, transparent, var(--topbar-bg));
    pointer-events: none;
  }
}

/* Under 400px the gap alone is not enough room for the tab row; shrink it
   further so the strip keeps a few pixels of breathing room. */
@media (max-width: 400px) {
  .tabs-inner { gap: 6px; }
}

/* ---------- Page layout ---------- */

.page {
  width: 100%;
  max-width: var(--page-max);
  margin: 0 auto;
  padding: var(--space-6) var(--gutter) var(--space-7);
}

.page-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-5);
}
.page-head p { margin-top: 6px; max-width: 62ch; color: var(--mist); }

.page-actions { display: flex; flex-wrap: wrap; gap: var(--space-3); }

/* Detail pages (member.html): a way back to the parent list, and a header for one record. */
.crumbs { margin-bottom: var(--space-3); font-size: 13.5px; }
.crumbs a {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: var(--mist);
  font-weight: 600;
  text-decoration: none;
}
.crumbs a:hover { color: var(--text); }
.crumbs svg { width: 14px; height: 14px; flex: none; }

.title-wrap { overflow-wrap: anywhere; }

.record-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 18px;
  margin-top: 10px;
  font-size: 14px;
  color: var(--mist);
}
.record-meta strong { color: var(--text); font-weight: 600; }

/* A status word with its dot, for places where the status is not pinned by a test. */
.status { display: inline-flex; align-items: center; gap: 8px; color: var(--text); font-weight: 600; }
.status::before { content: ""; flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--dot, var(--mist)); }
.status-active { --dot: var(--success); }
.status-invited { --dot: var(--gold-line); }

.section { margin-top: var(--space-6); }
.section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}

.grid-2 {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  gap: var(--space-4);
  align-items: start;
}
@media (max-width: 860px) {
  .grid-2 { grid-template-columns: minmax(0, 1fr); }
}

/* ---------- Cards and stats ---------- */

.card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  box-shadow: var(--shadow);
}
.card + .card { margin-top: var(--space-4); }

.card-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2) var(--space-3);
  margin-bottom: var(--space-4);
}
.card-title { font-size: 17px; font-weight: 650; }
.card-sub { font-size: 14px; color: var(--mist); }

@media (max-width: 480px) {
  .card { padding: 18px var(--space-4); }
}

.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-4);
}

.stat {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 20px 22px;
  box-shadow: var(--shadow);
}
.stat-value {
  margin: 6px 0 8px;
  font-size: 34px;
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -1px;
  font-variant-numeric: tabular-nums;
}
.stat-note { font-size: 13.5px; color: var(--mist); }
.stat .meter { margin-bottom: 10px; }

/* Four numbers in a row (member page). Two by two on a phone, not four stacked. */
.stats-4 { grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); }
@media (max-width: 480px) {
  .stats-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); }
  .stats-4 .stat { padding: 16px; }
  .stats-4 .stat-value { font-size: 28px; }
}

.facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--space-4) var(--space-5);
  margin: 0;
}
.facts dt { font-size: 11.5px; font-weight: 600; letter-spacing: 1.6px; text-transform: uppercase; color: var(--mist); }
.facts dd { margin: 4px 0 0; font-size: 17px; font-weight: 650; font-variant-numeric: tabular-nums; }

/* ---------- Meter and usage bar ---------- */

.meter {
  height: 6px;
  border-radius: 999px;
  background: var(--surface);
  overflow: hidden;
}
.meter > span { display: block; height: 100%; border-radius: inherit; background: var(--meter-fill); }

.bar-cell { display: flex; align-items: center; gap: var(--space-3); min-width: 180px; }
.bar-cell .num { width: 3ch; text-align: right; flex: none; font-weight: 650; }
.bar-cell .meter { flex: 1; height: 8px; }

/* ---------- Buttons ---------- */

/*
  Member-row hooks. The members script and the HTML tests pin three class
  attributes exactly: class="update-role", class="remove-member", and
  class="give-captures". Those buttons cannot carry .btn, so they are listed
  beside the .btn rules below and get the same look from their own names.
*/
.btn,
.update-role,
.give-captures,
.remove-member {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 42px;
  padding: 10px 18px;
  border: 1px solid transparent;
  border-radius: var(--radius);
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 14.5px;
  font-weight: 650;
  line-height: 1.2;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color .15s, border-color .15s, color .15s;
}
.btn svg { width: 16px; height: 16px; flex: none; }
.btn[disabled], .update-role[disabled], .give-captures[disabled], .remove-member[disabled] { opacity: .5; cursor: not-allowed; }

/* One gold primary per screen: the one thing to tap. */
.btn-primary { background: var(--gold); border-color: var(--gold-edge); color: var(--gold-ink); }
.btn-primary:hover { background: var(--gold-hover); border-color: var(--gold-edge); color: var(--gold-ink); }

.btn-secondary, .update-role, .give-captures { border-color: var(--teal); color: var(--text); }
.btn-secondary:hover, .update-role:hover, .give-captures:hover { background: var(--teal-tint); border-color: var(--teal-bright); color: var(--text); }

.btn-ghost { color: var(--mist); }
.btn-ghost:hover { background: var(--row-hover); color: var(--text); }

.btn-danger, .remove-member { border-color: var(--danger-border); color: var(--danger-text); }
.btn-danger:hover, .remove-member:hover { background: var(--danger-tint); border-color: var(--danger); color: var(--danger-text); }

.btn-sm,
.update-role,
.give-captures,
.remove-member {
  min-height: 34px;
  padding: 6px 12px;
  border-radius: var(--radius-sm);
  font-size: 13.5px;
}
.btn-block { width: 100%; }

/* ---------- Forms ---------- */

.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.field > span { font-size: 13px; font-weight: 600; color: var(--mist); }
.fieldset-plain { min-width: 0; margin: 0; padding: 0; border: 0; }
.fieldset-plain > legend { padding: 0; }
.field-legend { margin-bottom: 6px; font-size: 13px; font-weight: 600; color: var(--mist); }

.input,
.select {
  width: 100%;
  height: 42px;
  padding: 9px 12px;
  border: 1px solid var(--line-input);
  border-radius: var(--radius-sm);
  background-color: var(--input-bg);
  color: var(--text);
  font: inherit;
  font-size: 15px;
}
.input::placeholder { color: var(--placeholder); }
.input:hover, .select:hover { border-color: var(--mist); }
.input:focus-visible, .select:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; border-color: var(--focus); }
.input[readonly] { background-color: var(--input-readonly-bg); color: var(--mist); }

/* A chevron drawn with gradients, so the select arrow uses a token color. */
.select {
  -webkit-appearance: none;
  appearance: none;
  padding-right: 36px;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--mist) 50%),
    linear-gradient(135deg, var(--mist) 50%, transparent 50%);
  background-position: calc(100% - 19px) 55%, calc(100% - 14px) 55%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

.input-sm, .select-sm { height: 34px; padding-top: 5px; padding-bottom: 5px; font-size: 14px; }

.form-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-3);
}
.form-row .grow { flex: 1 1 240px; }
.form-row .fixed { flex: 0 1 160px; }
.form-row p { margin: 0; }

@media (max-width: 560px) {
  .form-row > * { flex: 1 1 100%; }
  .form-row .btn { width: 100%; }
}

.filters {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: var(--space-3);
  align-items: end;
}
.filters-actions { display: flex; gap: var(--space-2); }

.divider {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin: var(--space-5) 0;
  color: var(--mist);
  font-size: 13px;
}
.divider::before, .divider::after { content: ""; flex: 1; height: 1px; background: var(--line); }

.copy-field { display: flex; gap: var(--space-2); }
.copy-field .input { flex: 1; min-width: 0; font-size: 14px; }

/* Choice cards: radio inputs styled as selectable cards (plan picker). */
.choices {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: var(--space-3);
}
.choice {
  position: relative;
  display: block;
  padding: 16px 16px 16px 46px;
  border: 1px solid var(--line-input);
  border-radius: var(--radius);
  background: var(--input-bg);
  cursor: pointer;
}
.choice input { position: absolute; left: 16px; top: 18px; width: 18px; height: 18px; margin: 0; accent-color: var(--gold-line); }
.choice:hover { border-color: var(--mist); }
.choice:has(input:checked) { border-color: var(--gold-line); background: var(--gold-tint); }
.choice:has(input:focus-visible) { outline: 2px solid var(--focus); outline-offset: 2px; }
.choice-title { display: block; font-weight: 650; }
.choice-price { display: block; margin-top: 2px; font-variant-numeric: tabular-nums; }
.choice-note { display: block; margin-top: 6px; font-size: 13.5px; color: var(--mist); }

/* Segmented control: radio inputs styled as a two-way switch (interval). */
.segmented {
  display: inline-flex;
  gap: 4px;
  padding: 4px;
  border: 1px solid var(--line-input);
  border-radius: var(--radius);
  background: var(--track-bg);
}
.segmented label { position: relative; cursor: pointer; }
.segmented input { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; }
.segmented span {
  display: block;
  padding: 5px 16px;
  border-radius: var(--radius-sm);
  color: var(--mist);
  font-size: 14px;
  font-weight: 600;
}
.segmented input:checked + span { background: var(--selected-bg); color: var(--text); box-shadow: inset 0 0 0 1px var(--line-strong); }
.segmented input:focus-visible + span { outline: 2px solid var(--focus); outline-offset: 1px; }

/* ---------- Tables ---------- */

/* position: relative keeps absolutely positioned children (the visually
   hidden "Actions" header) inside the scroll box, so they never widen the page. */
.table-wrap {
  position: relative;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/* A table wider than a phone scrolls sideways; the same right-edge fade
   .tabs::after already uses says there is more to see. */
@media (max-width: 480px) {
  .table-wrap::after {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 24px;
    background: linear-gradient(to right, transparent, var(--panel));
    pointer-events: none;
  }
}

.table { width: 100%; border-collapse: collapse; font-size: 14.5px; }
.table th,
.table td {
  padding: 12px 16px;
  border-top: 1px solid var(--line);
  text-align: left;
  vertical-align: middle;
}
.table thead th {
  border-top: 0;
  border-bottom: 1px solid var(--line-strong);
  padding-top: 14px;
  padding-bottom: 10px;
  color: var(--mist);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  white-space: nowrap;
}
.table thead + tbody tr:first-child td { border-top: 0; }
.table tbody tr:hover { background: var(--row-hover); }
.table .num { text-align: right; font-variant-numeric: tabular-nums; }
.table .nowrap { white-space: nowrap; }
.table .strong { font-weight: 600; }
.table .cell-md { min-width: 150px; }
.table .actions { text-align: right; white-space: nowrap; }
/* A row with an open disclosure (Manage, Details) reads from its first line. */
.table tr:has(details[open]) > td { vertical-align: top; --dot-y: 23px; }

.table-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: var(--space-3);
  font-size: 13.5px;
  color: var(--mist);
}

.person-name { display: block; font-weight: 600; }
.person-sub { display: block; font-size: 13px; color: var(--mist); }

/* Initials in off-white, never gold: a standing brand call for avatar circles. */
.avatar {
  display: grid;
  place-items: center;
  flex: none;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 1px solid var(--line-strong);
  background: var(--teal-tint);
  color: var(--text);
  font-size: 12.5px;
  font-weight: 650;
  letter-spacing: .3px;
}

/*
  Members status column. The HTML tests pin the literal <td>active</td> and
  <td>invited</td>, so the status cell carries no class and no inner markup.
  The row's data-status picks the dot color and the column position finds
  the cell. Keep the status column third in both member tables.
*/
/* Tighter side padding than the base .table so the six-column Members
   table fits the 1078px card at a 1280px viewport without a horizontal
   scroll. */
.members-table th,
.members-table td {
  padding-left: 12px;
  padding-right: 12px;
}
.members-table tbody td:nth-child(3) {
  padding-left: 28px;
  background-image: radial-gradient(circle at 16px var(--dot-y, 50%), var(--dot, var(--mist)) 0 3.5px, transparent 4.5px);
  background-repeat: no-repeat;
  white-space: nowrap;
}
.members-table tbody td:nth-child(3)::first-letter { text-transform: uppercase; }
.members-table tr[data-status="active"] { --dot: var(--success); }
/* The first cell is the plain address: tests pin data-membership-id="..."><td>address</td>. */
.members-table tbody td:first-child { font-weight: 600; }
/*
  TP5: on an active row the address is a link to the member page. The link
  wraps the text inside the cell, so the cell still holds exactly the address
  text, but the markup becomes <td><a ...>address</a></td>. README.md lists
  the five members_test.go assertions TP5 must update. Pending rows stay plain.
*/
.member-link { color: var(--teal-bright); text-decoration: none; }
.member-link:hover { color: var(--text); text-decoration: underline; }
/* An unused link invite has no address, so its first cell is empty. Label it. */
.members-table tbody td:first-child:empty::before { content: "Invite link, not used yet"; color: var(--mist); font-weight: 500; }
.members-table tr[data-status="invited"] { --dot: var(--gold-line); }
.pending-table tbody td:nth-child(3) { white-space: normal; min-width: 220px; max-width: 320px; color: var(--mist); }

/* ---------- Row menu (Manage), a no-script disclosure ---------- */

.row-menu { display: inline-block; text-align: right; }
.row-menu > summary { list-style: none; }
.row-menu > summary::-webkit-details-marker { display: none; }
.row-menu > summary::after {
  content: "";
  width: 6px;
  height: 6px;
  margin-left: 2px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
}
.row-menu[open] > summary::after { transform: translateY(1px) rotate(-135deg); }

.row-panel {
  display: grid;
  gap: var(--space-4);
  min-width: 300px;
  margin-top: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--surface);
  text-align: left;
  white-space: normal;
}
.row-panel-group,
.row-panel > .give-captures-form { display: grid; gap: var(--space-2); margin: 0; }
.row-panel-group > .btn,
.row-panel-group > .remove-member { justify-self: start; }
.row-panel > * + * { padding-top: var(--space-4); border-top: 1px solid var(--line); }
.inline-controls { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--space-2); }
.inline-controls .field { flex: 1 1 140px; }
.inline-controls .select { width: auto; flex: 1 1 120px; }

/* ---------- Badges ---------- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 10px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  color: var(--text);
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.5;
  white-space: nowrap;
}
.badge-owner { border-color: var(--gold-border); color: var(--gold-text); }
.badge-admin { border-color: var(--teal); color: var(--teal-bright); }
.badge-member { color: var(--mist); }
.badge-success { border-color: var(--success-border); color: var(--success); }
.badge-warn { border-color: var(--gold-border); color: var(--gold-text); }
.badge-danger { border-color: var(--danger-border); color: var(--danger-text); }

/* Member status pill (badge badge-{{.Status}}), reusing the same tokens
   .status-active and .status-invited use, so active/invited/removed draw
   their real colors instead of every status falling through to gray. */
.badge-active { border-color: var(--success-border); color: var(--success); }
.badge-invited { border-color: var(--gold-border); color: var(--gold-text); }
.badge-removed { border-color: var(--danger-border); color: var(--danger-text); }

.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip {
  padding: 2px 9px;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--mist);
  font-size: 12.5px;
  font-weight: 600;
  white-space: nowrap;
}

/* ---------- Alerts ---------- */

/* .error is the login page's error paragraph: tests pin <p class="error">. */
.alert,
.error {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--surface);
  font-size: 14px;
  text-align: left;
}
.alert::before,
.error::before {
  content: "";
  flex: none;
  width: 8px;
  height: 8px;
  margin-top: 7px;
  border-radius: 50%;
  background: var(--alert-dot, var(--mist));
}
.alert-error, .error { --alert-dot: var(--danger); border-color: var(--danger-border); background: var(--danger-tint); }
.alert-success { --alert-dot: var(--success); border-color: var(--success-border); background: var(--success-tint); }
.alert-info { --alert-dot: var(--teal-bright); border-color: var(--teal); background: var(--teal-tint); }
.alert-warn { --alert-dot: var(--gold-line); border-color: var(--gold-border); background: var(--gold-tint); }
.alert:empty { display: none; }

/* ---------- Activity list ---------- */

.activity { margin: 0; padding: 0; list-style: none; }
.activity li {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: 14px 0;
  border-top: 1px solid var(--line);
}
.activity li:first-child { border-top: 0; padding-top: 0; }
.activity li:last-child { padding-bottom: 0; }
.activity-body { flex: 1; min-width: 0; }
.activity-meta { display: block; margin-top: 2px; font-size: 13px; color: var(--mist); }

/* ---------- Capture details disclosure ---------- */

.more { margin-top: 6px; }
.more > summary {
  display: inline-block;
  color: var(--teal-bright);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}
.more > summary::-webkit-details-marker { display: none; }
.more > summary:hover { color: var(--text); }
.more-body {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 6px 14px;
  min-width: 280px;
  max-width: 400px;
  margin: 10px 0 2px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font-size: 13.5px;
  white-space: normal;
}
.more-body dt { color: var(--mist); }
.more-body dd { margin: 0; overflow-wrap: anywhere; }

/* ---------- Empty state ---------- */

.empty { padding: 48px 24px; text-align: center; }
.empty img { display: block; width: 44px; height: 33px; margin: 0 auto 16px; opacity: .55; }
.empty h2 { font-size: 18px; font-weight: 650; }
.empty p { max-width: 46ch; margin: 8px auto 20px; color: var(--mist); }

/* ---------- Sign-in and join (centered card) ---------- */

.auth {
  flex: 1 0 auto;
  display: grid;
  place-items: center;
  align-content: center;
  padding: 48px var(--gutter);
}
.auth-card {
  width: 100%;
  max-width: 420px;
  padding: 36px 32px 32px;
  border: 1px solid var(--line);
  border-radius: 20px;
  background: var(--panel);
  box-shadow: var(--shadow);
  text-align: center;
}
.auth-card > img { display: block; width: 64px; height: 48px; margin: 0 auto 22px; }
.auth-card h1 { font-size: 24px; font-weight: 700; letter-spacing: -.5px; }
.auth-card .lead { margin: 10px auto 26px; max-width: 34ch; color: var(--mist); }
.auth-card .error, .auth-card .alert { margin-bottom: 20px; }
.auth-stack { display: grid; gap: var(--space-3); justify-items: center; }
.auth-note { margin-top: 24px; padding-top: 20px; border-top: 1px solid var(--line); font-size: 13.5px; color: var(--mist); }
.auth-note strong { color: var(--text); font-weight: 600; }

@media (max-width: 480px) {
  .auth { padding-top: 32px; }
  .auth-card { padding: 28px 20px 24px; }
}

.btn-provider {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  max-width: 320px;
  min-height: 44px;
  padding: 10px 16px;
  border: 1px solid var(--provider-border);
  border-radius: 4px;
  background: var(--provider-bg);
  color: var(--provider-text);
  font: inherit;
  font-size: 15px;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}
.btn-provider:hover { color: var(--provider-text); border-color: var(--provider-text); }
.btn-provider svg { width: 20px; height: 20px; flex: none; }

/* ---------- Manage card (member page) ---------- */

/* The member page's owner controls, laid out side by side. It reuses the
   Manage panel's groups and the three self-styled member-row hooks. */
.manage {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: var(--space-5);
}
.manage > .row-panel-group,
.manage > .give-captures-form { display: grid; gap: var(--space-2); align-content: start; margin: 0; }
.manage > .row-panel-group > .remove-member { justify-self: start; }

/* ---------- Events list (events.html) ---------- */

/*
  One <details> per event: the summary is the row, the body is the
  per-member breakdown. No script. On a phone the four columns fold into two
  lines, so the list never scrolls sideways.
*/
.event-list {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  overflow: hidden;
}

.event-list-head,
.event-row > summary {
  display: grid;
  grid-template-columns: minmax(0, 2.4fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) 16px;
  grid-template-areas: "name date members count chev";
  align-items: center;
  gap: var(--space-4);
  padding: 14px 20px;
}

.event-list-head {
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line-strong);
  color: var(--mist);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 1.4px;
  text-transform: uppercase;
}
.event-list-head .event-count { text-align: right; }

.event-row + .event-row { border-top: 1px solid var(--line); }
.event-row > summary { list-style: none; cursor: pointer; }
.event-row > summary::-webkit-details-marker { display: none; }
.event-row > summary:hover { background: var(--row-hover); }
.event-row > summary:focus-visible { outline-offset: -2px; }
.event-row > summary::after {
  content: "";
  grid-area: chev;
  justify-self: center;
  width: 7px;
  height: 7px;
  border-right: 1.5px solid var(--mist);
  border-bottom: 1.5px solid var(--mist);
  transform: translateY(-2px) rotate(45deg);
}
.event-row[open] > summary::after { transform: translateY(2px) rotate(-135deg); }

.event-name { grid-area: name; font-weight: 650; overflow-wrap: anywhere; }
.event-place { display: block; font-size: 13px; font-weight: 400; color: var(--mist); }
.event-date { grid-area: date; white-space: nowrap; }
.event-members { grid-area: members; white-space: nowrap; }
.event-count { grid-area: count; text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.event-count strong { font-weight: 700; }

.event-body { padding: 2px 20px 20px; }
.event-body > .label { display: block; padding-top: 14px; border-top: 1px solid var(--line); }

.breakdown { margin: 6px 0 0; padding: 0; list-style: none; }
.breakdown li {
  display: grid;
  grid-template-columns: minmax(0, 17rem) minmax(0, 1fr) 4ch;
  grid-template-areas: "who bar n";
  align-items: center;
  gap: 6px var(--space-4);
  padding: 9px 0;
}
.breakdown li + li { border-top: 1px solid var(--line); }
.breakdown .who { grid-area: who; overflow-wrap: anywhere; }
.breakdown .meter { grid-area: bar; height: 8px; }
.breakdown .n { grid-area: n; text-align: right; font-weight: 650; font-variant-numeric: tabular-nums; }

@media (max-width: 640px) {
  .event-list-head { display: none; }
  .event-row > summary {
    grid-template-columns: auto auto minmax(0, 1fr) 16px;
    grid-template-areas:
      "name name name chev"
      "date members count chev";
    gap: 4px var(--space-3);
    padding: 14px 16px;
  }
  .event-date, .event-members { font-size: 13.5px; color: var(--mist); }
  .event-body { padding: 2px 16px 18px; }
  .breakdown li {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "who n" "bar bar";
  }
}

/* ---------- Footer ---------- */

.site-footer {
  border-top: 1px solid var(--line);
  color: var(--mist);
  font-size: 12.5px;
}
.site-footer-inner {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 20px var(--gutter) 28px;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-3);
}
.site-footer nav { display: flex; flex-wrap: wrap; gap: var(--space-4); }
.site-footer a { color: var(--mist); text-decoration: none; }
.site-footer a:hover { color: var(--text); }

/* ---------- Mock only. TP2 does not port anything below this line. ---------- */

.mock-state {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin: var(--space-7) 0 var(--space-4);
  color: var(--mist);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 1.4px;
  text-transform: uppercase;
}
.mock-state::before, .mock-state::after { content: ""; flex: 1; border-top: 1px dashed var(--line-strong); }
.auth > .mock-state { width: 100%; max-width: 420px; }

/* ---------- Leaderboard (PL1) ---------- */

.lb-picker { display: flex; flex-wrap: wrap; gap: var(--space-2, 8px); margin: 0 0 var(--space-3, 12px); }
.lb-picker a { padding: 6px 12px; border: 1px solid var(--line-strong); border-radius: 999px; color: var(--text); text-decoration: none; font-size: 13.5px; }
.lb-picker a:hover { background: var(--row-hover); }
.lb-picker a[aria-current] { background: var(--gold-tint); border-color: var(--gold-border); font-weight: 650; }
.leaderboard-table .lb-rank { width: 4ch; font-variant-numeric: tabular-nums; font-weight: 650; color: var(--mist); }
.leaderboard-table .lb-you { background: var(--teal-tint); }
.lb-idle { margin: 0; padding-left: 1.2em; }

/* ---------- Venue screen (AV-S3) ---------- */

/*
  A TV in a room: always the dark palette (the page sets data-theme="dark"
  with no script), type sized to read from across the room at 1920 by 1080,
  and no portal chrome. The first three rows are larger than the rest. The
  tokens below name the few values the dark palette does not already hold.
*/
body.venue {
  --venue-row: var(--panel);
  --venue-row-top: var(--surface);
  margin: 0;
  background: var(--ink);
  color: var(--text);
  min-height: 100vh;
}
.venue-screen {
  box-sizing: border-box;
  max-width: 1600px;
  margin: 0 auto;
  padding: 3vh 4vw 2vh;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  gap: 1.6vh;
}
.venue-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.6em 1.2em; }
.venue-brand { display: flex; align-items: center; gap: 12px; font-size: 28px; font-weight: 700; color: var(--mist); }
.venue-team { margin: 0; font-size: clamp(34px, 4.4vw, 76px); font-weight: 700; letter-spacing: -0.5px; line-height: 1.05; }
.venue-metric { margin: 0 0 0 auto; font-size: clamp(18px, 1.8vw, 32px); font-weight: 600; letter-spacing: 1px; text-transform: uppercase; color: var(--gold); }
.venue-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.8vh;
  flex: none;
  align-content: start;
}
.venue-row {
  display: grid;
  grid-template-columns: 2.2em minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.6em;
  padding: 0.35em 0.8em;
  border-radius: 12px;
  background: var(--venue-row);
  font-size: clamp(20px, 2.2vw, 40px);
}
.venue-row-top {
  background: var(--venue-row-top);
  font-size: clamp(30px, 3.6vw, 64px);
  padding-top: 0.25em;
  padding-bottom: 0.25em;
}
.venue-rank { font-weight: 700; font-variant-numeric: tabular-nums; color: var(--mist); }
.venue-row-top .venue-rank { color: var(--gold); }
.venue-name { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.venue-count { font-weight: 700; font-variant-numeric: tabular-nums; text-align: right; color: var(--gold); }
.venue-empty { margin: 8vh 0; text-align: center; font-size: clamp(24px, 2.6vw, 48px); color: var(--mist); }
.venue-updated { margin: auto 0 0; font-size: clamp(16px, 1.4vw, 26px); color: var(--mist); }
.venue-footer { font-size: clamp(16px, 1.4vw, 26px); color: var(--mist); border-top: 1px solid var(--line); padding-top: 1.2vh; }

/*
  AV-S3b: rows after the top three drift upward in a fixed window, in CSS only.
  The window holds about four small rows at 1920 by 1080 (its font size is the
  row font size, so the height is in rows). Two identical tracks move in
  lockstep by their own height, so when the first has left the window the
  second sits exactly where the first began and the loop joins with no jump.
  The duration is the inline --venue-scroll-seconds, set by the server from the
  row count. A phone gets the plain list instead, in the query further down.
*/
.venue-scroll {
  overflow: hidden;
  height: 8.4em;
  flex: none;
  font-size: clamp(20px, 2.2vw, 40px);
}
.venue-scroll-track {
  list-style: none;
  margin: 0;
  padding: 0 0 0.8vh;
  display: grid;
  gap: 0.8vh;
  animation: venue-scroll-up calc(var(--venue-scroll-seconds) * 1s) linear infinite;
}
.venue-scroll-copy { display: grid; }
@keyframes venue-scroll-up {
  from { transform: translateY(0); }
  to { transform: translateY(-100%); }
}
/* With no motion the window must free every row, and the second copy would show each row twice. */
@media (prefers-reduced-motion: reduce) {
  .venue-scroll-track { animation: none; }
  .venue-scroll { overflow: visible; height: auto; }
  .venue-scroll-copy { display: none; }
}

/* The corner code: a white tile, because the page is dark. */
.venue-qr-box {
  position: fixed;
  right: 1vw;
  bottom: 1vh;
  margin: 0;
  width: clamp(96px, 7vw, 132px);
  text-align: center;
  font-size: clamp(11px, 0.9vw, 16px);
  color: var(--mist);
}
.venue-qr { display: block; width: 100%; height: auto; border-radius: 6px; }
.venue-qr-box figcaption { margin-top: 0.4em; }

/* At a laptop width the fixed corner code would cover the last rows, so it hides below a full TV width. */
@media (max-width: 1200px) {
  .venue-qr-box { display: none; }
}

/* A phone that scanned the code: nothing moves, the whole list is one page. */
@media (max-width: 800px) {
  .venue-scroll { overflow: visible; height: auto; }
  .venue-scroll-track { animation: none; }
  .venue-scroll-copy, .venue-qr-box { display: none; }
}
