/* app-modernist.css — the tenant application in the Modernist language.
 *
 * Replaces theme.css / globals.css / style.css / animations.css wholesale:
 * one light ground, Archivo throughout, zero corner radius, 2px rules doing
 * the organising instead of shadows and glass.
 *
 * Loaded AFTER Bootstrap so the component skin below wins. Bootstrap is kept
 * only for its grid, utilities and JS behaviours (dropdown, collapse, modal) —
 * every visual decision it ships is overridden here.
 *
 * The accent is the SOCIETY's colour, not RitualRhythms' red. Per-tenant
 * branding is a shipped feature (master.Tenant.primary_color, injected by
 * {% tenant_branding_css %}); Modernist supplies the structure, the society
 * supplies the hue. #ec3013 is only the fallback when a tenant sets nothing.
 */

@import url('https://fonts.googleapis.com/css2?family=Archivo:wght@400;600;800&display=swap');

:root {
  color-scheme: light;

  --color-bg: #f3f2f2;
  --color-surface: #eae9e9;
  --color-text: #201e1d;
  --color-accent: var(--tenant-primary-color, #ec3013);
  --color-divider: color-mix(in srgb, #201e1d 40%, transparent);
  --color-hairline: color-mix(in srgb, #201e1d 16%, transparent);

  --color-neutral-100: #f8f4f4;
  --color-neutral-200: #eae7e7;
  --color-neutral-300: #d7d3d3;
  --color-neutral-400: #bab6b6;
  --color-neutral-500: #9b9797;
  --color-neutral-600: #7d7979;
  --color-neutral-700: #605d5d;
  --color-neutral-800: #444141;
  --color-neutral-900: #2d2b2b;

  /* Status hues, desaturated to sit beside the accent without shouting. */
  --color-ok: #2f6b3d;
  --color-warn: #8a6410;
  --color-bad: #a3231a;
  --color-info: #2a5a72;

  --font-heading: "Archivo", system-ui, sans-serif;
  --font-body: "Archivo", system-ui, sans-serif;
  --font-heading-weight: 800;

  --leading: 28px;
  --half: 14px;

  /* ---- Bootstrap 5.3 is variable-driven; retune it at the root and every
     component it ships follows without touching a single template. ---- */
  --bs-body-bg: var(--color-bg);
  --bs-body-color: var(--color-text);
  --bs-body-font-family: var(--font-body);
  --bs-body-font-size: 15px;
  --bs-body-line-height: 1.55;
  --bs-emphasis-color: var(--color-text);
  --bs-secondary-color: var(--color-neutral-700);
  --bs-tertiary-bg: var(--color-surface);
  --bs-border-color: var(--color-hairline);
  --bs-border-radius: 0;
  --bs-border-radius-sm: 0;
  --bs-border-radius-lg: 0;
  --bs-border-radius-xl: 0;
  --bs-border-radius-2xl: 0;
  --bs-border-radius-pill: 0;
  --bs-link-color: var(--color-accent);
  --bs-link-hover-color: var(--color-accent);
  --bs-primary: var(--color-accent);
  --bs-focus-ring-color: var(--color-accent);
  --bs-heading-color: var(--color-text);
}

/* Nothing rounds. Bootstrap sprinkles radius through dozens of components and
   a hundred templates carry rounded/rounded-circle utilities. */
*, *::before, *::after { border-radius: 0 !important; }
/* Avatars and status dots are the one place a circle carries meaning. */
.rounded-circle, .avatar, .avatar-sm, .avatar-lg, .status-dot,
.timeline-item::before { border-radius: 50% !important; }

html { -webkit-text-size-adjust: 100%; }
body {
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  overflow-x: hidden;
  text-wrap: pretty;
}

h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6,
.display-1, .display-2, .display-3, .display-4, .display-5, .display-6 {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  letter-spacing: -0.01em;
  color: var(--color-text);
}
.display-1, .display-2, .display-3, .display-4, .display-5, .display-6 {
  line-height: 1.04;
}
.text-muted, .text-muted-ux, .text-secondary { color: var(--color-neutral-700) !important; }
a { color: var(--color-accent); text-decoration: none; }
a:hover { color: var(--color-accent); text-decoration: underline; }
hr { border-top: 2px solid var(--color-divider); opacity: 1; }
::selection { background: color-mix(in srgb, var(--color-accent) 22%, transparent); }
:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }

/* Elevation is a rule, not a shadow. */
.shadow, .shadow-sm, .shadow-lg, .card, .dropdown-menu, .modal-content,
.offcanvas, .toast, .popover { box-shadow: none !important; }

/* — navigation — */
.navbar, .navbar.luxe-nav {
  background: var(--color-bg) !important;
  border-bottom: 2px solid var(--color-divider);
  padding: var(--half) 0;
  min-height: 0;
}
.navbar-brand { padding: 0; margin-right: var(--leading); gap: 10px; }
.navbar-brand img {
  height: 40px !important; width: auto; display: block;
  background: none; padding: 0; box-shadow: none;
}
/* The product mark, when a society has not uploaded its own logo. */
.brand-mark { width: 32px; height: 32px; display: block; flex: none; }
/* Sign-in and kiosk screens show the mark larger, above the heading. */
.auth-mark { display: inline-block; }
.auth-mark .brand-mark { width: 64px; height: 64px; margin: 0 auto; }
.auth-logo { height: 72px; width: auto; display: block; margin: 0 auto; }
.brand-name {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 17px; letter-spacing: -.01em; color: var(--color-text);
  white-space: nowrap;
}
.navbar .nav-link,
.navbar-dark .navbar-nav .nav-link {
  color: var(--color-text) !important;
  font-size: 14px; padding: 6px 10px !important;
}
.navbar .nav-link:hover,
.navbar-dark .navbar-nav .nav-link:hover,
.navbar .nav-link.active { color: var(--color-accent) !important; }
/* Expanded, the nav is sized by the society's name plus 10 links. A long
   tenant name must push the links onto a second row, never off the page. */
.navbar-nav { flex-wrap: wrap; }
.navbar-toggler {
  border: 2px solid var(--color-divider); padding: 4px 8px;
}
.navbar-toggler-icon {
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='%23201e1d' stroke-width='2' stroke-linecap='round' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
}

.dropdown-menu, .navbar .dropdown-menu {
  background: var(--color-bg) !important;
  border: 2px solid var(--color-text);
  padding: var(--half) 0;
  color: var(--color-text);
}
.dropdown-item, .navbar .dropdown-menu .dropdown-item {
  color: var(--color-text); padding: 7px 18px; font-size: 14px;
}
.dropdown-item:hover, .dropdown-item:focus,
.navbar .dropdown-menu .dropdown-item:hover,
.navbar .dropdown-menu .dropdown-item:focus {
  background: color-mix(in srgb, var(--color-accent) 9%, transparent);
  color: var(--color-accent);
}
.navbar .dropdown-menu .dropdown-item i { margin-right: .5rem; color: var(--color-neutral-600); }
.navbar .dropdown-menu .dropdown-item:hover i { color: var(--color-accent); }
.dropdown-divider, .navbar .dropdown-menu .dropdown-divider {
  border-top: 2px solid var(--color-divider); opacity: 1; margin: var(--half) 0;
}

/* — mega menu — structure preserved from style.css, skin redone flat — */
.mega-menu { position: static !important; }
/* Shrink-wrap to the columns it actually has, so a 2-column menu is narrow
   instead of stretching its two columns across the full 900px. */
.mega-menu .dropdown-menu {
  width: max-content; max-width: min(900px, 94vw); padding: var(--leading);
  border: 2px solid var(--color-text); margin-top: 0;
  z-index: 1050; position: absolute; background: var(--color-bg) !important;
}
.navbar .mega-menu .dropdown-menu { left: 50%; transform: translateX(-50%); }
/* One track per .mega-menu-column, however many the template emits - a fixed
   count wraps the surplus column onto an orphan second row. */
.mega-menu-columns {
  display: grid; grid-auto-flow: column;
  grid-auto-columns: minmax(190px, 1fr); gap: var(--leading);
}
.mega-menu-column { min-width: 0; }
.mega-menu-section { margin-bottom: var(--leading); }
.mega-menu-section:last-child { margin-bottom: 0; }
.mega-menu-header {
  font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .09em; color: var(--color-accent);
  margin: 0 0 var(--half); padding: 0 0 6px;
  border-bottom: 2px solid var(--color-divider);
  display: flex; align-items: center; gap: .5rem;
}
.mega-menu-item {
  padding: 6px 0; display: flex; align-items: center;
  color: var(--color-text); text-decoration: none; font-size: 14px;
}
.mega-menu-item:hover { color: var(--color-accent); text-decoration: none; }
.mega-menu-item i { margin-right: .6rem; width: 18px; text-align: center; color: var(--color-neutral-600); }
.mega-menu-item:hover i { color: var(--color-accent); }
/* Below the navbar's expand point the menu is a stacked list, so the columns
   flow as rows. Keep this in step with navbar-expand-xxl in base.html. */
@media (max-width: 1399.98px) {
  .mega-menu-columns { grid-auto-flow: row; grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 768px) {
  .mega-menu-columns { grid-auto-flow: row; grid-template-columns: 1fr; }
  .mega-menu .dropdown-menu { padding: var(--half); }
}

/* — collapsed navbar (below navbar-expand-xxl) —
   The open menu is a vertical list, not a floating bar, so it needs its own
   rules: markup carries .align-items-center for the desktop row, and the
   mega menus are absolutely positioned. Left as-is on mobile that yields a
   centred stack of links above a ~1900px full-bleed dropdown that pushes the
   page. Here the whole menu becomes one left-aligned, self-scrolling panel. */
@media (max-width: 1399.98px) {
  .navbar-collapse {
    max-height: calc(100vh - 4.5rem); overflow-y: auto;
    overscroll-behavior: contain;
  }
  .navbar-collapse .navbar-nav { align-items: stretch !important; width: 100%; }
  .navbar-collapse .nav-item { width: 100%; }
  .navbar-collapse .nav-link { padding-left: 0 !important; }

  /* Join the list flow instead of overlaying the page. */
  .navbar .mega-menu .dropdown-menu,
  .navbar .dropdown-menu {
    position: static !important; float: none;
    left: auto !important; transform: none !important;
    width: auto; max-width: none;
    border-width: 0 0 0 2px; border-left-color: var(--color-divider);
    border-radius: 0; margin: 0 0 var(--half) var(--half);
    padding: var(--half) 0 var(--half) var(--leading);
  }
  /* Comfortable touch targets once rows are full-width. */
  .mega-menu-item, .navbar .dropdown-menu .dropdown-item { padding: 10px 0; }

  /* Stacked, the grid's row gap lands only between sections that happen to sit
     in different column divs, so header spacing looks arbitrary. Sections space
     themselves; keep the column gap for the 2-up range above 768px. */
  .mega-menu-columns { row-gap: 0; }

  /* Accordion: the script marks sections collapsible and toggles .is-open, so
     the menu opens as a short list of group headers rather than every link. */
  .mega-menu-section.is-collapsible { margin-bottom: 0; }
  .mega-menu-section.is-collapsible > .mega-menu-header {
    cursor: pointer; margin-bottom: 0; padding: 12px 0;
    border-bottom-width: 1px; justify-content: space-between;
  }
  .mega-menu-section.is-collapsible > .mega-menu-header::after {
    content: '+'; font-size: 15px; line-height: 1; color: var(--color-accent);
    margin-left: auto;
  }
  .mega-menu-section.is-collapsible.is-open > .mega-menu-header::after { content: '\2013'; }
  .mega-menu-section.is-collapsible > .mega-menu-item { display: none; }
  .mega-menu-section.is-collapsible.is-open > .mega-menu-item { display: flex; }
  .mega-menu-section.is-collapsible.is-open { padding-bottom: var(--half); }
}

/* — narrow-screen layout guards —
   Two patterns overflow the viewport on phones no matter which page they are
   on, so they are fixed here rather than in the 157 templates that use them. */
@media (max-width: 767.98px) {
  /* "Title on the left, buttons on the right" header rows: the action group
     cannot shrink below its content, so without wrapping it pushes off-screen.
     288 occurrences across the templates. */
  .d-flex.justify-content-between { flex-wrap: wrap; row-gap: var(--half); }

  /* Bootstrap ships 16px checkboxes and radios; WCAG 2.5.8 asks for a 24px
     minimum target for controls that are not inline text. Sized in px, not em:
     the inherited font-size here is 15px, so a 1.5em box lands at 22.5px and
     misses the bar by a pixel. Size every box wherever it sits, but only widen
     the gutter for the ones hanging in a .form-check. */
  input[type="checkbox"], input[type="radio"] { width: 24px; height: 24px; }
  /* Switches keep a wide track, but Bootstrap's 1em height is only 15px here. */
  .form-switch .form-check-input { width: 44px; height: 24px; }
  .form-check:not(.form-switch) { padding-left: 32px; }
  .form-check:not(.form-switch) > .form-check-input { margin-left: -32px; }
}
/* Summernote renders into a fixed-width iframe (720px by default), which is
   wider than a phone viewport. SUMMERNOTE_CONFIG sets width; this is the guard
   for the wrapper chrome around it. */
.note-editor, .note-editor .note-toolbar, .note-editor .note-editing-area,
.note-editor iframe, .note-editable { max-width: 100%; }

/* — buttons: flush-left labels, solid accent primary, square — */
.btn {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 14px; line-height: 1.2; padding: 9px 16px;
  border: 2px solid transparent; transition: background .15s ease, color .15s ease;
}
.btn-lg { font-size: 16px; padding: 12px 22px; }
.btn-sm { font-size: 13px; padding: 6px 12px; }
.btn:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; box-shadow: none; }
.btn-primary { background: var(--color-accent); border-color: var(--color-accent); color: #fff; }
.btn-primary:hover, .btn-primary:focus {
  background: color-mix(in srgb, var(--color-accent) 84%, #000);
  border-color: color-mix(in srgb, var(--color-accent) 84%, #000); color: #fff;
}
.btn-secondary, .btn-light, .btn-outline-secondary, .btn-outline-dark {
  background: transparent; border-color: var(--color-divider); color: var(--color-text);
}
.btn-secondary:hover, .btn-light:hover, .btn-outline-secondary:hover, .btn-outline-dark:hover {
  background: color-mix(in srgb, var(--color-text) 8%, transparent);
  border-color: var(--color-text); color: var(--color-text);
}
.btn-outline-primary { background: transparent; border-color: var(--color-accent); color: var(--color-accent); }
.btn-outline-primary:hover { background: var(--color-accent); border-color: var(--color-accent); color: #fff; }
.btn-success { background: var(--color-ok); border-color: var(--color-ok); color: #fff; }
.btn-danger { background: var(--color-bad); border-color: var(--color-bad); color: #fff; }
.btn-warning { background: var(--color-warn); border-color: var(--color-warn); color: #fff; }
.btn-info { background: var(--color-info); border-color: var(--color-info); color: #fff; }
.btn-outline-success { background: transparent; border-color: var(--color-ok); color: var(--color-ok); }
.btn-outline-danger { background: transparent; border-color: var(--color-bad); color: var(--color-bad); }
.btn-outline-warning { background: transparent; border-color: var(--color-warn); color: var(--color-warn); }
.btn-outline-info { background: transparent; border-color: var(--color-info); color: var(--color-info); }
.btn-outline-success:hover { background: var(--color-ok); color: #fff; }
.btn-outline-danger:hover { background: var(--color-bad); color: #fff; }
.btn-outline-warning:hover { background: var(--color-warn); color: #fff; }
.btn-outline-info:hover { background: var(--color-info); color: #fff; }
.btn-link { color: var(--color-accent); border-color: transparent; }
.btn:disabled, .btn.disabled { opacity: .45; }
/* Modernist rule: a button wider than its label starts the text at the left
   padding edge, never centred. */
.btn.w-100, .btn.btn-block, .d-grid > .btn { text-align: left; }

/* — cards: a bordered cell, not a floating tile — */
.card, .card.bg-transparent, .glass-card, .dashboard-card {
  background: var(--color-bg);
  border: 2px solid var(--color-divider);
  transition: none; transform: none; backdrop-filter: none;
}
.card:hover, .glass-card:hover, .dashboard-card:hover { transform: none; }
.dashboard-card:hover, a .card:hover, .card-link:hover {
  background: color-mix(in srgb, var(--color-accent) 5%, var(--color-bg));
}
.card-header {
  background: var(--color-bg); border-bottom: 2px solid var(--color-divider);
  padding: var(--half) var(--leading);
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 13px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--color-text);
}
.card-header h1, .card-header h2, .card-header h3, .card-header h4,
.card-header h5, .card-header h6 { font-size: 17px; letter-spacing: -.01em;
  text-transform: none; margin: 0; }
.card-body { padding: var(--leading); }
.card-footer { background: var(--color-bg); border-top: 2px solid var(--color-divider); padding: var(--half) var(--leading); }
.card-title { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 18px; }
.dashboard-card .card-icon {
  width: 44px; height: 44px; display: flex; align-items: center; justify-content: center;
  font-size: 20px; margin-bottom: var(--half);
  color: var(--color-accent); background: none;
}
/* .border-0 is on 331 elements and would erase the card edge the system needs. */
.card.border-0 { border: 2px solid var(--color-divider) !important; }

/* — tables: rules, no zebra, tabular figures — */
.table {
  --bs-table-bg: transparent;
  font-size: 14px; border-color: var(--color-hairline);
  font-variant-numeric: tabular-nums;
}
.table > thead > tr > th {
  border-bottom: 2px solid var(--color-text); background: transparent;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--color-neutral-800); padding: var(--half) 10px; white-space: nowrap;
}
.table > tbody > tr > td { padding: var(--half) 10px; border-color: var(--color-hairline); vertical-align: middle; }
.table-hover > tbody > tr:hover > * ,
.table-hover tbody tr:hover {
  background: color-mix(in srgb, var(--color-accent) 6%, transparent);
  --bs-table-accent-bg: transparent;
}
.table-striped > tbody > tr:nth-of-type(odd) > * { --bs-table-accent-bg: transparent; background: transparent; }
.table-responsive { border: 0; }
/* Contextual row classes — Bootstrap tints these from its own palette, which
   put a blue "Net Surplus" row in the middle of an otherwise flat ledger.
   A highlighted row is a rule and a weight change, not a wash of colour. */
.table > :not(caption) > tr.table-light > *,
.table > :not(caption) > * > tr.table-light > * {
  background: var(--color-surface); --bs-table-bg: transparent;
}
.table > :not(caption) > tr.table-primary > *,
.table > :not(caption) > * > tr.table-primary > * {
  background: var(--color-surface); --bs-table-bg: transparent;
  border-top: 2px solid var(--color-text); border-bottom: 2px solid var(--color-text);
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
}
.table > :not(caption) > * > tr.table-success > * { background: color-mix(in srgb, var(--color-ok) 10%, transparent); --bs-table-bg: transparent; }
.table > :not(caption) > * > tr.table-danger  > * { background: color-mix(in srgb, var(--color-bad) 10%, transparent); --bs-table-bg: transparent; }
.table > :not(caption) > * > tr.table-warning > * { background: color-mix(in srgb, var(--color-warn) 12%, transparent); --bs-table-bg: transparent; }
.table > :not(caption) > * > tr.table-secondary > * { background: var(--color-surface); --bs-table-bg: transparent; }

/* — forms: filled field, square, accent caret — */
.form-control, .form-select, .input-group-text {
  background: var(--color-surface); border: 1px solid var(--color-divider);
  color: var(--color-text); font-size: 14px; padding: 8px 11px;
  caret-color: var(--color-accent);
}
.form-control:focus, .form-select:focus {
  background: var(--color-surface); border-color: var(--color-accent);
  box-shadow: none; color: var(--color-text);
}
.form-control::placeholder { color: var(--color-neutral-600); }
.form-control:disabled, .form-control[readonly] { background: var(--color-neutral-200); opacity: 1; }
.form-label {
  font-size: 12px; color: var(--color-neutral-700); margin-bottom: 5px; font-weight: 400;
}
.form-text { font-size: 12px; color: var(--color-neutral-700); }
.form-check-input { border: 1.5px solid var(--color-divider); background-color: var(--color-bg); }
.form-check-input:checked { background-color: var(--color-accent); border-color: var(--color-accent); }
.form-check-input:focus { border-color: var(--color-accent); box-shadow: none; }
.form-check-label { font-size: 14px; }
.input-group-text { background: var(--color-neutral-200); }
.was-validated .form-control:invalid, .form-control.is-invalid { border-color: var(--color-bad); }
.invalid-feedback { color: var(--color-bad); font-size: 12px; }

/* — badges: flat tint, never a pill — */
.badge {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
  padding: 4px 8px; border: 0;
}
.badge.bg-primary, .badge-active { background: var(--color-accent) !important; color: #fff !important; }
.badge.bg-success { background: var(--color-ok) !important; color: #fff !important; }
.badge.bg-danger { background: var(--color-bad) !important; color: #fff !important; }
.badge.bg-warning, .badge-pending { background: var(--color-warn) !important; color: #fff !important; }
.badge.bg-info { background: var(--color-info) !important; color: #fff !important; }
.badge.bg-secondary, .badge-expired { background: var(--color-neutral-600) !important; color: #fff !important; }
.badge.bg-light { background: var(--color-neutral-200) !important; color: var(--color-text) !important; }
.badge.bg-dark { background: var(--color-text) !important; color: var(--color-bg) !important; }
.badge-cancelled { background: var(--color-bad) !important; color: #fff !important; }

/* — alerts: a left rule, not a tinted balloon — */
.alert {
  background: var(--color-surface); border: 0;
  border-left: 3px solid var(--color-neutral-600);
  padding: var(--half) var(--leading); font-size: 14px; color: var(--color-text);
}
.alert-primary { border-left-color: var(--color-accent); }
.alert-success { border-left-color: var(--color-ok); }
.alert-danger { border-left-color: var(--color-bad); }
.alert-warning { border-left-color: var(--color-warn); }
.alert-info { border-left-color: var(--color-info); }
.alert-heading { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 15px; }

/* — overlays — */
.modal-content { background: var(--color-bg); border: 2px solid var(--color-text); }
.modal-header, .modal-footer { border-color: var(--color-divider); border-width: 2px; padding: var(--half) var(--leading); }
.modal-title { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 18px; }
.modal-body { padding: var(--leading); }
.btn-close { opacity: .7; }
.offcanvas { background: var(--color-bg); border-right: 2px solid var(--color-text); }
.toast { background: var(--color-text); color: var(--color-bg); border: 0; }
.tooltip-inner { background: var(--color-text); font-size: 12px; }
.popover { background: var(--color-bg); border: 2px solid var(--color-text); }

/* — lists, tabs, pagination, progress — */
.list-group-item {
  background: var(--color-bg); border-color: var(--color-hairline);
  color: var(--color-text); padding: var(--half) var(--leading); font-size: 14px;
}
.list-group-item.active { background: var(--color-accent); border-color: var(--color-accent); color: #fff; }
.nav-tabs { border-bottom: 2px solid var(--color-divider); }
.nav-tabs .nav-link {
  border: 0; border-bottom: 3px solid transparent; margin-bottom: -2px;
  color: var(--color-neutral-700); font-size: 14px;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
}
.nav-tabs .nav-link:hover { border-bottom-color: var(--color-divider); color: var(--color-text); }
.nav-tabs .nav-link.active { background: transparent; color: var(--color-accent); border-bottom-color: var(--color-accent); }
.nav-pills .nav-link { color: var(--color-text); font-size: 14px; }
.nav-pills .nav-link.active { background: var(--color-accent); color: #fff; }
.page-link { background: var(--color-bg); border-color: var(--color-hairline); color: var(--color-text); font-size: 14px; }
.page-link:hover { background: var(--color-surface); color: var(--color-accent); }
.page-item.active .page-link { background: var(--color-accent); border-color: var(--color-accent); color: #fff; }
.progress { background: var(--color-neutral-300); height: 10px; }
.progress-bar { background: var(--color-accent); }
.accordion-item { background: var(--color-bg); border: 0; border-bottom: 2px solid var(--color-divider); }
.accordion-button {
  background: var(--color-bg); color: var(--color-text); padding: var(--half) 0;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 15px;
}
.accordion-button:not(.collapsed) { background: var(--color-bg); color: var(--color-accent); box-shadow: none; }
.accordion-button:focus { box-shadow: none; border-color: transparent; }
.accordion-body { padding: 0 0 var(--leading); font-size: 14px; }
.breadcrumb { font-size: 13px; }
.breadcrumb-item + .breadcrumb-item::before { content: "·"; color: var(--color-neutral-500); }
.spinner-border, .spinner-grow { color: var(--color-accent); }
.spinner-container { display: flex; justify-content: center; align-items: center; height: 300px; }

/* — background utilities: the app leans on bg-white/bg-light for surfaces — */
.bg-white, .bg-body, .bg-body-tertiary { background-color: var(--color-bg) !important; }
.bg-light { background-color: var(--color-surface) !important; }
.bg-dark { background-color: rgba(32, 30, 29, var(--bs-bg-opacity, 1)) !important; }
.bg-primary { background-color: var(--color-accent) !important; }
/* Written as rgba so the bg-opacity-* utilities keep working — the app uses
   them for the tinted icon chips on the dashboard. */
.bg-success { background-color: rgba(47, 107, 61, var(--bs-bg-opacity, 1)) !important; }
.bg-danger  { background-color: rgba(163, 35, 26, var(--bs-bg-opacity, 1)) !important; }
.bg-warning { background-color: rgba(138, 100, 16, var(--bs-bg-opacity, 1)) !important; }
.bg-info    { background-color: rgba(42, 90, 114, var(--bs-bg-opacity, 1)) !important; }
.text-primary { color: var(--color-accent) !important; }
.text-success { color: var(--color-ok) !important; }
.text-danger { color: var(--color-bad) !important; }
.text-warning { color: var(--color-warn) !important; }
.text-info { color: var(--color-info) !important; }
.text-white { color: #fff !important; }
.border { border-color: var(--color-hairline) !important; }

/* — app components carried over from style.css, restyled flat — */
.timeline { position: relative; padding: var(--half) 0; }
.timeline-item { position: relative; padding-left: 34px; margin-bottom: var(--leading); }
.timeline-item::before {
  content: ''; position: absolute; left: 6px; top: 6px;
  width: 9px; height: 9px; background: var(--color-accent);
}
.timeline-item::after {
  content: ''; position: absolute; left: 10px; top: 18px;
  width: 2px; height: calc(100% + 10px); background: var(--color-divider);
}
.timeline-item:last-child::after { display: none; }

.donation-progress { position: relative; background: var(--color-neutral-300); overflow: hidden; }
.donation-progress-bar { background: var(--color-accent); height: 26px; transition: width .6s ease; }
.donation-progress-text {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 13px; color: var(--color-text);
}

.veg-badge, .non-veg-badge {
  color: #fff; padding: 3px 9px; font-size: 11px; letter-spacing: .06em;
  text-transform: uppercase; display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
}
.veg-badge { background: var(--color-ok); }
.non-veg-badge { background: var(--color-bad); }
.coupon-card { position: relative; }
.coupon-card-veg { border: 2px solid var(--color-ok) !important; }
.coupon-card-non-veg { border: 2px solid var(--color-bad) !important; }
.coupon-card-veg:hover, .coupon-card-non-veg:hover { box-shadow: none; }
/* A spent coupon stays legible but visibly out of play. */
.coupon-card-used {
  opacity: .55; background: var(--color-surface) !important;
  border-color: var(--color-hairline) !important;
}
.coupon-card-used:hover { box-shadow: none !important; transform: none; }
.coupon-card-used .card-body, .coupon-card-used .card-title { color: var(--color-neutral-700) !important; }
.coupon-card .form-check { z-index: 1; }
.coupon-card .form-check-input, #selectAllUpgradeable { width: 1.15em; height: 1.15em; cursor: pointer; }

/* Coupon and order lifecycle states, as flat fills on the status palette. */
.bg-pending { background-color: var(--color-warn) !important; color: #fff !important; }
.bg-paid    { background-color: var(--color-ok) !important; color: #fff !important; }
.bg-cancelled { background-color: var(--color-bad) !important; color: #fff !important; }
.bg-active  { background-color: var(--color-info) !important; color: #fff !important; }
.bg-used    { background-color: var(--color-neutral-600) !important; color: #fff !important; }

.qr-code-container {
  background: var(--color-bg); border: 2px solid var(--color-text);
  padding: var(--leading); text-align: center;
}
.qr-code-container img { max-width: 200px; margin: 0 auto; }

footer, footer.bg-light {
  margin-top: auto; background: var(--color-bg) !important;
  border-top: 2px solid var(--color-divider);
}
footer .text-muted { color: var(--color-neutral-700) !important; }

/* — kill the old dark/glass/gradient language wherever a template still
     reaches for it. These classes are being removed template by template;
     this neutralises them until the sweep reaches each file. — */
.luxe-bg, .hero-wrap, .hero-section, .glass-card {
  background: var(--color-bg) !important;
  backdrop-filter: none !important;
  border-radius: 0 !important;
}
.hero-section { border: 2px solid var(--color-divider); padding: var(--leading); margin: var(--leading) 0; }
.display-serif { font-family: var(--font-heading); }

/* ========================================================================
   Page primitives — the vocabulary application screens are rebuilt on.
   Prefer these over ad-hoc per-template <style> blocks.
   ======================================================================== */

.app-page { padding-bottom: calc(var(--leading) * 2); }

.kicker {
  display: block; font-size: 12px; line-height: var(--half);
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--color-accent); margin: 0 0 var(--half);
  font-variant-numeric: tabular-nums;
}
.kicker em {
  font-style: normal;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
}

.page-head { padding: calc(var(--leading) * 1.5) 0 var(--leading); }
.page-head h1 {
  font-size: clamp(30px, 5vw, 56px); line-height: 1.04;
  margin: 0 0 var(--half); max-width: 18ch;
}
.page-head .lede {
  font-size: 16px; line-height: var(--leading); max-width: 62ch;
  margin: 0; color: var(--color-neutral-800);
}
.head-actions { display: flex; flex-wrap: wrap; gap: var(--half); margin-top: var(--leading); }

/* A page header with an action parked on the right — the common list-screen top. */
.page-bar {
  display: flex; flex-wrap: wrap; gap: var(--half);
  align-items: flex-end; justify-content: space-between;
  padding: calc(var(--leading) * 1.5) 0 var(--half);
  border-bottom: 2px solid var(--color-divider); margin-bottom: var(--leading);
}
.page-bar h1 { font-size: clamp(24px, 3.2vw, 36px); line-height: 1.06; margin: 0; }

.app-section { padding: calc(var(--leading) * 1.5) 0; }
.section-title {
  font-size: clamp(22px, 2.8vw, 32px); line-height: 1.08;
  margin: 0 0 var(--leading); max-width: 22ch;
}

/* ========================================================================
   Home hero — headline, society picture and the numbers as ONE framed block.
   Only templates/home.html uses these; .stat-band below is the standalone
   version other screens still reach for.
   ======================================================================== */

.home-hero {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  grid-template-areas: "copy plate" "stats stats";
  border: 2px solid var(--color-text);
  margin: calc(var(--leading) * 1.5) 0 0;
}
/* No stats (a tenant with both products off) must not leave an empty row. */
.home-hero--nostats { grid-template-areas: "copy plate"; }

.home-hero-copy {
  grid-area: copy;
  padding: calc(var(--leading) * 1.5) var(--leading) calc(var(--leading) * 1.5) calc(var(--leading) * 1.25);
  align-self: center;
}
.home-hero-copy h1 {
  font-size: clamp(30px, 4.4vw, 54px); line-height: 1.04;
  margin: 0 0 var(--half); max-width: 15ch;
}
.home-hero-copy .lede {
  font-size: 16px; line-height: var(--leading); max-width: 46ch;
  margin: 0; color: var(--color-neutral-800);
}
.home-hero-copy .head-actions { margin-top: calc(var(--leading) * 1.1); }

.home-hero-plate {
  grid-area: plate; margin: 0; position: relative;
  border-left: 2px solid var(--color-text);
  min-height: 340px;
  /* The picture governs the row's height; the copy centres against it. */
  display: flex;
}
.home-hero-plate > img {
  display: block; width: 100%; height: 100%;
  object-fit: cover; object-position: center;
}

/* The no-upload state. The society's own accent, ruled — NOT a stock photo:
   one shared illustration is wrong for somebody by definition, and the one
   this replaced had "Event Management System" baked into the artwork. */
.brand-plate {
  flex: 1; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: var(--half);
  padding: var(--leading);
  background-color: var(--color-accent);
  background-image:
    repeating-linear-gradient(
      -45deg,
      rgba(255, 255, 255, .10) 0 2px,
      transparent 2px 22px
    ),
    /* A flat scrim under the rules. WHY: the accent is the SOCIETY's colour and
       nothing constrains it -- a tenant may set pale yellow, against which white
       text and a white mark are unreadable. This darkens any hue enough to
       carry white while leaving it recognisably that society's colour. */
    linear-gradient(rgba(0, 0, 0, .22), rgba(0, 0, 0, .22));
  color: #fff;
}
.brand-plate .brand-mark-plain {
  width: clamp(72px, 12vw, 112px); height: auto;
  opacity: .95;
}
.brand-plate-name {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: clamp(15px, 1.6vw, 20px); line-height: 1.15; text-align: center;
  letter-spacing: .02em; text-wrap: balance;
}

.home-hero-stats {
  grid-area: stats;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  border-top: 2px solid var(--color-text);
}
.home-hero-stats .stat-cell {
  padding: var(--leading) var(--leading) var(--leading) calc(var(--leading) * 1.25);
  border-left: 2px solid var(--color-divider);
}
/* padding-left is restated because the generic `.stat-cell:first-child` rule
   further down zeroes it for the standalone band, where the cell sits against
   no frame. Here it does. */
.home-hero-stats .stat-cell:first-child {
  border-left: 0;
  padding-left: calc(var(--leading) * 1.25);
}

@media (max-width: 860px) {
  .home-hero,
  .home-hero--nostats { grid-template-areas: "copy" "plate" "stats"; grid-template-columns: 1fr; }
  .home-hero--nostats { grid-template-areas: "copy" "plate"; }
  .home-hero-copy { padding: var(--leading); }
  /* Reading order keeps the headline first, so the plate's rule moves to its top. */
  .home-hero-plate { border-left: 0; border-top: 2px solid var(--color-text); min-height: 220px; }
}

/* Retained for any screen still reaching for the old single-image banner. */
.app-banner { margin: 0 0 var(--leading); border: 2px solid var(--color-divider); }
.app-banner img { display: block; width: 100%; max-height: 380px; object-fit: cover; }

/* — numbers band — */
.stat-band { padding: var(--leading) 0; border-top: 2px solid var(--color-divider); }
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }
.stat-cell { padding: var(--half) var(--leading) var(--half) 0; border-left: 2px solid var(--color-divider); padding-left: var(--leading); }
.stat-cell:first-child { border-left: 0; padding-left: 0; }
.stat-num {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: clamp(32px, 4vw, 52px); line-height: 1; margin: 0 0 6px;
  color: var(--color-accent); font-variant-numeric: tabular-nums;
}
.stat-label {
  margin: 0; font-size: 12px; letter-spacing: .07em; text-transform: uppercase;
  color: var(--color-neutral-700);
}

/* — tile grid — the module/shortcut cell — */
.tile-grid {
  display: grid; grid-template-columns: repeat(3, 1fr);
  border-top: 2px solid var(--color-text); border-left: 2px solid var(--color-divider);
}
@media (max-width: 860px) { .tile-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .tile-grid { grid-template-columns: 1fr; } }
.tile {
  position: relative; display: block; padding: var(--leading);
  border-bottom: 2px solid var(--color-divider); border-right: 2px solid var(--color-divider);
  background: var(--color-bg); color: var(--color-text); text-decoration: none;
  transition: background .2s ease;
}
.tile:hover {
  background: color-mix(in srgb, var(--color-accent) 7%, var(--color-bg));
  color: var(--color-text); text-decoration: none;
}
/* Tiles number themselves. WHY a counter and not literal text: which tiles
   render depends on the tenant's enabled products, so hardcoded numbers left
   visible gaps (a society-only tenant would start at 05). */
.tile-grid { counter-reset: tile; }
.tile { counter-increment: tile; }
.tile-idx {
  position: absolute; top: var(--leading); right: var(--leading);
  font-size: 11px; letter-spacing: .06em; font-variant-numeric: tabular-nums;
  color: var(--color-neutral-500);
}
.tile-idx::before { content: counter(tile, decimal-leading-zero); }
.tile:hover .tile-idx { color: var(--color-accent); }
.tile > i { display: block; font-size: 24px; color: var(--color-accent); line-height: 1; }
.tile h3 {
  font-size: 18px; line-height: var(--leading); margin: var(--half) 0 0;
}
.tile p {
  font-size: 14px; line-height: var(--leading); margin: 6px 0 0;
  color: var(--color-neutral-700);
}

/* — the accent statement band that closes a page — */
.app-close {
  background: var(--color-accent); color: #fff;
  padding: calc(var(--leading) * 1.6) calc(var(--leading) * 1.25);
  margin-top: calc(var(--leading) * 1.5);
  /* Statement left, action right — the same asymmetric split as the hero, so
     the page opens and closes on one structural idea instead of two. Collapses
     to a single column below the tile grid's own breakpoint. */
  display: grid; align-items: center; gap: var(--leading);
  grid-template-columns: minmax(0, 1fr) auto;
}
.app-close h2 {
  color: #fff; font-size: clamp(24px, 3.4vw, 40px); line-height: 1.06;
  margin: 0 0 var(--half); max-width: 20ch;
}
.app-close p { margin: 0; max-width: 56ch; color: rgba(255,255,255,.88); }
.app-close > .btn { justify-self: end; }
@media (max-width: 860px) {
  .app-close { grid-template-columns: 1fr; }
  .app-close > .btn { justify-self: start; }
}
.app-close .btn-primary { background: var(--color-bg); border-color: var(--color-bg); color: var(--color-text); }
.app-close .btn-primary:hover { background: #fff; border-color: #fff; color: var(--color-text); }

/* ------------------------------------------------------------------------
   Screen-level classes that used to live in per-template <style> blocks.
   Those blocks were dark-mode compensation and radius/shadow decoration the
   theme now owns; these are the handful of names that carried real meaning
   and are still referenced by markup.
   ------------------------------------------------------------------------ */

/* Every "…-card" in the app is the same object: a bordered panel. */
.stat-card, .info-card, .warning-card, .shift-card, .timeline-card,
.template-card, .gateway-provider-card, .food-meal-card, .event-filter-card,
.filter-section, .no-shift-container {
  background: var(--color-bg); border: 2px solid var(--color-divider);
  padding: var(--leading);
}
.warning-card { border-left: 3px solid var(--color-warn); }
.gateway-provider-card, .template-card, .food-meal-card { transition: background .2s ease; }
.gateway-provider-card:hover, .template-card:hover, .food-meal-card:hover,
.gateway-provider-card.selected, .template-card.selected {
  background: color-mix(in srgb, var(--color-accent) 6%, var(--color-bg));
}
.stat-card .value, .stat-card h3 {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: clamp(24px, 3vw, 36px); line-height: 1; color: var(--color-accent);
  font-variant-numeric: tabular-nums; margin: 0;
}

/* Key/value rows — shift details, gateway fees, price breakdowns. */
.shift-info, .gateway-features, .gateway-fees, .price-info {
  display: grid; gap: 6px; margin-top: var(--half); font-size: 14px;
}
.shift-info-item, .gateway-fees li, .price-info > * {
  display: flex; justify-content: space-between; gap: var(--half);
  padding: 6px 0; border-bottom: 1px solid var(--color-hairline);
}
.shift-info-item:last-child, .gateway-fees li:last-child { border-bottom: 0; }
.shift-info-item .label, .label {
  color: var(--color-neutral-700); font-size: 12px;
  letter-spacing: .06em; text-transform: uppercase;
}
.shift-info-item .value, .value {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-variant-numeric: tabular-nums;
}

/* A section introduced by a ruled, uppercase header. */
.meal-type-section { margin-bottom: calc(var(--leading) * 1.5); }
.meal-type-header {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 12px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--color-accent); padding-bottom: 6px; margin-bottom: var(--half);
  border-bottom: 2px solid var(--color-divider);
  display: flex; align-items: center; gap: 8px;
}

.variant-badge, .duration-badge {
  display: inline-block; padding: 3px 8px; font-size: 11px;
  letter-spacing: .06em; text-transform: uppercase;
  background: var(--color-surface); color: var(--color-neutral-800);
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
}
.print-type-icon, .no-shift-icon, .card-icon, .icon {
  color: var(--color-accent); line-height: 1;
}
.no-shift-icon { font-size: 40px; margin-bottom: var(--half); display: block; }
.card-icon {
  width: 44px; height: 44px; display: flex; align-items: center;
  justify-content: center; font-size: 20px; margin-bottom: var(--half);
}

/* ------------------------------------------------------------------------
   Guard panel — a phone/tablet shell, not a desktop page: fixed header,
   fixed bottom nav, safe-area insets and deliberately large touch targets
   for someone working a gate one-handed. The layout is carried over
   unchanged from guard/base.html; only the skin is Modernist.
   ------------------------------------------------------------------------ */
:root {
  --guard-bottom-nav-height: 70px;
  --guard-header-height: 60px;
}
body.guard-shell {
  overscroll-behavior-y: contain;
  padding-top: var(--guard-header-height);
  padding-bottom: calc(var(--guard-bottom-nav-height) + env(safe-area-inset-bottom, 0px));
}
html:has(body.guard-shell) { height: 100%; }

.guard-header {
  position: fixed; top: 0; left: 0; right: 0; z-index: 1000;
  height: var(--guard-header-height);
  display: flex; align-items: center; padding: 0 var(--half);
  background: var(--color-bg); border-bottom: 2px solid var(--color-text);
}
.guard-header .society-name {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 17px; color: var(--color-text);
}
.guard-header .gate-badge {
  background: var(--color-accent); color: #fff; padding: 3px 9px;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
}

.guard-bottom-nav {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 1000;
  height: calc(var(--guard-bottom-nav-height) + env(safe-area-inset-bottom, 0px));
  padding-bottom: env(safe-area-inset-bottom, 0px);
  display: flex; justify-content: space-around; align-items: center;
  background: var(--color-bg); border-top: 2px solid var(--color-text);
}
.guard-nav-item {
  flex: 1; min-height: 60px; min-width: 70px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 8px; text-decoration: none; color: var(--color-neutral-700);
  border-top: 3px solid transparent;
}
.guard-nav-item:hover, .guard-nav-item.active {
  color: var(--color-accent); text-decoration: none; border-top-color: var(--color-accent);
}
.guard-nav-item i { font-size: 22px; margin-bottom: 3px; }
.guard-nav-item span { font-size: 11px; letter-spacing: .04em; text-transform: uppercase; }
.guard-nav-item .badge { position: absolute; top: 0; right: 50%; transform: translateX(1.5rem); }
.guard-nav-item-wrapper { position: relative; display: flex; flex-direction: column; align-items: center; }

.guard-content {
  min-height: calc(100vh - var(--guard-header-height) - var(--guard-bottom-nav-height));
  padding: var(--half) var(--half) var(--leading);
}

.guard-action-card {
  min-height: 100px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  background: var(--color-bg); border: 2px solid var(--color-divider);
  text-decoration: none; color: var(--color-text); transition: background .2s ease;
}
.guard-action-card:hover {
  background: color-mix(in srgb, var(--color-accent) 8%, var(--color-bg));
  color: var(--color-text); text-decoration: none;
}
.guard-action-card i { font-size: 34px; margin-bottom: 6px; color: var(--color-accent); }
.guard-action-card .title {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 15px;
}

.guard-session-bar {
  position: sticky; top: 0; z-index: 100;
  background: var(--color-accent); color: #fff;
}
.guard-session-bar .session-info { font-size: 13px; }
.guard-session-bar .session-timer {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-variant-numeric: tabular-nums;
}
.guard-session-bar .session-timer.warning { animation: guard-pulse 1s infinite; }
@keyframes guard-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .5; } }
.guard-session-bar .btn-end-shift {
  border-color: rgba(255,255,255,.7); color: #fff; font-size: 13px; background: transparent;
}
.guard-session-bar .btn-end-shift:hover { background: rgba(255,255,255,.14); border-color: #fff; color: #fff; }

@media (display-mode: standalone) {
  .guard-header {
    padding-top: env(safe-area-inset-top, 0px);
    height: calc(var(--guard-header-height) + env(safe-area-inset-top, 0px));
  }
  body.guard-shell { padding-top: calc(var(--guard-header-height) + env(safe-area-inset-top, 0px)); }
}
@media (max-width: 576px) {
  .guard-session-bar { flex-direction: column; gap: 8px; padding: 8px var(--half); }
  .guard-session-bar .session-info { font-size: 12px; }
  .guard-session-bar .d-flex.align-items-center:last-child { width: 100%; justify-content: space-between; }
}

/* ------------------------------------------------------------------------
   Guard roster (fm/guards/*) — six screens sharing one vocabulary: a profile
   card, a settings form, a schedule calendar and a roster list.
   ------------------------------------------------------------------------ */

/* Panels */
.filter-card, .calendar-container, .schedule-sidebar, .form-section,
.settings-section, .profile-card {
  background: var(--color-bg); border: 2px solid var(--color-divider);
  padding: var(--leading); margin-bottom: var(--leading);
}
.schedule-sidebar { height: fit-content; position: sticky; top: var(--half); }
.profile-card { padding: 0; overflow: hidden; }

/* Section headings, all the same ruled uppercase label. */
.form-section-title, .settings-section-title, .sidebar-title {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 12px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--color-accent); margin-bottom: var(--half);
  padding-bottom: 6px; border-bottom: 2px solid var(--color-divider);
}
.sidebar-title { border-bottom: 0; padding-bottom: 0; }
.form-section-title i, .settings-section-title i { margin-right: 8px; }
.settings-description, .form-check-description, .radio-card-description {
  font-size: 13px; color: var(--color-neutral-700); margin-bottom: 0;
}
.sidebar-section { margin-bottom: var(--leading); }
.sidebar-section:last-child { margin-bottom: 0; }
.required-label::after { content: " *"; color: var(--color-accent); }

/* Roster list */
.guard-photo, .guard-photo-placeholder {
  width: 48px; height: 48px; object-fit: cover;
  border-radius: 50% !important; border: 2px solid var(--color-divider);
}
.guard-photo-placeholder {
  display: flex; align-items: center; justify-content: center;
  background: var(--color-surface); color: var(--color-neutral-700); font-size: 20px;
}
.status-dot { width: 10px; height: 10px; display: inline-block; margin-right: 5px; }
.status-dot.on-duty { background: var(--color-ok); animation: guard-pulse 2s infinite; }
.status-dot.off-duty { background: var(--color-neutral-500); }

/* Profile */
.profile-header {
  background: var(--color-accent); color: #fff;
  padding: var(--leading); text-align: center;
}
.profile-photo, .profile-photo-placeholder {
  width: 120px; height: 120px; object-fit: cover;
  border-radius: 50% !important; margin: 0 auto var(--half);
  border: 3px solid rgba(255, 255, 255, .5);
}
.profile-photo-placeholder {
  display: flex; align-items: center; justify-content: center;
  background: rgba(255, 255, 255, .18); font-size: 44px; color: rgba(255, 255, 255, .85);
}
.profile-name {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 22px; margin-bottom: 2px; color: #fff;
}
.profile-agency { opacity: .9; font-size: 13px; }
.profile-body { padding: var(--leading); }
.profile-info-item {
  display: flex; align-items: flex-start; gap: 8px;
  padding: 10px 0; border-bottom: 1px solid var(--color-hairline);
}
.profile-info-item:last-child { border-bottom: 0; }
.profile-info-icon { width: 28px; color: var(--color-accent); flex: none; }
.profile-info-label {
  font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--color-neutral-700);
}
.profile-info-value { font-family: var(--font-heading); font-weight: var(--font-heading-weight); }
.duty-status, .duty-indicator { padding: var(--half); }
.duty-status.on-duty, .duty-indicator.on-duty { border-left: 3px solid var(--color-ok); background: var(--color-surface); }
.duty-status.off-duty, .duty-indicator.off-duty { border-left: 3px solid var(--color-neutral-500); background: var(--color-surface); }
.mini-table { width: 100%; font-size: 13px; }
.mini-table th {
  font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--color-neutral-700); border-bottom: 2px solid var(--color-divider);
  padding-bottom: 6px;
}

/* Photo upload target */
.photo-preview-container {
  width: 150px; height: 150px; margin: 0 auto var(--half);
  border: 2px dashed var(--color-divider); border-radius: 50% !important;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden; position: relative; cursor: pointer;
}
.photo-preview-container:hover { border-color: var(--color-accent); }
.photo-preview-container img { width: 100%; height: 100%; object-fit: cover; }
.photo-preview-placeholder { text-align: center; color: var(--color-neutral-700); }
.photo-preview-placeholder i { font-size: 34px; display: block; margin-bottom: 6px; }
.photo-input { display: none; }

/* Card-shaped radio group */
.radio-card { border: 2px solid var(--color-divider); padding: var(--half); cursor: pointer; }
.radio-card:hover { border-color: var(--color-accent); }
.radio-card.selected {
  border-color: var(--color-accent);
  background: color-mix(in srgb, var(--color-accent) 6%, transparent);
}
.radio-card input[type="radio"] { display: none; }
.radio-card-title { font-family: var(--font-heading); font-weight: var(--font-heading-weight); margin-bottom: 2px; }
.radio-indicator {
  width: 18px; height: 18px; flex-shrink: 0; position: relative;
  border: 2px solid var(--color-divider); border-radius: 50% !important;
}
.radio-card.selected .radio-indicator { border-color: var(--color-accent); }
.radio-card.selected .radio-indicator::after {
  content: ''; position: absolute; top: 50%; left: 50%;
  width: 9px; height: 9px; background: var(--color-accent);
  border-radius: 50% !important; transform: translate(-50%, -50%);
}
.slider-value {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-variant-numeric: tabular-nums; color: var(--color-accent);
}

/* Schedule calendar (FullCalendar) */
#calendar { min-height: 600px; }
.fc .fc-toolbar-title {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 20px;
}
.fc .fc-button-primary {
  background-color: var(--color-text); border-color: var(--color-text);
  font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 13px;
}
.fc .fc-button-primary:not(:disabled):active,
.fc .fc-button-primary:not(:disabled).fc-button-active {
  background-color: var(--color-accent); border-color: var(--color-accent);
}
.fc .fc-event { cursor: pointer; font-size: 12px; padding: 2px 4px; border: 0; }
.fc .fc-daygrid-event { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.legend-item { display: flex; align-items: center; margin-bottom: 6px; font-size: 13px; }
.legend-color { width: 14px; height: 14px; margin-right: 8px; flex: none; }
.legend-scheduled { background-color: var(--color-info); }
.legend-active { background-color: var(--color-ok); }
.legend-completed { background-color: var(--color-neutral-600); }
.legend-cancelled { background-color: var(--color-bad); }
.guard-checkbox { display: flex; align-items: center; gap: 8px; padding: 3px 0; }
.guard-checkbox label { font-size: 13px; margin-bottom: 0; cursor: pointer; }

/* — facility-manager console: its own mega menu and stats strip — */
.fm-mega-menu {
  position: absolute; left: 0; top: 100%; width: 100%; z-index: 1000;
  display: none; padding: var(--leading) 0;
  background: var(--color-bg); border-top: 2px solid var(--color-divider);
  border-bottom: 2px solid var(--color-text);
}
.fm-mega-menu.show { display: block; }
.fm-mega-menu-section { padding: 0 var(--half); }
.fm-mega-menu-title {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 11px; letter-spacing: .09em; text-transform: uppercase;
  color: var(--color-accent); margin-bottom: var(--half);
  padding-bottom: 6px; border-bottom: 2px solid var(--color-divider);
}
.fm-mega-menu-link {
  display: flex; align-items: center; padding: 6px 0; font-size: 14px;
  color: var(--color-text); text-decoration: none;
}
.fm-mega-menu-link:hover { color: var(--color-accent); text-decoration: none; }
.fm-mega-menu-link i { width: 24px; margin-right: 8px; color: var(--color-neutral-600); }
.fm-mega-menu-link:hover i { color: var(--color-accent); }

.fm-header-badge {
  background: var(--color-accent); color: #fff; padding: 3px 9px;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
}
.fm-quick-stats {
  background: var(--color-bg); padding: var(--half) 0;
  border-bottom: 2px solid var(--color-divider);
}
.fm-stat-item {
  display: flex; align-items: baseline; gap: 8px;
  padding: 0 var(--leading); border-right: 2px solid var(--color-divider);
}
.fm-stat-item:last-child { border-right: 0; }
.fm-stat-value {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 20px; color: var(--color-accent); font-variant-numeric: tabular-nums;
}
.fm-stat-label { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--color-neutral-700); }

/* Long selection lists get a scroll box rather than an endless page. */
.permission-checklist, .guards-list, .timeline-selection {
  max-height: 340px; overflow-y: auto;
  border: 2px solid var(--color-divider); padding: var(--half);
}
.timeline-selection .form-check { margin-bottom: 8px; }
.timeline-selection .form-check:last-child { margin-bottom: 0; }

/* — repeatable form rows (menu item variants) — */
.variant-container {
  background: var(--color-surface); border: 2px solid var(--color-divider);
  padding: var(--leading); margin-bottom: var(--half); position: relative;
}
.variant-container.is-default { border-color: var(--color-ok); }
.remove-variant { position: absolute; top: 8px; right: 8px; }
.price-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--half); }
.add-variant-btn {
  border: 2px dashed var(--color-divider); background: transparent;
  color: var(--color-neutral-700); padding: var(--leading); width: 100%;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 14px; text-align: left; cursor: pointer;
}
.add-variant-btn:hover { border-color: var(--color-accent); color: var(--color-accent); background: transparent; }
/* Progressive-disclosure hooks the form's script toggles. */
#variantsSection { display: none; }
#variantsSection.show { display: block; }
#simpleSection { display: block; }
#simpleSection.hide { display: none; }

/* — onboarding completion — */
.complete-container {
  max-width: 720px; margin: calc(var(--leading) * 2) auto;
  padding: calc(var(--leading) * 1.5); border: 2px solid var(--color-text);
  background: var(--color-bg);
}
.success-icon { font-size: 48px; color: var(--color-accent); margin-bottom: var(--half); display: block; }
.tenant-info {
  background: var(--color-accent); color: #fff;
  padding: var(--leading); margin: var(--leading) 0;
}
.tenant-info a, .tenant-info h4 { color: #fff; }
.btn-dashboard {
  display: inline-block; background: var(--color-text); color: var(--color-bg);
  border: 2px solid var(--color-text); padding: 11px 20px; margin: var(--half) 0;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 15px; text-decoration: none;
}
.btn-dashboard:hover { background: var(--color-accent); border-color: var(--color-accent); color: #fff; text-decoration: none; }
.quick-links { background: var(--color-surface); padding: var(--leading); margin-top: var(--leading); text-align: left; }
.quick-link {
  display: flex; align-items: center; gap: var(--half);
  padding: var(--half); margin-bottom: 2px;
  background: var(--color-bg); border: 2px solid var(--color-divider);
  text-decoration: none; color: var(--color-text); transition: background .2s ease;
}
.quick-link:hover {
  background: color-mix(in srgb, var(--color-accent) 7%, var(--color-bg));
  color: var(--color-text); text-decoration: none;
}
.quick-link-icon {
  background: var(--color-accent); color: #fff; width: 36px; height: 36px;
  display: flex; align-items: center; justify-content: center;
  font-size: 17px; flex-shrink: 0;
}

/* Charts need a fixed box or Chart.js grows without bound. */
.chart-container { position: relative; height: 300px; }
.chart-container canvas { max-height: 100%; }

/* Neutralised: the old language reached for lift on hover. */
.hover-shadow:hover { box-shadow: none; transform: none; }
.hover-shadow:hover, a.card:hover .card-body {
  background: color-mix(in srgb, var(--color-accent) 5%, var(--color-bg));
}

.min-vh-75 { min-height: 75vh; }
.bg-purple { background: color-mix(in srgb, var(--color-accent) 10%, transparent) !important; }
.text-purple { color: var(--color-accent) !important; }

/* fa-spin had no Bootstrap Icons equivalent, so the spinner is ours. */
.spin { display: inline-block; animation: rr-spin 1s linear infinite; }
@keyframes rr-spin { to { transform: rotate(360deg); } }

/* ------------------------------------------------------------------------
   AI assistant panel — a docked chat used by the event builder and the
   society-structure setup. Both screens carried a near-identical copy of
   this, roughly 250 lines each; it lives here once.

   The floating toggle's hint text comes from data-tip on the button, since
   the two screens label it differently.
   ------------------------------------------------------------------------ */
.ai-assistant-container {
  position: fixed; bottom: var(--leading); right: var(--leading); z-index: 1000;
  width: 400px; max-width: 90vw;
}
.ai-assistant-toggle {
  position: absolute; bottom: 0; right: 0;
  width: 56px; height: 56px; display: flex; align-items: center; justify-content: center;
  background: var(--color-accent); color: #fff; border: 0; cursor: pointer;
}
.ai-assistant-toggle:hover { background: color-mix(in srgb, var(--color-accent) 84%, #000); }
.ai-assistant-toggle i { font-size: 22px; }
.ai-assistant-toggle[data-tip]::after {
  content: attr(data-tip);
  position: absolute; bottom: -22px; left: 50%; transform: translateX(-50%);
  background: var(--color-text); color: var(--color-bg);
  padding: 3px 7px; font-size: 11px; white-space: nowrap; pointer-events: none;
}

.ai-chat-panel, .ai-event-assistant {
  display: none; position: absolute; bottom: 72px; right: 0;
  width: 100%; height: 500px; overflow: hidden;
  background: var(--color-bg); border: 2px solid var(--color-text);
}
.ai-chat-panel.active, .ai-event-assistant.active { display: flex; flex-direction: column; }

.ai-chat-header {
  background: var(--color-accent); color: #fff;
  padding: var(--half) var(--leading);
  display: flex; justify-content: space-between; align-items: center;
}
.ai-chat-header h5 {
  margin: 0; color: #fff; font-size: 15px;
  display: flex; align-items: center; gap: 10px;
}
.ai-chat-header button {
  background: transparent; border: 0; color: #fff; cursor: pointer;
  font-size: 18px; padding: 0; width: 28px; height: 28px;
  display: flex; align-items: center; justify-content: center;
}
.ai-chat-header button:hover { opacity: .8; }

.ai-chat-messages { flex: 1; overflow-y: auto; padding: var(--leading); background: var(--color-surface); }
.ai-message { margin-bottom: var(--half); display: flex; gap: 10px; }
.ai-message.user { flex-direction: row-reverse; }
.ai-message-avatar {
  width: 32px; height: 32px; flex-shrink: 0; border-radius: 50% !important;
  display: flex; align-items: center; justify-content: center;
}
.ai-message.ai .ai-message-avatar { background: var(--color-accent); color: #fff; }
.ai-message.user .ai-message-avatar { background: var(--color-neutral-300); color: var(--color-text); }
.ai-message-content {
  max-width: 80%; padding: 8px 12px; font-size: 14px; line-height: var(--leading);
  background: var(--color-bg); border: 1px solid var(--color-hairline);
}
.ai-message.user .ai-message-content { background: var(--color-accent); color: #fff; border-color: var(--color-accent); }

.ai-structure-preview, .ai-event-preview {
  margin-top: 10px; padding: var(--half);
  background: var(--color-surface); border-left: 3px solid var(--color-accent);
}
.ai-event-preview { display: none; }
.ai-event-preview.active { display: block; }
.ai-structure-preview h6, .ai-event-preview h6 {
  font-size: 12px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--color-accent); margin-bottom: 8px;
}
.ai-structure-preview .badge { margin-right: 5px; }
.preview-field { display: flex; justify-content: space-between; gap: var(--half); padding: 4px 0; font-size: 13px; }
.preview-field strong { font-family: var(--font-heading); font-weight: var(--font-heading-weight); }
.preview-field span { color: var(--color-neutral-700); }

.ai-action-buttons { margin-top: 10px; display: flex; gap: 8px; }
.ai-action-buttons button {
  padding: 6px 12px; border: 2px solid transparent; font-size: 13px; cursor: pointer;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
}
.ai-action-buttons .btn-apply { background: var(--color-ok); color: #fff; }
.ai-action-buttons .btn-reject { background: var(--color-bad); color: #fff; }
.ai-action-buttons .btn-modify, .ai-action-buttons .btn-preview {
  background: transparent; border-color: var(--color-divider); color: var(--color-text);
}
.ai-action-buttons .btn-modify:hover, .ai-action-buttons .btn-preview:hover { border-color: var(--color-text); }

.ai-chat-input { padding: var(--half); border-top: 2px solid var(--color-divider); background: var(--color-bg); }
.ai-chat-input-wrapper { display: flex; gap: 8px; }
.ai-chat-input input, .ai-chat-input textarea {
  flex: 1; padding: 9px 12px; font: inherit; font-size: 14px; resize: none;
  background: var(--color-surface); border: 1px solid var(--color-divider);
  color: var(--color-text); outline: none;
}
.ai-chat-input input:focus, .ai-chat-input textarea:focus { border-color: var(--color-accent); }
.ai-chat-input button {
  width: 38px; height: 38px; flex: none; cursor: pointer; border: 0;
  background: var(--color-accent); color: #fff;
  display: flex; align-items: center; justify-content: center;
}
.ai-chat-input button:disabled { opacity: .5; cursor: not-allowed; }
.ai-loading { display: flex; align-items: center; gap: 10px; color: var(--color-neutral-700); font-size: 13px; }

.ai-examples h6 {
  font-size: 11px; letter-spacing: .07em; text-transform: uppercase;
  color: var(--color-neutral-700); margin-bottom: 8px;
}
.ai-example-chip {
  display: inline-block; padding: 5px 10px; margin: 0 5px 5px 0; cursor: pointer;
  background: var(--color-surface); border: 1px solid var(--color-divider);
  font-size: 13px; color: var(--color-text);
}
.ai-example-chip:hover { border-color: var(--color-accent); color: var(--color-accent); }

/* Dims the form behind the docked assistant without hiding it. */
.form-overlay {
  position: fixed; top: 0; left: 0; right: 450px; bottom: 0; z-index: 1049;
  background: rgba(32, 30, 29, .18); opacity: 0; pointer-events: none;
  transition: opacity .3s ease;
}
.form-overlay.active { opacity: 1; pointer-events: auto; }

@media (max-width: 768px) {
  .ai-event-assistant { width: 100vw; right: -100vw; }
  .form-overlay { right: 0; }
  .ai-assistant-toggle[data-tip]::after { display: none; }
}

/* ------------------------------------------------------------------------
   Coupon scanning console — worked one-handed at a bhog counter, so the
   touch targets stay large. Full-bleed on a phone, a panel on a tablet.
   ------------------------------------------------------------------------ */
.main-content { padding-top: 0; background: var(--color-bg); min-height: calc(100vh - 56px); }
.scanner-container { max-width: 100%; padding: 0; }
.scanner-card { background: var(--color-bg); border: 0; margin-bottom: 10px; }
.scanner-header {
  background: var(--color-accent); color: #fff;
  padding: var(--leading); text-align: center;
}
.scanner-header h1, .scanner-header h2, .scanner-header h3, .scanner-header h5 { color: #fff; }
@media (min-width: 768px) {
  .scanner-container { max-width: 600px; margin: var(--leading) auto; padding: 0 var(--leading); }
  .scanner-card { border: 2px solid var(--color-divider); overflow: hidden; }
}
#qr-reader { width: 100% !important; max-width: 500px; margin: 0 auto; }
#qr-reader video { width: 100% !important; height: auto !important; }

.scan-btn, .manual-entry-btn {
  min-height: 48px; padding: 11px 24px; margin: 5px; font-size: 16px;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
}
.manual-entry-btn { background: var(--color-bg); border: 2px solid var(--color-divider); color: var(--color-text); }
.manual-entry-btn:hover { border-color: var(--color-accent); color: var(--color-accent); }
#startScan { background: var(--color-accent); border: 2px solid var(--color-accent); color: #fff; }
#stopScan { background: transparent; border: 2px solid var(--color-divider); color: var(--color-text); }

/* Deliberately oversized: this is tapped while holding a plate. */
.action-btn, .primary-btn {
  width: 100%; min-height: 68px; margin-bottom: 10px; border: 0;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 18px; position: relative; overflow: hidden;
}
.primary-btn, .deliver-btn { background: var(--color-accent); color: #fff; }
.distribute-btn { background: var(--color-ok); color: #fff; }
/* A downgrade is the unusual choice, so it is visibly the quieter one. */
.downgrade-btn {
  min-height: 48px; font-size: 15px;
  background: transparent; border: 2px solid var(--color-warn); color: var(--color-warn);
}
.downgrade-btn:hover { background: var(--color-warn); color: #fff; }

.info-badge, .delivery-badge {
  display: inline-block; padding: 4px 9px; margin: 2px; color: #fff;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 11px; letter-spacing: .05em; text-transform: uppercase;
}
.delivery-badge-sit-eat { background: var(--color-info); }
.delivery-badge-parcel { background: var(--color-warn); }

.recent-scans-card { background: var(--color-bg); border: 2px solid var(--color-divider); overflow: hidden; }
.recent-scans-header {
  background: var(--color-accent); color: #fff; padding: var(--half);
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 12px; letter-spacing: .07em; text-transform: uppercase;
}
.scan-history-item { padding: var(--half); border-bottom: 1px solid var(--color-hairline); }
.scan-history-item:hover { background: color-mix(in srgb, var(--color-accent) 5%, transparent); }
.scan-history-item:last-child { border-bottom: 0; }

.result-card { animation: scan-slide-in .3s ease-out; }
@keyframes scan-slide-in { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: none; } }
/* A rejected coupon has to be unmistakable across a noisy counter. */
.error-message { animation: scan-shake .5s; }
@keyframes scan-shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-10px); }
  75% { transform: translateX(10px); }
}

/* — society setup wizard — the screen a committee meets on day one — */
.setup-container {
  max-width: 720px; margin: calc(var(--leading) * 2) auto;
  padding: calc(var(--leading) * 1.5); background: var(--color-bg);
  border: 2px solid var(--color-text);
}
.setup-header {
  margin-bottom: calc(var(--leading) * 1.5); padding-bottom: var(--leading);
  border-bottom: 2px solid var(--color-divider);
}
.setup-icon { font-size: 44px; color: var(--color-accent); margin-bottom: var(--half); display: block; }
.setup-title {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: clamp(26px, 4vw, 36px); line-height: 1.06; margin-bottom: 6px;
}
.setup-subtitle { color: var(--color-neutral-700); font-size: 16px; margin: 0; }
.form-section {
  background: var(--color-surface); padding: var(--leading);
  margin-bottom: var(--leading); border: 0; border-left: 3px solid var(--color-accent);
}
.form-section h5 {
  font-size: 13px; letter-spacing: .07em; text-transform: uppercase;
  color: var(--color-accent); margin-bottom: var(--half);
  display: flex; align-items: center;
}
.form-section h5 i { margin-right: 8px; }
.help-text { font-size: 13px; color: var(--color-neutral-700); }
.examples-box { background: var(--color-surface); padding: var(--half) var(--leading); }
.example-item { padding: 6px 0; border-bottom: 1px solid var(--color-hairline); font-size: 14px; }
.example-item:last-child { border-bottom: 0; }
.example-item strong { font-family: var(--font-heading); font-weight: var(--font-heading-weight); }
.example-item em { color: var(--color-neutral-700); font-style: normal; }

.btn-setup {
  width: 100%; min-height: 52px; padding: var(--half) var(--leading);
  background: var(--color-accent); border: 2px solid var(--color-accent); color: #fff;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 15px; letter-spacing: .06em; text-transform: uppercase; text-align: left;
}
.btn-setup:hover { background: color-mix(in srgb, var(--color-accent) 84%, #000); color: #fff; }
.btn-setup:disabled { opacity: .5; cursor: not-allowed; }
.ai-button {
  padding: 9px 16px; min-height: 40px;
  background: transparent; border: 2px solid var(--color-divider); color: var(--color-text);
  font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 14px;
}
.ai-button:hover { border-color: var(--color-accent); color: var(--color-accent); }
.ai-button:disabled { opacity: .5; cursor: not-allowed; }
@media (max-width: 576px) {
  .setup-container { margin: var(--half); padding: var(--half); }
  .ai-button { width: 100%; margin-bottom: 8px; }
  .mt-3.d-flex.gap-2 { flex-direction: column !important; }
}

.structure-preview {
  background: var(--color-bg); border: 2px solid var(--color-divider);
  padding: var(--leading); margin-top: var(--leading);
}
.structure-preview .preview-header {
  background: var(--color-accent); color: #fff;
  padding: 8px var(--half); margin: calc(var(--leading) * -1) calc(var(--leading) * -1) var(--half);
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 12px; letter-spacing: .07em; text-transform: uppercase;
  display: flex; align-items: center;
}
.structure-preview .preview-header i { margin-right: 8px; }
.structure-summary {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 17px; margin-bottom: var(--half);
}
.structure-details { font-size: 14px; color: var(--color-neutral-700); }
.loading-message { font-size: 14px; color: var(--color-neutral-700); }

/* — society structure preview: towers and their flats — */
.towers-detail-section h6, .structure-summary-section h6 {
  font-size: 12px; letter-spacing: .07em; text-transform: uppercase;
  color: var(--color-accent); margin-bottom: var(--half);
}
.tower-detail-card {
  background: var(--color-bg); border: 2px solid var(--color-divider);
  padding: var(--half); margin-bottom: 8px;
}
.tower-detail-card:hover { background: color-mix(in srgb, var(--color-accent) 5%, var(--color-bg)); }
.tower-detail-card.more-towers { border-style: dashed; color: var(--color-neutral-700); }
.tower-header { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.tower-header strong { font-family: var(--font-heading); font-weight: var(--font-heading-weight); }
.tower-specs { font-size: 12px; color: var(--color-neutral-700); }
.flat-samples, .flat-numbers { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
.flat-chip, .flat-chip-more {
  padding: 2px 7px; font-size: 11px; font-variant-numeric: tabular-nums;
  background: var(--color-surface); border: 1px solid var(--color-hairline);
}
.flat-chip-more { color: var(--color-neutral-600); }

/* An event with no photograph gets a ruled panel, not a gradient. */
.event-image-placeholder {
  height: 200px;
  background: var(--color-surface);
  border-bottom: 2px solid var(--color-divider);
  color: var(--color-neutral-400);
}
.event-image-placeholder i { font-size: 48px; }

/* — empty states — */
.empty-state {
  border: 2px dashed var(--color-divider); padding: calc(var(--leading) * 1.5);
  text-align: left; color: var(--color-neutral-700);
}
.empty-state h3 { font-size: 18px; margin: 0 0 6px; color: var(--color-text); }
.empty-state p { margin: 0 0 var(--half); font-size: 14px; }

@media (max-width: 768px) {
  .card-body, .modal-body { padding: var(--half); }
  .table { font-size: 13px; }
  .stat-cell { border-left: 0; padding-left: 0; }
}

/* — QR scanner: a camera viewport with a reticle. Receipts and passes get
     scanned at a gate or a bhog counter, so the frame stays high contrast. — */
#scanner-container, .manual-input { position: relative; max-width: 400px; margin: 0 auto; }
#video-container { position: relative; overflow: hidden; background: #000; border: 2px solid var(--color-text); }
#qr-video { width: 100%; display: block; }
/* Scoped to the guard viewport: the kiosk screen uses the same class name for
   a wrapper whose ::after draws the reticle, so an unscoped rule collides. */
#video-container .scanner-overlay {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 200px; height: 200px;
  border: 3px solid var(--color-accent);
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, .55);
}

/* — timeline marker variant: some screens place their own dot, so the
     automatic one must stand down or they double up. — */
.timeline-item:has(.timeline-marker)::before,
.timeline-item:has(.timeline-marker)::after { display: none; }
.timeline:has(.timeline-marker) { padding-left: 30px; }
.timeline:has(.timeline-marker)::before {
  content: ''; position: absolute; left: 9px; top: 0; bottom: 0;
  width: 2px; background: var(--color-divider);
}
.timeline-marker {
  position: absolute; left: -25px; top: 5px; width: 12px; height: 12px;
  background: var(--color-accent); border-radius: 50% !important;
  box-shadow: 0 0 0 3px var(--color-bg);
}
/* The committee screens run the same timeline vertically with its own rail. */
.timeline-vertical { position: relative; padding-left: 40px; }
.timeline-vertical::before {
  content: ''; position: absolute; left: 15px; top: 0; bottom: 0;
  width: 2px; background: var(--color-divider);
}
.timeline-vertical .timeline-item { position: relative; padding-bottom: var(--leading); }
.timeline-vertical .timeline-item:last-child { padding-bottom: 0; }
.timeline-vertical .timeline-marker { left: -30px; width: 14px; height: 14px; }
.timeline-content { background: var(--color-surface); padding: var(--half); }

/* — month calendar — */
.calendar-table { min-height: 500px; }
.calendar-table td { height: 100px; vertical-align: top; position: relative; }
.calendar-day { padding: 8px; }
.calendar-day.other-month { background: var(--color-surface); color: var(--color-neutral-600); }
.calendar-day.today { box-shadow: inset 0 3px 0 0 var(--color-accent); }
.calendar-day.today .day-number { color: var(--color-accent); }
.day-number {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-variant-numeric: tabular-nums; margin-bottom: 4px;
}
.events { overflow-y: auto; max-height: 70px; }
.event-link { display: block; margin-bottom: 2px; font-size: 12px; text-decoration: none; }
.event-link:hover { text-decoration: underline; }

/* — checkout: pick a payment method — */
.payment-method-option { position: relative; }
.payment-method-label { display: block; cursor: pointer; }
.payment-method-label input[type="radio"] { position: absolute; opacity: 0; }
.payment-method-card {
  border: 2px solid var(--color-divider); padding: var(--half);
  background: var(--color-bg); transition: background .2s ease, border-color .2s ease;
}
.payment-method-card:hover { border-color: var(--color-text); }
.payment-method-label input[type="radio"]:checked + .payment-method-card {
  border-color: var(--color-accent);
  background: color-mix(in srgb, var(--color-accent) 6%, var(--color-bg));
}
.payment-icon {
  width: 48px; height: 48px; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: var(--color-surface); color: var(--color-accent); font-size: 20px;
}

/* Printing is how a receipt, bill or pass leaves the building. */
@media print {
  .navbar, footer, .btn, .btn-group, .alert, .card-footer, .no-print,
  .guard-bottom-nav, .guard-header, .fm-quick-stats { display: none !important; }
  body { background: #fff; color: #000; }
  .container, .container-fluid { max-width: none !important; }
  .card { border: 1px solid #000 !important; box-shadow: none !important; }
  a[href]::after { content: ""; }
}
