/*
 * Component primitives. Every value here references a token from tokens.css.
 *
 * This file must not define :root. See tokens.css for why, and web_test.go for
 * the test that enforces it.
 */

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

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: var(--leading-normal);
  color: var(--ink);
  background: var(--surface-sunken);
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3 {
  font-family: var(--font-display);
  line-height: var(--leading-tight);
  font-weight: var(--weight-bold);
  margin: 0 0 var(--space-4);
}

h1 { font-size: var(--text-3xl); }
h2 { font-size: var(--text-2xl); }
h3 { font-size: var(--text-xl); }

p {
  margin: 0 0 var(--space-4);
  max-width: var(--measure);
}

a {
  color: var(--link);
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}

a:hover { color: var(--link-hover); }

/* Never removed, only replaced. A focus style that is merely `outline: none` is
   a keyboard user locked out of the page. */
:focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-offset);
}

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--space-4);
}

.masthead {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  padding-block: var(--space-4);
}

.masthead__brand {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  letter-spacing: 0.02em;
  color: var(--ink);
  text-decoration: none;
}

.main { padding-block: var(--space-12); }

.card {
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  padding: var(--space-8);
}

/* Console member record (SER-23): the operator notes. */
.note-list { list-style: none; margin: var(--space-6) 0 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-4); }
.note { border: 1px solid var(--border); border-radius: var(--radius-md); padding: var(--space-4); background: var(--surface-sunken); }
.note__meta { font-size: var(--text-sm); margin-bottom: var(--space-2); }
/* Notes are entered in a multi-line textarea and stored with their breaks, so
   keep them on render (matches .event-detail__description). Escaping is
   unchanged — this is CSS, not an unescaped <br>. */
.note__body { margin: 0; white-space: pre-line; line-height: 1.6; }

.muted {
  color: var(--ink-muted);
  font-size: var(--text-sm);
}

.definition-list {
  display: grid;
  grid-template-columns: minmax(8rem, max-content) 1fr;
  gap: var(--space-2) var(--space-6);
  margin: 0;
  font-size: var(--text-sm);
}

.definition-list dt {
  color: var(--ink-muted);
}

.definition-list dd {
  margin: 0;
  font-family: var(--font-mono);
}

.footer {
  padding-block: var(--space-8);
  color: var(--ink-muted);
  font-size: var(--text-xs);
}

/* Masthead + console navigation ------------------------------------------- */
.masthead__inner {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  flex-wrap: wrap;
}

.nav {
  display: flex;
  gap: var(--space-1);
  flex-wrap: wrap;
}

.nav__item {
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--ink-muted);
  text-decoration: none;
}

.nav__item:hover { color: var(--ink); background: var(--surface-sunken); }

.nav__item.is-active {
  color: var(--ink);
  background: var(--surface-sunken);
  font-weight: var(--weight-semibold);
}

.nav__item--soon {
  color: var(--ink-subtle);
  cursor: default;
}

.nav__item--soon:hover { background: none; color: var(--ink-subtle); }

/* Page head ---------------------------------------------------------------- */
.page-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-bottom: var(--space-6);
}

.page-head h1 { margin: 0; }

/* Buttons ------------------------------------------------------------------ */
.button {
  display: inline-block;
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--accent-500);
  border-radius: var(--radius-sm);
  background: var(--accent-500);
  color: var(--ink-inverse);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
}

.button:hover { background: var(--accent-600); border-color: var(--accent-600); color: var(--ink-inverse); }

.button--primary { background: var(--highlight-500); border-color: var(--highlight-500); color: var(--black); }
.button--primary:hover { filter: brightness(0.95); background: var(--highlight-500); border-color: var(--highlight-500); color: var(--black); }

.button--ghost { background: transparent; color: var(--ink); border-color: var(--border-strong); }
.button--ghost:hover { background: var(--surface-sunken); color: var(--ink); border-color: var(--border-strong); }

.button--danger { background: transparent; color: var(--danger-500); border-color: var(--danger-500); }
.button--danger:hover { background: var(--danger-500); color: var(--ink-inverse); border-color: var(--danger-500); }

.button--small { padding: var(--space-1) var(--space-2); font-size: var(--text-xs); }

.icon-button {
  border: 1px solid var(--border);
  background: var(--surface-raised);
  color: var(--ink-muted);
  border-radius: var(--radius-sm);
  cursor: pointer;
  line-height: 1;
  padding: 0 var(--space-2);
}

.icon-button:hover { color: var(--danger-500); border-color: var(--danger-500); }

/* Filters ------------------------------------------------------------------ */
.filters { display: flex; gap: var(--space-2); flex-wrap: wrap; margin-bottom: var(--space-6); }

.filter {
  font-size: var(--text-sm);
  color: var(--ink-muted);
  text-decoration: none;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
}

.filter:hover { color: var(--ink); }
.filter.is-active { color: var(--ink); background: var(--surface-sunken); font-weight: var(--weight-semibold); }

/* Tables ------------------------------------------------------------------- */
.table-wrap { overflow-x: auto; }

.table {
  width: 100%;
  border-collapse: collapse;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  font-size: var(--text-sm);
}

.table th,
.table td {
  text-align: left;
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}

.table th {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-muted);
  background: var(--surface);
}

.table tbody tr:last-child td { border-bottom: none; }
.table__actions { text-align: right; white-space: nowrap; }

/* Badges ------------------------------------------------------------------- */
.badge {
  display: inline-block;
  padding: 0 var(--space-2);
  border-radius: var(--radius-sm);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  line-height: 1.6;
  background: var(--surface-sunken);
  color: var(--ink-muted);
}

.badge--published,
.badge--active { background: var(--tint-success-bg); color: var(--grey-1); }
.badge--draft { background: var(--tint-info-bg); color: var(--deep-grape); }
.badge--disabled,
.badge--suspended { background: var(--tint-warning-bg); color: var(--grey-1); }
.badge--archived { background: var(--surface-sunken); color: var(--ink-subtle); }
.badge--role { background: var(--tint-info-bg); color: var(--deep-grape); text-transform: none; letter-spacing: 0; }

/* Empty state -------------------------------------------------------------- */
.empty { text-align: center; }
.empty p { margin-inline: auto; }

/* Forms -------------------------------------------------------------------- */
.form {
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  padding: var(--space-8);
  max-width: var(--page-lg);
}

.field { margin-bottom: var(--space-4); }

.field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
}

@media (max-width: 640px) {
  .field-row { grid-template-columns: 1fr; }
}

.field label {
  display: block;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  margin-bottom: var(--space-1);
}

.field input,
.field select,
.field textarea {
  width: 100%;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-raised);
  color: var(--ink);
  font: inherit;
  font-size: var(--text-sm);
}

.field textarea { resize: vertical; }

.field-hint { font-size: var(--text-xs); color: var(--ink-muted); margin: var(--space-1) 0 0; }
.field-error { font-size: var(--text-xs); color: var(--danger-500); margin: var(--space-1) 0 0; font-weight: var(--weight-medium); }

/* Description editor: a formatting toolbar over the textarea and a live preview
   below it. The toolbar is aria-hidden until the script reveals it, so it never
   shows actions that only work with JS. */
.editor-toolbar {
  display: flex;
  gap: var(--space-1);
  margin-bottom: var(--space-2);
}
.editor-toolbar[aria-hidden="true"] { display: none; }
.editor-toolbar__btn {
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-raised);
  color: var(--ink);
  font-size: var(--text-sm);
  line-height: 1.4;
  cursor: pointer;
}
.editor-toolbar__btn:hover { background: var(--surface-sunken); }
.editor-preview {
  margin-top: var(--space-2);
  padding: var(--space-3);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-raised);
  min-height: var(--space-8);
}
.editor-preview:empty::before {
  content: "Nothing to preview yet.";
  color: var(--ink-muted);
  font-size: var(--text-sm);
}

.fieldset {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  margin-bottom: var(--space-4);
}

.fieldset legend { font-size: var(--text-sm); font-weight: var(--weight-semibold); padding-inline: var(--space-2); }

.form-actions { display: flex; gap: var(--space-3); align-items: center; margin-top: var(--space-6); }

/* UTM link builder (SER-295): the assembled URL sits beside its copy button, in
   a monospace field; the standard-link examples wrap rather than stretch their
   table cell. is-copied is the brief "Copied" acknowledgement on a copy button. */
.utm-output { display: flex; gap: var(--space-2); align-items: stretch; }
.utm-output input { flex: 1; font-family: var(--font-mono); }
.utm-output .button { white-space: nowrap; }
.utm-example { font-family: var(--font-mono); font-size: var(--text-xs); word-break: break-all; }
.button.is-copied { color: var(--accent-600); }

/* Alerts ------------------------------------------------------------------- */
.alert {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  margin-bottom: var(--space-6);
}

.alert--error { background: var(--tint-warning-bg); color: var(--grey-1); border: 1px solid var(--danger-500); }

/* Publish + attach --------------------------------------------------------- */
.publish {
  display: flex;
  gap: var(--space-3);
  align-items: center;
  margin-top: var(--space-6);
}

.attach { margin-top: var(--space-8); }
.attach__list { padding-left: var(--space-6); font-size: var(--text-sm); }
.attach__list li { margin-bottom: var(--space-1); }

/* Operator role controls --------------------------------------------------- */
.role-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-1); }
.role-list li { display: flex; align-items: center; gap: var(--space-2); }

.inline { display: inline-flex; gap: var(--space-2); align-items: center; margin: 0; }

/* Dashboard cards ---------------------------------------------------------- */
.dash-card { padding: var(--space-6); }

.dash-card__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}

.dash-card__head h2 { margin: 0; font-size: var(--text-xl); }
.dash-card__head a { font-size: var(--text-sm); }

.dash-card__subhead {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-muted);
  margin: var(--space-4) 0 var(--space-2);
}

.stat-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-6);
  margin: 0;
}

.stat { margin: 0; }
.stat dt { font-size: var(--text-xs); color: var(--ink-muted); text-transform: uppercase; letter-spacing: 0.03em; }
.stat dd {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  font-weight: var(--weight-bold);
  line-height: 1.1;
}

.dash-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  font-size: var(--text-sm);
}

.dash-list li { display: flex; flex-direction: column; }
.dash-list li .muted { font-size: var(--text-xs); }

.dash-empty { margin: 0; }
.dash-accrual { margin: 0 0 var(--space-4); }

/* Members ------------------------------------------------------------------ */
.members-tools {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-bottom: var(--space-4);
}

.members-tools .filters { margin-bottom: 0; }

.search { display: flex; gap: var(--space-2); align-items: center; margin: 0; }

.search input[type="search"] {
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-raised);
  color: var(--ink);
  font: inherit;
  font-size: var(--text-sm);
  min-width: 16rem;
}

.badge--applied,
.badge--waitlisted { background: var(--tint-info-bg); color: var(--deep-grape); }
.badge--deleted { background: var(--surface-sunken); color: var(--ink-subtle); }

.alert--notice { background: var(--tint-success-bg); color: var(--grey-1); }

.pagination {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-top: var(--space-4);
  font-size: var(--text-sm);
}

.pagination__links { display: flex; gap: var(--space-2); align-items: center; }

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

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Orders (SER-13) ---------------------------------------------------------- */
.badge--confirmed { background: var(--tint-success-bg); color: var(--grey-1); }
.badge--pending { background: var(--tint-info-bg); color: var(--deep-grape); }
.badge--cancelled { background: var(--surface-sunken); color: var(--ink-subtle); }
.badge--refunded { background: var(--tint-warning-bg); color: var(--grey-1); }
/* An imported row: its date is not a purchase date, so the badge stands where a
   date would otherwise be. */
.badge--backfill { background: var(--surface-sunken); color: var(--ink-muted); }

.orders-summary { padding: var(--space-6); margin-bottom: var(--space-6); }
.orders-summary .stat-row { margin-bottom: var(--space-4); }
.orders-note { margin: 0; font-size: var(--text-sm); }

.filter-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin: 0 0 var(--space-6);
  font-size: var(--text-sm);
}
.filter-form label { color: var(--ink-muted); }

.table__filter { font-size: var(--text-xs); margin-left: var(--space-2); white-space: nowrap; }
.table__ref { color: var(--ink-muted); font-family: var(--font-mono); font-size: var(--text-xs); white-space: nowrap; }
.orders-truncated { margin: var(--space-4) 0 0; }

/* Member web app (app.) --------------------------------------------------- */
/* The eatwithsera.com shell and pages, ported one for one (SER-49, SER-41).
   Measurements are the old Tailwind values: container 16px gutters, masthead
   56px (72px from lg), page column 552px (--page), headings text-4xl/6xl in
   the display face, pill buttons, 12px input radius. */

body.member {
  background: var(--surface);
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

body.member .main { flex: 1; padding-block: 0; }
body.member .main > .container { padding-inline: var(--space-4); }

/* Masthead */
.mh {
  position: sticky;
  top: 0;
  z-index: 40;
}

.mh--guest { background: var(--black); color: var(--paper); }
.mh--member { background: var(--white); color: var(--black); }
.mh--signed-in { border-bottom: 1px solid var(--paper); }

.mh__inner {
  display: flex;
  align-items: center;
  height: 56px;
}

.mh__brand {
  display: block;
  height: 24px;
  color: inherit;
  margin-right: auto;
}

.mh__brand svg { height: 100%; width: auto; display: block; }

.mh__links,
.mh__guest { display: none; }

.mh__burger {
  display: block;
  cursor: pointer;
  line-height: 0;
  color: inherit;
}

.mh__toggle { display: none; }

.mh__scrim {
  position: fixed;
  inset: 0;
  background: rgb(38 27 27 / 50%);
  opacity: 0;
  pointer-events: none;
  transition: opacity 150ms var(--ease-out);
  cursor: pointer;
}

.mh__drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 66.666%;
  background: var(--white);
  color: var(--black);
  padding: var(--space-18) var(--space-6) var(--space-6);
  transform: translateX(100%);
  transition: transform 150ms var(--ease-out);
  overflow-y: auto;
}

.mh__close {
  position: fixed;
  top: 16px;
  right: 16px;
  color: var(--black);
  line-height: 0;
  opacity: 0;
  pointer-events: none;
  cursor: pointer;
  transition: opacity 150ms var(--ease-out);
}

.mh__toggle:checked ~ .mh__scrim { opacity: 1; pointer-events: auto; }
.mh__toggle:checked ~ .mh__drawer { transform: translateX(0); }
.mh__toggle:checked ~ .mh__close { opacity: 1; pointer-events: auto; }

.mh__drawer-links {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 36px;
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
}

.mh__drawer-links a,
.mh__signout {
  color: inherit;
  text-decoration: none;
  font: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

.mh__drawer-sep { border-top: 1px solid var(--grey-1); padding-top: 36px; }

.mh__insta { display: inline-block; margin-top: 36px; color: var(--black); line-height: 0; }

.mh__links a[aria-current="page"] { text-decoration: underline; text-underline-offset: 4px; }

/* Nav entries whose routes have not landed yet: the same words, no href. */
.mh__soon,
.mf__soon { color: inherit; cursor: default; }

@media (min-width: 1024px) {
  .mh__inner { height: 72px; }
  .mh__brand { height: 40px; }
  .mh__burger { display: none; }

  .mh__links {
    display: flex;
    gap: var(--space-8);
    list-style: none;
    margin: 0;
    padding: 0;
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
    align-items: center;
  }

  .mh__links a { color: inherit; text-decoration: none; }

  .mh__guest { display: flex; align-items: center; gap: var(--space-8); }
  .mh__link { color: inherit; text-decoration: none; font-size: var(--text-base); font-weight: var(--weight-semibold); }

  .mh__pill {
    display: inline-block;
    color: inherit;
    text-decoration: none;
    font-weight: var(--weight-semibold);
    border: 1px solid currentColor;
    border-radius: 999px;
    padding: 14px 28px;
    line-height: 1.2;
  }

  .mh__pill:hover { background: var(--white); color: var(--black); }
}

@media (max-width: 1023.98px) {
  .mh__inner .mh__pill {
    display: inline-block;
    color: inherit;
    text-decoration: none;
    font-weight: var(--weight-semibold);
    font-size: var(--text-sm);
    border: 1px solid currentColor;
    border-radius: 999px;
    padding: 10px 20px;
    margin-right: var(--space-4);
    line-height: 1.2;
  }
  .mh__guest { display: flex; align-items: center; }
  .mh__guest .mh__link { display: none; }
}

/* Page column */
.member-page {
  width: 100%;
  max-width: var(--page);
  margin: var(--space-16) auto;
}

.member-page--center { text-align: center; }
.member-page--center p { margin-inline: auto; }

.member-wide { margin: var(--space-8) auto var(--space-22); }

.heading {
  font-family: var(--font-display);
  font-weight: var(--weight-bold);
  font-size: var(--text-4xl);
  line-height: 48px;
  margin: 0 0 var(--space-8);
}

.heading--center { text-align: center; margin-bottom: 56px; }

.member-page__lead { margin: 0 0 var(--space-8); max-width: none; }
.member-page__aside { text-align: center; font-size: var(--text-sm); color: var(--grey-2); margin: var(--space-4) 0 0; max-width: none; }
.member-page__resend { margin-top: var(--space-8); text-align: center; }
.member-page__resend .btn-outline { margin-top: var(--space-4); }

/* Member data-export list (SER-56): each request's date, status and download. */
.export-list { list-style: none; margin: var(--space-4) 0 0; padding: 0; display: flex; flex-direction: column; }
.export { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-4); padding: var(--space-3) 0; border-top: 1px solid var(--border); }
.export__meta { color: var(--ink-muted); font-size: var(--text-sm); }

.link { color: var(--black); text-decoration: underline; }
.link--bold { font-weight: var(--weight-semibold); }

@media (min-width: 1024px) {
  .member-page { margin-block: var(--space-22); }
  .heading { font-size: var(--text-6xl); line-height: 67.2px; }
}

/* Fields (the old x-forms.input) */
.mfield { margin-bottom: var(--space-6); }

.mfield__label {
  display: block;
  font-weight: var(--weight-semibold);
  margin-bottom: var(--space-2);
}

.mfield__input {
  display: block;
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--grey-4);
  border-radius: var(--radius-lg);
  background: var(--white);
  color: var(--black);
  font: inherit;
  line-height: 1.5;
}

.mfield__input::placeholder { color: var(--grey-3); }
.mfield__input:focus { outline: none; border-color: var(--black); }
.mfield__input:focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-offset); }

.mfield__input--code {
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  letter-spacing: 0.3em;
  text-align: center;
  padding-block: var(--space-2);
}

.mfield__error { margin: var(--space-2) 0 0; font-size: var(--text-sm); color: var(--danger-500); }

/* Buttons (btn-filled, btn-outline) */
.btn-filled,
.btn-outline {
  display: block;
  width: 100%;
  padding: 14px 20px;
  border-radius: 999px;
  font: inherit;
  font-weight: var(--weight-semibold);
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  line-height: 1.25;
  margin-bottom: var(--space-4);
}

.btn-filled { background: var(--black); color: var(--white); border: 1px solid var(--black); }
.btn-filled:hover { background: var(--paper); color: var(--black); }

.btn-outline { background: transparent; color: var(--black); border: 1px solid var(--black); }
.btn-outline:hover { background: var(--black); color: var(--white); }

@media (min-width: 1024px) {
  .member-page__resend .btn-outline { display: inline-block; width: auto; }
}

/* Event cards (a first pass; SER-51 completes the page) */
.event-cards {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-4);
}

@media (min-width: 1024px) {
  .event-cards { grid-template-columns: repeat(3, 1fr); gap: var(--space-6); }
}

.event-card__link { display: block; color: inherit; text-decoration: none; background: var(--white); border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-card); }
.event-card__image { height: 180px; background: var(--paper); }
.event-card__body { padding: var(--space-4); }
.event-card__title { font-family: var(--font-body); font-size: var(--text-lg); font-weight: var(--weight-semibold); margin: 0 0 var(--space-1); }
.event-card__meta { margin: 0; font-size: var(--text-sm); color: var(--grey-2); }
.event-card__cta { display: inline-block; margin-top: var(--space-3); font-size: var(--text-sm); font-weight: var(--weight-semibold); text-decoration: underline; text-underline-offset: 4px; }

/* Events list sections (SER-51) */
.events-section { font-family: var(--font-body); font-size: var(--text-2xl); font-weight: var(--weight-semibold); margin: var(--space-12) 0 var(--space-6); }
.events-section:first-of-type { margin-top: 0; }
.events-empty { margin: 0 0 var(--space-8); color: var(--grey-2); }

/* Members landing navigation cards (SER-57) */
.nav-cards {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-4);
}

@media (min-width: 1024px) {
  /* auto-fit, so the row is filled by however many cards there are — the landing
     renders two (Events, Community) and must not leave an empty third cell. */
  .nav-cards { grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); gap: var(--space-6); }
}

.nav-card__link { display: block; color: inherit; text-decoration: none; background: var(--white); border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-card); }
.nav-card__image { height: 180px; background: var(--paper); }
.nav-card__body { padding: var(--space-4); }
.nav-card__title { font-family: var(--font-body); font-size: var(--text-lg); font-weight: var(--weight-semibold); margin: 0 0 var(--space-1); }
.nav-card__desc { margin: 0; font-size: var(--text-sm); color: var(--grey-2); }

/* Community WhatsApp group cards (SER-57). Static, hard-coded; the card image
   is a stub until the media slice. */
.wa-cards {
  list-style: none;
  margin: 0 0 var(--space-8);
  padding: 0;
  display: grid;
  gap: var(--space-4);
}

@media (min-width: 1024px) {
  .wa-cards { grid-template-columns: repeat(3, 1fr); gap: var(--space-6); }
}

.wa-card { display: flex; flex-direction: column; background: var(--white); border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-card); }
.wa-card__image { height: 180px; background: var(--paper); }
.wa-card__body { display: flex; flex-direction: column; flex-grow: 1; padding: var(--space-4); }
.wa-card__title { font-family: var(--font-body); font-size: var(--text-lg); font-weight: var(--weight-semibold); margin: 0 0 var(--space-1); }
.wa-card__desc { margin: 0 0 var(--space-4); font-size: var(--text-sm); color: var(--grey-2); }
.wa-card__cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  margin-top: auto;
  padding: 10px 14px;
  border: 1px solid var(--grey-4);
  border-radius: var(--radius-lg);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--black);
  text-decoration: none;
}
.wa-card__cta:hover { background: var(--black); border-color: var(--black); color: var(--white); }

/* Event detail (SER-52). The hero and gallery are stubbed until the media slice. */
.event-detail__hero { height: 220px; background: var(--paper); border-radius: var(--radius-lg); margin-bottom: var(--space-8); }
.event-detail__body { display: flex; flex-direction: column; gap: var(--space-8); }
.event-meta { list-style: none; margin: 0 0 var(--space-6); padding: 0; display: grid; gap: var(--space-3); }
.event-meta__item { margin: 0; font-size: var(--text-base); color: var(--grey-1); }
.event-detail__rule { border: 0; border-top: 1px solid var(--grey-4); margin: var(--space-8) 0; }
/* No white-space: pre-line here. The description is rendered through
   descriptionHTML (nl2br + raw HTML), so <br /> already breaks the lines the way
   the public site does; pre-line would ALSO honour the preserved newline and
   double every break. Normal white-space collapses that newline, matching sera-site. */
.event-detail__description { color: var(--grey-1); line-height: 1.6; }
.event-detail__panel { display: flex; flex-direction: column; gap: var(--space-3); }

.btn-disabled { display: block; width: 100%; padding: 14px 20px; border-radius: 999px; font: inherit; font-weight: var(--weight-semibold); text-align: center; background: var(--paper); color: var(--grey-3); border: 1px solid var(--paper); cursor: default; line-height: 1.25; }

@media (min-width: 1024px) {
  .event-detail__hero { height: 400px; }
  .event-detail__body { flex-direction: row; align-items: flex-start; }
  .event-detail__main { flex: 3 1 0; padding-right: var(--space-6); }
  .event-detail__panel { flex: 2 1 0; background: var(--white); border-radius: var(--radius-lg); padding: var(--space-8) var(--space-4); }
}

/* Footer */
.mf {
  background: var(--black);
  color: var(--paper);
  border-radius: var(--space-6) var(--space-6) 0 0;
}

.mf__inner {
  display: grid;
  gap: var(--space-12);
  padding-block: var(--space-16);
}

.mf__brand-col { order: 2; }
.mf__brand { display: inline-block; height: 40px; color: var(--off-white); margin-bottom: var(--space-8); }
.mf__brand svg { height: 100%; width: auto; display: block; }
.mf__address { font-size: var(--text-sm); line-height: 1.5rem; color: var(--paper); margin: 0; }

.mf__cols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-12) var(--space-2);
}

.mf__head { font-size: var(--text-sm); color: var(--paper); margin-bottom: var(--space-4); }
.mf__list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-4); font-weight: var(--weight-semibold); color: var(--off-white); }
.mf__list a { color: inherit; text-decoration: none; }
.mf__contact { grid-column: span 2; }
.mf__list--contact { grid-template-columns: 1fr 1fr; align-items: center; }
.mf__insta { display: inline-block; line-height: 0; color: var(--paper); }

@media (min-width: 1024px) {
  .mf__inner { grid-template-columns: 1fr 1fr; padding-block: var(--space-18); }
  .mf__brand-col { order: 0; }
  .mf__brand { margin-bottom: var(--space-16); }
  .mf__cols { grid-template-columns: repeat(3, 1fr); column-gap: var(--space-6); }
  .mf__contact { grid-column: auto; }
  .mf__list--contact { grid-template-columns: 1fr; }
}

/* Console shell — the Focus sidebar layout (SER-2 decision: Direction C) --------
 * A persistent left sidebar plus the page body, for the signed-in console only.
 * The member surface and the sign-in page keep the .masthead layout above. Every
 * value references a token; this file still defines no :root (see tokens.css). */
.console {
  display: grid;
  grid-template-columns: 248px 1fr;
  min-height: 100vh;
  background: var(--surface-sunken);
}

.side {
  position: sticky;
  top: 0;
  align-self: start;
  height: 100vh;
  overflow-y: auto;
  background: var(--surface-raised);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-4) var(--space-3);
}

.side__brand {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  letter-spacing: 0.02em;
  color: var(--ink);
  text-decoration: none;
  padding: var(--space-2) var(--space-3) 0;
}

.side__kicker {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-subtle);
  padding: 0 var(--space-3) var(--space-3);
}

.side__nav { display: flex; flex-direction: column; gap: var(--space-4); }
.side__group { display: flex; flex-direction: column; gap: 2px; }

.side__label {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-subtle);
  padding: 0 var(--space-3);
  margin-bottom: var(--space-1);
}

/* Sidebar rows reuse .nav__item — the class the console nav has always used, and
   the one the router-gating tests recognise — restyled from the old masthead pill
   into a full-width row within the sidebar. */
.side .nav__item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--ink-muted);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  text-decoration: none;
}

.side .nav__item:hover { background: var(--surface-sunken); color: var(--ink); }

.side .nav__item.is-active {
  background: var(--surface-sunken);
  color: var(--ink);
  font-weight: var(--weight-semibold);
  box-shadow: inset 3px 0 0 var(--accent-500);
}

.side .nav__item--soon { color: var(--ink-subtle); cursor: default; }
.side .nav__item--soon:hover { background: none; color: var(--ink-subtle); }

.side__icon { width: 18px; height: 18px; flex: 0 0 18px; }

.side__soon {
  margin-left: auto;
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-subtle);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0 var(--space-1);
}

.side__foot {
  margin-top: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-3) var(--space-1);
  border-top: 1px solid var(--border);
}

.side__me { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); color: var(--ink-muted); }

.side__signout {
  background: none;
  border: 0;
  padding: var(--space-1) var(--space-2);
  font: inherit;
  font-size: var(--text-sm);
  color: var(--link);
  cursor: pointer;
  border-radius: var(--radius-sm);
}
.side__signout:hover { color: var(--link-hover); background: var(--surface-sunken); }

/* The page body sits beside the sidebar, with the roomier padding Direction C
   leans on. Pages that need a narrower measure (the event form) keep their own
   max-width. */
.console__main { min-width: 0; padding: var(--space-8) var(--space-12); }

/* Dashboard (Focus): the greeting, the needs-attention queue, the at-a-glance
   cards. The card internals (.dash-card, .stat, .dash-list) are unchanged. */
.console-hello { margin: 0 0 var(--space-1); }

.section-heading {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  margin: 0 0 var(--space-4);
}

.section-heading--muted {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-muted);
  font-weight: var(--weight-semibold);
  margin-top: var(--space-8);
}

.queue-section { margin-bottom: var(--space-8); }
.queue { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-3); }

.qitem {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-4);
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card);
}

.qitem__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  flex: 0 0 40px;
  border-radius: var(--radius-md);
}
.qitem__icon svg { width: 20px; height: 20px; }
.qi-warn { background: var(--tint-warning-bg); color: var(--grey-1); }

.qitem__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.qitem__body a { text-decoration: none; }

.at-glance {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
  gap: var(--space-6);
}

/* A desk tool first, but the sidebar folds to a wrapping top strip on a narrow
   viewport rather than eating the screen. */
@media (max-width: 900px) {
  .console { grid-template-columns: 1fr; }
  .side {
    position: static;
    height: auto;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
  }
  .side__nav { flex-direction: row; flex-wrap: wrap; gap: var(--space-2); }
  .side__label { display: none; }
  .side__foot { margin: 0 0 0 auto; border: 0; padding: 0; }
  .console__main { padding: var(--space-6); }
}

/* Member record (Focus) — a reading surface: identity summary, the SER-24
   dietary placeholder, and operator notes. Tokens only; no new :root. */
.record { max-width: 760px; }

.record-head { margin-bottom: var(--space-8); }
.record-back { font-size: var(--text-sm); }
.record-title { display: flex; align-items: baseline; gap: var(--space-3); margin: var(--space-3) 0 var(--space-1); }
.record-title h1 { margin: 0; }
.record-summary { margin: 0; }
.record-actions { margin: var(--space-4) 0 0; }
.record-block { margin-bottom: var(--space-6); }
.record-note-form { box-shadow: none; padding: 0; border: 0; margin-bottom: var(--space-6); max-width: none; }

/* An honest "not built yet" placeholder for a section the console will grow into
   (here SER-24). Matches the dimmed "soon" language of the sidebar. */
.placeholder {
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
  background: color-mix(in srgb, var(--grey-4) 8%, transparent);
}
.placeholder .badge { background: var(--surface-sunken); }
.placeholder strong { font-size: var(--text-lg); }
.placeholder .muted { max-width: var(--measure); }

/* Event form (Focus) — a sticky action bar that stays reachable while editing the
   long form, and a tidy lifecycle cluster in place of the old stack of
   full-width verb forms. Scoped to the edit form; tokens only, no new :root. */
.form-actions--sticky {
  position: sticky;
  bottom: 0;
  margin: var(--space-6) calc(-1 * var(--space-8)) calc(-1 * var(--space-8));
  padding: var(--space-4) var(--space-8);
  background: var(--surface-raised);
  border-top: 1px solid var(--border);
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}

.lifecycle { margin-top: var(--space-6); }
.verb-row { display: flex; flex-direction: column; gap: var(--space-3); }
.verb-row form {
  margin: 0;
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.verb-row form .button { flex: 0 0 auto; }
.verb-row form .muted { flex: 1 1 12rem; }

/* Member record — dietary, attendance (SER-24). A dietary requirement is a
   must-read constraint: visually distinct from a preference and from "nothing
   captured" (ADR-0004). Tokens only; no new :root. */
.constraint {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  padding: var(--space-4);
  border: 1px solid var(--red);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--red) 8%, var(--surface-raised));
}
.constraint svg { width: 20px; height: 20px; flex: 0 0 20px; color: var(--red); margin-top: 2px; }
.constraint__label {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: var(--weight-semibold);
  color: var(--red);
  margin-bottom: var(--space-1);
}
.constraint__body { margin: 0; white-space: pre-line; color: var(--ink); }

/* A stack of structured constraints, most severe first. The plain .constraint
   above (free text of unstated severity) stays red; these modifiers colour a
   structured constraint by the KIND of rule it is, so an operator scanning the
   record sees an allergy apart from a by-choice avoidance at a glance. */
.constraint-list {
  list-style: none;
  margin: 0 0 var(--space-3);
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.constraint--allergy { border-color: var(--red); background: color-mix(in srgb, var(--red) 8%, var(--surface-raised)); }
.constraint--allergy svg, .constraint--allergy .constraint__label { color: var(--red); }
.constraint--intolerance { border-color: var(--highlight-500); background: color-mix(in srgb, var(--highlight-500) 10%, var(--surface-raised)); }
.constraint--intolerance svg, .constraint--intolerance .constraint__label { color: var(--highlight-500); }
.constraint--avoid { border-color: var(--accent-500); background: color-mix(in srgb, var(--accent-500) 7%, var(--surface-raised)); }
.constraint--avoid svg, .constraint--avoid .constraint__label { color: var(--accent-500); }

/* Member /account constraint rows: the term and its severity on the left, a
   compact inline Remove on the right (the member surface's buttons are otherwise
   full-width pills, which would be wrong per row). The console list has no Remove
   and its own svg+body layout, so these member-only parts do not touch it. */
.constraint__text { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.constraint__term { color: var(--ink); overflow-wrap: anywhere; }
.constraint__remove { margin-left: auto; }
.constraint__remove .btn-outline--small,
.btn-outline--small {
  display: inline-block;
  width: auto;
  padding: var(--space-1) var(--space-3);
  margin-bottom: 0;
  font-size: var(--text-sm);
}
.constraint-add { margin-top: var(--space-4); }

/* "Not captured" reads as its own state — dashed, muted, never mistakable for a
   filled-in "no requirements". */
.nodata {
  margin: 0;
  padding: var(--space-4);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-md);
  color: var(--ink-muted);
  font-style: italic;
  background: color-mix(in srgb, var(--grey-4) 8%, transparent);
}
.nodata strong { color: var(--ink); font-style: normal; }

.attend-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.attend {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--border);
}
.attend:last-child { border-bottom: 0; }

/* Stated preferences (SER-22) on the console member record: a small definition
   list, one row per stated slot. Read-only display, kept visually calmer than the
   dietary constraints above — it ranks, it never gates. */
.prefs { margin: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.pref {
  display: grid;
  grid-template-columns: 10rem 1fr;
  gap: var(--space-3);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--border);
}
.pref:last-child { border-bottom: 0; }
.pref dt { color: var(--ink-muted); font-size: var(--text-sm); }
.pref dd { margin: 0; color: var(--ink); }
@media (max-width: 40rem) { .pref { grid-template-columns: 1fr; gap: var(--space-1); } }
.attend__event a { text-decoration: none; }

/* Console tab strip (event form, SER-4 tabs). The tablist is server-rendered
   with the `hidden` attribute and revealed by console-tabs.js; without JS it
   stays hidden and the panels stack (progressive enhancement). Tokens only. */
.tabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  border-bottom: 1px solid var(--border);
  margin-bottom: var(--space-6);
}
.tab {
  appearance: none;
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  padding: var(--space-2) var(--space-3);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--ink-muted);
  cursor: pointer;
}
.tab:hover { color: var(--ink); }
.tab[aria-selected="true"] {
  color: var(--ink);
  font-weight: var(--weight-semibold);
  border-bottom-color: var(--accent-500);
}

/* The hidden attribute must win over any component display (a flex tablist, a
   grid panel), so JS panel toggling and the no-JS hidden tablist both hold. */
[hidden] { display: none !important; }

/* Seating picker (SER-96/97): a date -> time flow on the member event page. Days
   are tabs (multi-day only, revealed by member_event.html's nonced script; with
   no JS every day stacks visibly). Each slot shows its time and availability; a
   sold-out slot greys. --preview is the interest-only pre-sale state, where the
   whole picker is muted and the waitlist is the call to action. Tokens only. */
.sitting-picker__days {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  margin-bottom: var(--space-4);
}
.sitting-picker__day-btn {
  appearance: none;
  background: none;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-1) var(--space-3);
  font: inherit;
  font-size: var(--text-sm);
  color: var(--ink-muted);
  cursor: pointer;
}
.sitting-picker__day-btn:hover { color: var(--ink); }
.sitting-picker__day-btn[aria-current="true"] {
  color: var(--ink);
  font-weight: var(--weight-semibold);
  border-color: var(--accent-500);
}
.sitting-picker__day + .sitting-picker__day { margin-top: var(--space-4); }
.sitting-picker__day-heading {
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--ink-muted);
  margin: 0 0 var(--space-2);
}
.sitting-picker__slots {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.sitting-slot {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 6rem;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
}
.sitting-slot__time { font-weight: var(--weight-medium); color: var(--ink); }
.sitting-slot__label,
.sitting-slot__status { font-size: var(--text-xs); color: var(--ink-muted); }
.sitting-slot--soldout {
  opacity: 0.55;
  background: var(--surface-sunken);
}
.sitting-slot--soldout .sitting-slot__status { color: var(--danger-500); }
.sitting-picker--preview .sitting-slot { opacity: 0.6; }
.sitting-picker__soldout {
  font-weight: var(--weight-semibold);
  color: var(--danger-500);
  margin: 0 0 var(--space-2);
}
.sitting-picker__note { font-size: var(--text-sm); color: var(--ink-muted); margin: 0 0 var(--space-3); }

/* Platform Health (SER-ops) — the admin infra-operations tab. Tokens only; this
 * file still defines no :root (tokens.css owns it). Semantic status colour
 * (healthy / degraded / down) is the brand tints — mint, salmon, red — kept
 * distinct from the grape accent, so "needs attention" reads without relying on
 * the accent hue. No new interactivity: the tab is static server-render. */

/* Meta row under the page head: as-of time, region, and the opt-in refresh. */
.ops-meta {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  color: var(--ink-muted);
  font-size: var(--text-sm);
  margin-bottom: var(--space-8);
}
.ops-dot { width: 4px; height: 4px; border-radius: 50%; background: var(--ink-subtle); }
.ops-refresh { display: flex; align-items: center; gap: var(--space-2); margin-left: auto; }
.ops-toggle { display: inline-flex; border: 1px solid var(--border-strong); border-radius: var(--radius-sm); overflow: hidden; font-size: var(--text-xs); }
.ops-toggle a { padding: 2px var(--space-2); text-decoration: none; color: var(--ink-muted); }
.ops-toggle a:hover { background: var(--surface-sunken); color: var(--ink); }
.ops-toggle a.is-on { background: var(--accent-500); color: var(--ink-inverse); }

/* Overall status pill — semantic, not the accent. */
.status-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-3);
  border-radius: 999px;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  border: 1px solid transparent;
}
.status-pill .lamp { width: 9px; height: 9px; border-radius: 50%; box-shadow: 0 0 0 3px rgb(255 255 255 / 50%) inset; }
.status-pill--operational { background: var(--tint-success-bg); color: var(--grey-1); border-color: color-mix(in srgb, var(--tint-mint) 55%, var(--grey-1)); }
.status-pill--operational .lamp { background: var(--grey-1); }
.status-pill--degraded { background: var(--tint-warning-bg); color: var(--grey-1); border-color: var(--danger-500); }
.status-pill--degraded .lamp { background: var(--danger-500); }
.status-pill--down { background: var(--alert-500); color: var(--white); border-color: var(--alert-500); }
.status-pill--down .lamp { background: var(--white); }

/* A small uppercase tag for the plane a card describes (e.g. eu). */
.plane-tag {
  display: inline-block;
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: var(--weight-semibold);
  color: var(--ink-subtle);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0 var(--space-1);
  vertical-align: middle;
}

/* Health badges — extend the existing .badge vocabulary. */
.badge--healthy { background: var(--tint-success-bg); color: var(--grey-1); }
.badge--degraded { background: var(--tint-warning-bg); color: var(--grey-1); }
.badge--down { background: var(--alert-500); color: var(--white); }

/* Needs-attention queue — reuse .queue / .qitem, add severity stripes + a red icon. */
.qitem--warn { border-left: 4px solid var(--danger-500); }
.qitem--crit { border-left: 4px solid var(--alert-500); }
.qi-crit { background: var(--alert-500); color: var(--white); }
.ops-sub { font-size: var(--text-sm); color: var(--ink-muted); }

/* Stat tiles and numbers use tabular figures so columns line up. */
.ops-num { margin: 0; font-family: var(--font-display); font-size: var(--text-3xl); font-weight: var(--weight-bold); line-height: 1.1; font-variant-numeric: tabular-nums; }
.ops-num small { font-family: var(--font-body); font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--ink-subtle); }
.ops-stat-warn dd { color: var(--danger-500); }

.ops-note { margin: var(--space-4) 0 0; font-size: var(--text-xs); color: var(--ink-subtle); max-width: var(--measure); }
.ops-unavail { margin: var(--space-2) 0 0; font-size: var(--text-sm); color: var(--ink-muted); font-style: italic; }
.ops-muted { color: var(--ink-muted); font-size: var(--text-sm); max-width: var(--measure); }
.ops-foot { margin-top: var(--space-8); font-size: var(--text-xs); color: var(--ink-subtle); max-width: var(--measure); }

/* Label/value rows and a thin meter for the database cards. */
.ops-kv { display: flex; justify-content: space-between; gap: var(--space-4); padding: var(--space-2) 0; border-bottom: 1px dotted var(--border); font-size: var(--text-sm); }
.ops-kv:last-of-type { border-bottom: none; }
.ops-kv .k { color: var(--ink-muted); }
.ops-kv .v { font-variant-numeric: tabular-nums; font-weight: var(--weight-medium); }
.ops-warn { color: var(--danger-500); font-weight: var(--weight-semibold); }
.ops-meter { height: 6px; border-radius: 999px; background: var(--surface-sunken); overflow: hidden; margin-top: var(--space-1); }
.ops-meter > i { display: block; height: 100%; background: var(--accent-500); }
.ops-meter > i.ops-warn { background: var(--danger-500); }

/* GCP placeholder chips. */
.ph-signals { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.ph-signals span { font-size: var(--text-xs); color: var(--ink-muted); border: 1px solid var(--border); border-radius: 999px; padding: 2px var(--space-2); background: var(--surface-raised); }

/* Job-queue tables sit flush inside their card (the card supplies the border). */
.ops-flush { padding: 0; overflow: hidden; }
.ops-pad { padding: var(--space-6) var(--space-6) 0; }
.ops-hint { font-size: var(--text-xs); color: var(--ink-subtle); }
.ops-r { text-align: right; font-variant-numeric: tabular-nums; }
.ops-kind { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--ink); }
.ops-lasterr { display: block; font-family: var(--font-body); font-size: var(--text-xs); color: var(--ink-muted); margin-top: 2px; }
.ops-row-warn { background: color-mix(in srgb, var(--tint-salmon) 22%, transparent); }

/* A card that spans two grid tracks (the wide job tables); folds to one when narrow. */
.ops-span-2 { grid-column: span 2; }
@media (max-width: 900px) {
  .ops-span-2 { grid-column: auto; }
  .ops-refresh { margin-left: 0; }
}
