@font-face {
  font-family: "Anton";
  src: url("/static/fonts/Anton-Regular.ttf") format("truetype");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Aileron";
  src: url("/static/fonts/Aileron-Regular.otf") format("opentype");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Aileron";
  src: url("/static/fonts/Aileron-Light.otf") format("opentype");
  font-weight: 300;
  font-display: swap;
}
@font-face {
  font-family: "Aileron";
  src: url("/static/fonts/Aileron-SemiBold.otf") format("opentype");
  font-weight: 600;
  font-display: swap;
}
@font-face {
  font-family: "Aileron";
  src: url("/static/fonts/Aileron-Bold.otf") format("opentype");
  font-weight: 700;
  font-display: swap;
}
@font-face {
  font-family: "Aileron";
  src: url("/static/fonts/Aileron-Black.otf") format("opentype");
  font-weight: 900;
  font-display: swap;
}
@font-face {
  font-family: "Aileron";
  src: url("/static/fonts/Aileron-Italic.otf") format("opentype");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

:root {
  --am-red: #ed1c24;
  --am-black: #231f20;
  --am-white: #ffffff;
  --am-orange: #f7941d;
  --am-gray-100: #f1f2f2;
  --am-gray-300: #d1d3d4;
  --am-gray-500: #939598;
  --am-gray-700: #58595b;
  --am-green: #1a9c4c;
  --am-amber: #f7941d;
  --am-dark-red: #a3151a;
  --am-dark-orange: #c2720a;

  /* Red for button fills: #e01a22 looks the same as the brand red but white text on it passes contrast (4.84:1).
     Red for text on white: #d0141b (5.3:1). The logo and accents keep --am-red. (Amr, 2026-10-05) */
  --am-red-btn: #e01a22;
  --am-red-text: #d0141b;
  /* Text versions of the other base colours: 4.5:1 or more on white, light grey and their own pale tint.
     The base colours stay for dots, stripes, borders and fills. (UI audit 2026-10-06) */
  --am-green-text: #0f6e33;
  --am-warn-text: #8a4b00;

  --font-display: "Anton", "Arial Narrow", sans-serif;
  --font-body: "Aileron", "Helvetica Neue", Arial, sans-serif;

  --radius: 10px;
  --shadow: 0 2px 10px rgba(35, 31, 32, 0.08);
}

* { box-sizing: border-box; }

/* The [hidden] attribute must always win over any component class that sets
   its own display (e.g. .form-row, .type-pill-group) — without !important,
   an author-stylesheet class beats the browser's default [hidden]{display:none}
   UA rule regardless of selector specificity, since UA styles are lowest
   priority in the cascade. Toggle visibility via the hidden property/attribute
   everywhere, never a manual style.display, and this rule keeps it reliable. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--am-gray-100);
  color: var(--am-black);
  font-family: var(--font-body);
  font-size: 15px;
}

h1, h2, h3, .display {
  font-family: var(--font-display);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--am-black);
  margin: 0 0 0.5em;
}
/* Anton capitals are for big page and section titles only (h1, h2, .display). Card titles (h3) are
   labels: Aileron bold, normal case, so a page isn't a wall of capitals. (Amr, 2026-10-05) */
h3:not(.display) { font-family: var(--font-body); font-weight: 700; font-size: 16px; letter-spacing: 0; text-transform: none; }

/* Form controls use the app font (some fell back to Arial), and ticks / radios / sliders are brand red. */
button, input, select, textarea { font-family: inherit; }
:root { accent-color: var(--am-red); }

/* One visible focus ring for keyboard users everywhere (buttons and links had only the faint browser ring). */
:where(a, button, [tabindex], summary, input, select, textarea, .btn):focus-visible { outline: 2px solid var(--am-red); outline-offset: 2px; }
.sidebar :focus-visible, .mobile-topbar :focus-visible { outline-color: var(--am-white); }
.btn-primary:focus-visible { outline-color: var(--am-black); }

/* "Skip to content": first thing a keyboard user reaches, jumps past the sidebar */
.skip-link { position: absolute; left: -9999px; top: 0; z-index: 300; background: var(--am-black); color: var(--am-white); padding: 0.6rem 1rem; font-weight: 700; }
.skip-link:focus { left: 0.5rem; top: 0.5rem; }

a { color: var(--am-red-text); text-decoration: none; }
a:hover { text-decoration: underline; }

.app-shell {
  display: flex;
  min-height: 100vh;
}

.sidebar {
  width: 220px;
  background: var(--am-black);
  color: var(--am-white);
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  padding: 1.25rem 0;
}

.sidebar .brand {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0 1.25rem 1.25rem;
  border-bottom: 1px solid rgba(255,255,255,0.12);
  margin-bottom: 0.75rem;
}
.sidebar .brand img { height: 34px; width: auto; }
.sidebar .brand .tagline {
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--am-gray-300);
}

.sidebar nav { display: flex; flex-direction: column; }
.sidebar nav a {
  display: flex;
  align-items: center;
  color: var(--am-gray-300);
  padding: 0.65rem 1.25rem;
  font-size: 14px;
  font-weight: 600;
  border-left: 3px solid transparent;
}
.sidebar nav a:hover { color: var(--am-white); text-decoration: none; background: rgba(255,255,255,0.06); }
.sidebar nav a.active {
  color: var(--am-white);
  border-left-color: var(--am-red);
  background: rgba(237,28,36,0.15);
}

.sidebar nav .nav-item { position: relative; margin-top: 0.2rem; cursor: grab; }
.sidebar nav .nav-item:first-child { margin-top: 0; }
.sidebar nav .nav-drag-handle {
  position: absolute;
  left: 0.15rem;
  top: 50%;
  transform: translateY(-50%);
  color: var(--am-gray-300);
  opacity: 0.3;
  cursor: grab;
  font-size: 13px;
  padding: 0.1rem 0.3rem;
  user-select: none;
  z-index: 1;
}
.sidebar nav .nav-item:hover .nav-drag-handle { opacity: 0.9; }
.sidebar nav .nav-drag-handle:hover { opacity: 1 !important; }
.sidebar nav .nav-item.nav-dragging { opacity: 0.4; }
.sidebar nav .nav-item.nav-drag-over { box-shadow: inset 0 2px 0 var(--am-red); }

.sidebar nav .nav-group-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: var(--am-gray-300);
  padding: 0.65rem 1.25rem;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  border-left: 3px solid transparent;
  /* it's a <button> now (keyboard can open it): strip the button look */
  background: none; border-top: 0; border-right: 0; border-bottom: 0; width: 100%; font-family: inherit; text-align: left;
}
.sidebar nav .nav-group-toggle:hover { color: var(--am-white); background: rgba(255,255,255,0.06); }
.sidebar nav .nav-group-toggle.nav-drag-over { box-shadow: inset 0 2px 0 var(--am-red); background: rgba(255,255,255,0.06); }
.sidebar nav .nav-group-body { display: flex; flex-direction: column; }
.sidebar nav .nav-group-body a { padding-left: 2.5rem; font-size: 13px; }

.sidebar nav .nav-subitem { position: relative; cursor: grab; }
.sidebar nav .nav-subitem .nav-drag-handle { left: 1.4rem; font-size: 11px; }
.sidebar nav .nav-subitem:hover .nav-drag-handle { opacity: 0.9; }
.sidebar nav .nav-subitem.nav-dragging { opacity: 0.4; }
.sidebar nav .nav-subitem.nav-drag-over { box-shadow: inset 0 2px 0 var(--am-red); }

/* side menu search (nav-search.js) */
.sidebar .nav-search { position: relative; margin: 0 0.5rem 0.75rem; }
.sidebar .nav-search input {
  box-sizing: border-box; width: 100%; height: var(--ctl-h, 40px); min-height: var(--ctl-h, 40px); margin: 0;
  padding: 0 2.4rem 0 2.25rem;
  background: rgba(255,255,255,0.08); color: var(--am-white);
  border: 1px solid rgba(255,255,255,0.16); border-radius: 8px;
  font: 400 14px/1.3 var(--font-body, inherit);
  -webkit-appearance: none; appearance: none;
}
.sidebar .nav-search input::placeholder { color: var(--am-gray-300); opacity: 0.75; }
.sidebar .nav-search input:hover { border-color: rgba(255,255,255,0.32); }
.sidebar .nav-search input:focus { outline: none; border-color: var(--am-white); background: rgba(255,255,255,0.12); }
.sidebar .nav-search input:focus-visible { outline: 2px solid var(--am-red); outline-offset: 1px; }
.sidebar .nav-search-clear:focus-visible { outline-offset: -2px; }
.sidebar .nav-search input::-webkit-search-cancel-button { -webkit-appearance: none; display: none; }
.sidebar .nav-search-icon { position: absolute; left: 0.75rem; top: calc(var(--ctl-h, 40px) / 2); transform: translateY(-50%); color: var(--am-gray-300); pointer-events: none; }
.sidebar .nav-search-clear {
  position: absolute; right: 2px; top: 2px; width: calc(var(--ctl-h, 40px) - 4px); height: calc(var(--ctl-h, 40px) - 4px);
  display: none; align-items: center; justify-content: center; padding: 0; border: 0; border-radius: 6px;
  background: none; color: var(--am-gray-300); font-size: 20px; line-height: 1; cursor: pointer;
}
.sidebar .nav-search.has-text .nav-search-clear { display: inline-flex; }
.sidebar .nav-search-clear:hover { color: var(--am-white); background: rgba(255,255,255,0.1); }
.sidebar .nav-search-empty { margin: 0.6rem 0.75rem 0; color: var(--am-gray-300); font-size: 13px; }
.sidebar .nav-search .visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.sidebar nav.is-searching .nav-drag-handle { display: none; }
.sidebar nav.is-searching .nav-item, .sidebar nav.is-searching .nav-subitem { cursor: default; }
.sidebar nav a.nav-hit, body.sk-app .sidebar #main-nav a.nav-hit {   /* beats staff-kit's a.active: the lit match must show even on the open page */ color: var(--am-white); background: rgba(255,255,255,0.16); box-shadow: inset 3px 0 0 var(--am-white); border-radius: 8px; }
@media (max-width: 768px) { .sidebar .nav-search input { font-size: 16px; } }   /* 16px: iPhone doesn't zoom in on tap */

.sidebar-footer {
  margin-top: auto;
  padding: 1rem 1.25rem;
  border-top: 1px solid rgba(255,255,255,0.12);
}

.main {
  flex: 1;
  /* A flex child's default min-width is its content's width, so one wide
     table used to stretch the whole page sideways on a laptop screen. */
  min-width: 0;
  padding: 1.75rem 2rem;
  max-width: 1500px;
}

/* Wide tables scroll inside their own box instead of widening the page. */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }

.topbar {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 1.5rem;
}

.card {
  background: var(--am-white);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.25rem 1.5rem;
  margin-bottom: 1.25rem;
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 14px;
  line-height: 1.2;
  border: none;
  border-radius: 8px;
  padding: 0.55rem 1.1rem;
  cursor: pointer;
  background: var(--am-black);
  color: var(--am-white);
  white-space: nowrap;
  vertical-align: middle;
}
.btn:hover { opacity: 0.9; text-decoration: none; }
.btn-primary { background: var(--am-red-btn); color: var(--am-white); }
.btn-outline { background: transparent; color: var(--am-black); border: 1.5px solid var(--am-gray-300); }
.btn-danger { background: #c0212b; color: var(--am-white); }
.btn-sm { padding: 0.35rem 0.75rem; font-size: 12px; }

table { width: 100%; border-collapse: collapse; }
th, td { text-align: left; padding: 0.6rem 0.5rem; border-bottom: 1px solid var(--am-gray-100); font-size: 14px; }
th { font-size: 12px; font-weight: 700; color: var(--am-gray-700); }
table[data-sortable] th[data-sort] { user-select: none; }
table[data-sortable] th[data-sort]:hover { color: var(--am-black); }
table[data-sortable] th.sorted-asc::after { content: " \25B2"; font-size: 9px; }
table[data-sortable] th.sorted-desc::after { content: " \25BC"; font-size: 9px; }

.badge { display: inline-block; padding: 0.2rem 0.55rem; border-radius: 999px; font-size: 12px; font-weight: 700; }
/* A category chip's pill shape only fits its short collapsed label — once
   clicked open to show edit/deactivate/delete controls, it needs normal
   rectangular corners instead of a huge stretched-pill radius. */
.badge.chip-open { border-radius: 10px; display: block; padding: 0.6rem 0.75rem; }
.badge-green { background: rgba(26,156,76,0.14); color: var(--am-green-text); }
.badge-amber { background: rgba(247,148,29,0.16); color: #9a5500; }
.badge-orange { background: rgba(247,148,29,0.18); color: var(--am-warn-text); }
.badge-red { background: rgba(237,28,36,0.14); color: #b3141b; }
.badge-dark-red { background: rgba(163,21,26,0.14); color: var(--am-dark-red); }
.badge-dark-orange { background: rgba(194,114,10,0.16); color: #7a3e00; }
.badge-gray { background: var(--am-gray-100); color: var(--am-gray-700); }
.badge-blue { background: rgba(37,99,235,0.12); color: #1d4ed8; }

label { display: block; font-size: 13px; font-weight: 600; margin: 0.7rem 0 0.25rem; }
input, select, textarea {
  width: 100%;
  padding: 0.5rem 0.6rem;
  border: 1.5px solid var(--am-gray-300);
  border-radius: 6px;
  font-family: var(--font-body);
  font-size: 14px;
  background: var(--am-white);
}
input:focus, select:focus, textarea:focus { outline: 2px solid var(--am-red); border-color: var(--am-red); }
/* flex:1 alone has a 0 basis, so a row with many fields shrinks every one
   of them arbitrarily thin to fit on a single line instead of wrapping.
   Labeled field wrappers (the standard <div><label>…</label><input …>
   pattern used throughout) get a real minimum width so a crowded row
   wraps onto a second line instead, keeping every box wide enough to
   actually type and read in. Scoped to labeled wrappers specifically
   (not every .form-row child) so it doesn't touch the app's other use
   of .form-row: a tight inline sentence like "every [70px] day(s)" or
   a flex:0 button wrapper, both of which rely on staying compact. */
.form-row { display: flex; gap: 1rem; flex-wrap: wrap; }
.form-row > * { flex: 1; }
/* max-width caps how far a field can grow to fill leftover row space —
   without it, a lone field wrapping onto an otherwise-empty row (e.g. a
   "Calendar Color" field with nothing after it) stretches to fill the
   entire row by itself, looking broken rather than just wrapped. */
.form-row > div:has(> label) { flex: 1 1 240px; min-width: 240px; max-width: 360px; }

.status-msg { padding: 0.6rem 0.9rem; border-radius: 8px; font-weight: 600; margin-bottom: 1rem; }
.status-ok { background: rgba(26,156,76,0.12); color: var(--am-green-text); }
.status-err { background: rgba(237,28,36,0.12); color: #b3141b; }
.status-warn { background: rgba(247,148,29,0.14); color: var(--am-warn-text); }

.scan-box {
  font-size: 22px;
  padding: 1rem;
  text-align: center;
  border: 2px dashed var(--am-gray-300);
}

.searchable-select { position: relative; }
.search-results {
  position: absolute; top: 100%; left: 0; right: 0; z-index: 50;
  background: var(--am-white); border: 1.5px solid var(--am-gray-300); border-top: none;
  border-radius: 0 0 8px 8px; max-height: 280px; overflow-y: auto;
  box-shadow: var(--shadow);
}
.search-result-row {
  display: flex; justify-content: space-between; align-items: center; gap: 0.75rem;
  padding: 0.5rem 0.75rem; cursor: pointer; border-bottom: 1px solid var(--am-gray-100);
}
.search-result-row:last-child { border-bottom: none; }
.search-result-row:hover, .search-result-row.highlighted { background: var(--am-gray-100); }
.search-result-row .result-name { font-weight: 600; }
.search-result-row .result-summary { font-size: 12px; color: var(--am-gray-700); }
.search-result-empty { padding: 0.75rem; color: var(--am-gray-700); font-size: 13px; }

.checkin-result { display: flex; align-items: center; gap: 1.25rem; padding: 1.5rem; border-radius: var(--radius); }
.checkin-result.green { background: rgba(26,156,76,0.12); }
.checkin-result.amber { background: rgba(247,148,29,0.14); }
.checkin-result.red { background: rgba(237,28,36,0.12); }
.checkin-result.visit { background: rgba(88,89,91,0.12); }
.checkin-result .credits-num { font-family: var(--font-display); font-size: 42px; line-height: 1; }

.type-pill-group { display: flex; gap: 0.5rem; flex-wrap: wrap; margin: 0.5rem 0 1rem; }
.type-pill {
  border: 1.5px solid var(--am-gray-300);
  background: var(--am-white);
  padding: 0.45rem 0.9rem;
  border-radius: 999px;
  font-weight: 600;
  font-size: 13px;
  cursor: pointer;
}
.type-pill.selected { background: var(--am-black); color: var(--am-white); border-color: var(--am-black); }

.sp-add-box:not([hidden]) { display: flex; gap: 0.4rem; margin-top: 0.4rem; }

.avatar { border-radius: 50%; object-fit: cover; flex: none; }
.avatar-sm { width: 32px; height: 32px; }
.avatar-md { width: 42px; height: 42px; }
.avatar-lg { width: 64px; height: 64px; }
.avatar-xl { width: 140px; height: 140px; }
.avatar-placeholder {
  display: flex; align-items: center; justify-content: center;
  background: var(--am-black); color: var(--am-white);
  font-family: var(--font-display); font-size: 1.4em;
}
.avatar-placeholder.avatar-sm { font-size: 1em; }
.avatar-placeholder.avatar-md { font-size: 1.2em; }
.avatar-placeholder.avatar-xl { font-size: 3em; }

/* Photo/color cards — the Services page's look, reused anywhere a
   package/session-type choice benefits from the same "photo or color
   background, white text overlay" treatment (e.g. the Personal
   Appointments booking wizard's "Pick a Session" step). */
.services-grid { display:grid; grid-template-columns:repeat(auto-fill, minmax(180px, 1fr)); gap:1rem; margin-top:0.5rem; }
.service-card {
  position:relative; border-radius:16px; overflow:hidden; min-height:230px;
  background-size:cover; background-position:center;
  box-shadow:0 2px 8px rgba(0,0,0,0.15);
  display:flex; align-items:flex-end;
}
.service-card-body { padding:1rem; width:100%; color:var(--am-white); }
.service-card-type { font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:0.06em; opacity:0.85; margin-bottom:0.15rem; }
.service-card-name { font-family:var(--font-display); font-size:22px; line-height:1.05; text-transform:uppercase; margin-bottom:0.5rem; word-break:break-word; }
.service-card-meta { font-size:12px; opacity:0.9; display:flex; gap:0.4rem; margin-bottom:0.3rem; }
.service-card-price { font-family:var(--font-display); font-size:20px; }

.cover-photo-preview {
  width: 220px; height: 110px; border-radius: 10px; object-fit: cover; flex: none;
  display: flex; align-items: center; justify-content: center;
}
.cover-photo-preview.avatar-placeholder { background: var(--am-black); color: var(--am-white); font-family: var(--font-display); font-size: 1.4em; }

.search-result-row .result-avatar { flex-shrink: 0; }
.search-result-row .result-text { flex: 1; min-width: 0; display: flex; flex-direction: column; }

/* Photo widget: bigger clickable avatar + a real "Upload Photo" button (the ugly
   native file-input chrome is hidden and triggered by the styled label instead). */
.photo-widget { display: flex; align-items: center; justify-content: center; gap: 1rem; flex-wrap: wrap; }
.avatar-view-trigger { cursor: zoom-in; border: none; background: none; padding: 0; }
.photo-upload-btn { position: relative; overflow: hidden; display: inline-flex; cursor: pointer; }
.photo-upload-btn input[type="file"] {
  position: absolute; inset: 0; opacity: 0; cursor: pointer; width: 100%; height: 100%;
}

/* Full-size lightbox */
.lightbox-overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,0.85); z-index: 1000;
  display: flex; align-items: center; justify-content: center; cursor: zoom-out;
}
.lightbox-overlay img { max-width: 90vw; max-height: 90vh; border-radius: 8px; }
.lightbox-overlay .lightbox-close {
  position: absolute; top: 1.5rem; right: 1.5rem; color: var(--am-white);
  font-size: 28px; font-weight: 700; cursor: pointer; line-height: 1; background: none; border: none;
}

/* Crop modal */
.cropper-overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,0.7); z-index: 1000;
  display: flex; align-items: center; justify-content: center;
}
.cropper-box {
  background: var(--am-white); border-radius: var(--radius); padding: 1.5rem;
  box-shadow: var(--shadow); width: 360px; max-width: 92vw;
}
.cropper-frame {
  width: 280px; height: 280px; margin: 0 auto; border-radius: 50%; overflow: hidden;
  background: var(--am-gray-100); position: relative; cursor: grab; touch-action: none;
}
.cropper-frame.dragging { cursor: grabbing; }
.cropper-frame img { position: absolute; top: 0; left: 0; transform-origin: 0 0; user-select: none; -webkit-user-drag: none; }
.cropper-controls { display: flex; align-items: center; gap: 0.6rem; margin-top: 1rem; }
.cropper-controls input[type="range"] { flex: 1; }
.cropper-actions { display: flex; justify-content: flex-end; gap: 0.5rem; margin-top: 1.25rem; }

/* Camera capture modal — shares .cropper-overlay/.cropper-box/.cropper-actions
   for the chrome, but its own frame (rectangular, not the crop tool's circle —
   clipping the live preview to a circle would make it hard to aim the shot). */
.camera-frame {
  width: 320px; height: 320px; margin: 0 auto; border-radius: var(--radius);
  overflow: hidden; background: #000; display: flex; align-items: center; justify-content: center;
}
.camera-frame video { width: 100%; height: 100%; object-fit: cover; }

/* Client tags */
.tag-pills { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-bottom: 0.5rem; }
.tag-pill {
  display: inline-flex; align-items: center; gap: 0.3rem;
  background: var(--am-gray-100); border: 1px solid var(--am-gray-300); border-radius: 999px;
  padding: 0.2rem 0.5rem 0.2rem 0.7rem; font-size: 12px; font-weight: 600; color: var(--am-black);
}
.tag-pill button {
  background: none; border: none; cursor: pointer; color: var(--am-gray-700); font-size: 14px;
  line-height: 1; padding: 0 0.15rem;
}
.tag-pill button:hover { color: var(--am-red-text); }

/* Read-only info display, paired with a toggled edit form */
.info-grid { display: flex; flex-wrap: wrap; gap: 1.5rem; align-items: flex-start; }
.info-field .info-label { font-size: 12px; color: var(--am-gray-700); margin-bottom: 0.15rem; }
.info-field .info-value { font-size: 15px; font-weight: 600; }
.edit-section { display: none; margin-top: 1.25rem; padding-top: 1.25rem; border-top: 1px solid var(--am-gray-300); }
.edit-section.open { display: block; }
.freeze-row.open, .refund-row.open { display: table-row !important; }

/* "⋮" action dropdown — see action-menu.js for the markup contract. */
.action-menu { position: relative; display: inline-block; }
.action-menu-list {
  display: none;
  position: absolute; top: 100%; left: 0; margin-top: 4px; z-index: 50;
  background: var(--am-white); border: 1px solid var(--am-gray-300); border-radius: var(--radius);
  box-shadow: var(--shadow); min-width: 200px; padding: 0.4rem; flex-direction: column; gap: 2px;
}
/* A plain ".action-menu-list { display: flex }" would tie in specificity
   with the browser's own "[hidden] { display: none }" rule and — since an
   author stylesheet always wins that tie — silently defeat the hidden
   attribute the moment this file loads. This selector is one level more
   specific than [hidden] on its own, so it reliably wins only when hidden
   is actually absent. */
.action-menu-list:not([hidden]) { display: flex; }
.action-menu-list form { margin: 0; }
.action-menu-list button, .action-menu-list a {
  display: block; width: 100%; text-align: left; background: none; border: none;
  padding: 0.5rem 0.6rem; border-radius: 6px; cursor: pointer; font-size: 13px; font-weight: 600;
  color: var(--am-black); text-decoration: none; font-family: inherit; white-space: nowrap;
}
.action-menu-list button:hover, .action-menu-list a:hover { background: var(--am-gray-100); text-decoration: none; }
.action-menu-list .action-menu-danger { color: var(--am-red-text); }

.pagination-bar { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 0.75rem; margin-top: 0.75rem; }
.pagination-bar select { padding: 0.3rem 0.5rem; font-size: 12.5px; border: 1.5px solid var(--am-gray-300); border-radius: var(--radius-sm, 4px); background: var(--am-white); }
.btn.disabled { opacity: 0.4; pointer-events: none; }

[data-collapsible-toggle] { cursor: pointer; user-select: none; }
.panel-collapse-arrow { display: inline-block; transition: transform 0.15s ease; margin-left: 0.5rem; font-size: 12px; }
[data-collapsible].panel-collapsed .panel-collapse-arrow { transform: rotate(-90deg); }
[data-collapsible].panel-collapsed [data-collapsible-body] { display: none !important; } /* beats an inline display on the body */

/* Week calendar grid — shared by Group Sessions and Personal Appointments */
.gs-calendar { display: grid; grid-template-columns: 64px repeat(7, 1fr); gap: 5px; }
.gs-hours { display: flex; flex-direction: column; padding-top: 34px; }
.gs-hour-label { height: 60px; font-size: 12px; color: var(--am-gray-700); transform: translateY(-6px); }
.gs-day-col { border-left: 3px solid var(--am-gray-500); }
.gs-day-header { height: 34px; font-weight: 700; font-size: 13px; text-align: center; }
.gs-day-body {
  position: relative; height: 960px; cursor: pointer; overflow: hidden;
  background-image: repeating-linear-gradient(to bottom, var(--am-gray-100) 0, var(--am-gray-100) 1px, transparent 1px, transparent 60px);
}
.gs-block {
  position: absolute; left: 3px; right: 3px; border-radius: 7px; padding: 0.4rem 0.55rem; overflow: hidden;
  color: var(--am-black); text-decoration: none; font-size: 12.5px; box-shadow: 0 1px 3px rgba(0,0,0,0.15); cursor: pointer;
}
.gs-block:hover { outline: 2px solid var(--am-black); text-decoration: none; }
.gs-block-cancelled { opacity: 0.4; text-decoration: line-through; }
.gs-block-time, .gs-block-name, .gs-block-instructor { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gs-block-time { font-weight: 700; }
.gs-block-name { font-weight: 700; }
.gs-block-instructor { font-style: italic; font-size: 12px; }

/* Viewing fewer days at once (see the 1 Day / 3 Days toggle) already widens
   each day column since they're flexible-width — bump the tile text/padding
   further too, since the extra room actually has something worth showing. */
.gs-calendar[data-view-days="1"] .gs-block,
.gs-calendar[data-view-days="3"] .gs-block {
  font-size: 14px; padding: 0.55rem 0.7rem; border-radius: 8px;
}
.gs-calendar[data-view-days="1"] .gs-block-instructor,
.gs-calendar[data-view-days="3"] .gs-block-instructor {
  font-size: 12.5px;
}
.gs-calendar[data-view-days="1"] .gs-day-header,
.gs-calendar[data-view-days="3"] .gs-day-header {
  font-size: 15px; height: 38px;
}

/* Tab bar */
.tab-bar {
  display: flex; flex-wrap: wrap; gap: 0.25rem; border-bottom: 2px solid var(--am-gray-300);
  margin-bottom: 1rem;
}
.tab-btn {
  background: none; border: none; cursor: pointer; padding: 0.6rem 0.9rem;
  font-family: var(--font-body); font-size: 13px; font-weight: 700; color: var(--am-gray-700);
  border-bottom: 3px solid transparent; margin-bottom: -2px;
}
.tab-btn:hover { color: var(--am-black); }
.tab-btn.active { color: var(--am-black); border-bottom-color: var(--am-red); }
.period-pill-group { display: flex; gap: 0.4rem; margin-bottom: 1rem; }
.period-pill {
  padding: 0.35rem 0.8rem; border-radius: 999px; border: 1px solid var(--am-gray-300);
  background: var(--am-white); font-size: 12px; font-weight: 700; cursor: pointer; color: var(--am-gray-700);
}
.period-pill.active { background: var(--am-black); color: var(--am-white); border-color: var(--am-black); }
.period-pill.active .muted { color: inherit; opacity: 0.7; }
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 1rem; }
.stat-grid[hidden] { display: none; }
.stat-box { background: var(--am-gray-100); border-radius: var(--radius); padding: 1rem 1.25rem; }
.stat-box .stat-num { font-family: var(--font-display); font-size: 32px; line-height: 1; }
.stat-box .stat-label { font-size: 12px; color: var(--am-gray-700); margin-top: 0.3rem; }
.stat-box[data-stats-drilldown]:hover { background: var(--am-gray-300); }

/* Generic small modal (confirmation / choice dialogs) */
.modal-overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,0.6); z-index: 1000;
  display: flex; align-items: center; justify-content: center;
}
.modal-box {
  background: var(--am-white); border-radius: var(--radius); padding: 1.5rem;
  box-shadow: var(--shadow); width: 380px; max-width: 92vw;
}
.modal-box h4 { margin: 0 0 0.75rem; }
/* Radio/tick choice rows in pop-ups. The control sits in a left gutter so
   long labels (text + muted hint span) wrap beside it, never under it.
   width:auto undoes the global input{width:100%}. */
.modal-choice { display: block; position: relative; margin: 0 0 0.25rem; padding: 0.3rem 0 0.3rem 1.75rem; font-size: 14px; font-weight: 400; line-height: 1.45; cursor: pointer; }
.modal-choice > input[type="radio"], .modal-choice > input[type="checkbox"] { position: absolute; left: 0.1rem; top: calc(0.3rem + 3px); width: 16px; height: 16px; min-height: 0; margin: 0; padding: 0; }
@media (max-width: 768px) {
  .modal-choice { min-height: 44px; padding-top: 0.6rem; padding-bottom: 0.6rem; }
  .modal-choice > input[type="radio"], .modal-choice > input[type="checkbox"] { top: calc(0.6rem + 3px); }
}
fieldset.modal-fieldset { border: 0; margin: 0 0 0.5rem; padding: 0; min-width: 0; }
fieldset.modal-fieldset > legend { padding: 0; margin: 0 0 0.4rem; font-size: 14px; font-weight: 600; }
.modal-box textarea { width: 100%; resize: vertical; min-height: 60px; }
.modal-actions { display: flex; justify-content: flex-end; gap: 0.5rem; margin-top: 1.25rem; }
.modal-box.modal-box-wide { width: 760px; max-width: 94vw; max-height: 82vh; overflow-y: auto; }

.report-drill-row { cursor: pointer; }
.report-drill-row:hover td { background: var(--am-gray-100); }

.health-drill-tile { cursor: pointer; border-radius: 6px; margin: -0.5rem; padding: 0.5rem; }
.health-drill-tile:hover { background: var(--am-gray-100); }

.group-slot-row:hover td { background: rgba(237, 28, 36, 0.1); }
.group-slot-row:active td { background: rgba(237, 28, 36, 0.2); }

/* Radios used to be force-styled as solid-red squares with no checkmark to
   "match" checkboxes in kind — in practice that just made them look broken
   next to real (native, blue, checkmarked) checkboxes on the same page,
   e.g. a permission tier's radio options sitting beside a Full Access
   checkbox. Left fully native (no color override), both render in the
   browser's own blue with their own standard checked indicator —
   consistent with each other without redrawing either by hand. */
input[type="radio"] { cursor: pointer; }

.muted { color: var(--am-gray-700); font-size: 13px; }

/* Printable pages */
.print-page {
  background: var(--am-white);
  max-width: 700px;
  margin: 0 auto;
  padding: 2rem;
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.print-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem; border-bottom: 3px solid var(--am-black); padding-bottom: 1rem; }
.print-header img { height: 76px; }

@media print {
  .no-print { display: none !important; }
  body { background: var(--am-white); }
  .app-shell { display: block; }
  .main { max-width: none; padding: 0; }
  .print-page { box-shadow: none; margin: 0; max-width: none; }
}

/* ------------------------------------------------------------------
   Mobile — one breakpoint applied to the shared shell (this file +
   base.html) so it cascades to every page automatically instead of
   editing each template. Desktop layout (sidebar always visible) is
   untouched above 860px; below it the sidebar becomes an off-canvas
   drawer opened from a new top bar.

   The top bar's logo also carries width/height attributes + an inline
   style directly on the <img> in base.html (belt-and-suspenders): if
   this stylesheet ever fails to load, the browser's own image sizing
   still applies and it can never render at full native resolution.
   ------------------------------------------------------------------ */
.mobile-topbar { display: none; }
.sidebar-backdrop { display: none; }
.mobile-card-list { display: none; }

@media (max-width: 860px) {
  /* A report table that's fine to scan wide on desktop (many columns,
     compared side by side) becomes a stacked .gs-card list instead of a
     horizontally-scrolling table on a narrow screen, where the most
     important column would otherwise sit off-screen until scrolled to. */
  .mobile-card-list { display: block; }
  .desktop-only-table { display: none; }

  .mobile-topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    background: var(--am-black);
    padding: 0.6rem 0.9rem;
    position: sticky;
    top: 0;
    z-index: 220;
  }
  .mobile-topbar img { height: 26px; width: auto; }
  .mobile-nav-toggle {
    background: none;
    border: none;
    color: var(--am-white);
    font-size: 22px;
    line-height: 1;
    padding: 0.3rem 0.5rem;
    min-width: 44px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
  }

  .app-shell { flex-direction: column; min-height: 0; }

  .sidebar {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: 78vw;
    max-width: 300px;
    z-index: 240;
    transform: translateX(-100%);
    transition: transform 0.2s ease;
    overflow-y: auto;
  }
  .sidebar.mobile-open { transform: translateX(0); }
  /* closed: off-screen AND out of the Tab order (its 20+ links were still reachable by keyboard) */
  .sidebar:not(.mobile-open) { visibility: hidden; transition: transform 0.2s ease, visibility 0s linear 0.2s; }
  .sidebar nav .nav-drag-handle { display: none; }

  .sidebar-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 230;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s ease;
  }
  .sidebar-backdrop.visible { opacity: 1; pointer-events: auto; }

  .main { padding: 1rem; max-width: 100%; }

  .topbar { flex-direction: column; align-items: flex-start; gap: 0.5rem; }
  .topbar > div { display: flex; flex-wrap: wrap; gap: 0.5rem; }
  /* a collapsible card header keeps its ▾ on the same line as its title */
  .topbar[data-collapsible-toggle] { flex-direction: row; align-items: center; }
  /* a card inside a card: less side padding, a line instead of a second shadow */
  .card { padding: 1rem; }
  .card .card { padding: 0.75rem; box-shadow: none; border: 1px solid var(--am-gray-300); }
  /* No flex-direction:column here — .form-row already wraps (base rule
     above) which is enough to stack fields one-per-line on a narrow
     screen. Forcing column here previously turned each labeled field's
     flex-basis (a WIDTH in row direction) into a HEIGHT instead, since
     flex-basis follows whichever axis is "main" — every field rendered
     240-360px *tall* instead of wide. */
  .info-grid { gap: 1rem; }

  /* Wide tables scroll horizontally inside themselves rather than
     squeezing columns or overflowing the page. */
  table { display: block; overflow-x: auto; white-space: nowrap; -webkit-overflow-scrolling: touch; }
  th, td { white-space: nowrap; }
  /* label + amount tables (mobile-tables.js adds m-two) fit: wrap the label, keep the amount whole and in view */
  table.m-two { display: table; width: 100%; white-space: normal; }
  table.m-two th, table.m-two td { white-space: normal; }
  table.m-two td:last-child { white-space: nowrap; text-align: right; }

  /* The week calendar's 7 day-columns can't reflow — give them a fixed,
     legible width and let the whole grid scroll sideways instead. */
  .gs-calendar { grid-template-columns: 42px repeat(7, 96px); overflow-x: auto; -webkit-overflow-scrolling: touch; }

  .modal-box.modal-box-wide { width: 94vw; }

  /* Prevents iOS Safari's auto-zoom-on-focus for any field under 16px. */
  input, select, textarea { font-size: 16px; }
  .btn { min-height: 40px; }
  /* finger-size targets (44px) for everything you tap on a phone */
  input:not([type="checkbox"]):not([type="radio"]), select, .btn, .btn-sm, .tab-btn, .type-pill, .filter-pill select { min-height: 44px; }
}

/* ---------------------------------------------------------------------
   Client Portal — polished mobile UI: dashboard hero + tiles, the Group
   Sessions day-strip/filters/calendar sheet, and session cards.
   --------------------------------------------------------------------- */

.portal-hero {
  position: relative;
  border-radius: 16px;
  overflow: hidden;
  padding: 2.5rem 1.5rem 2rem;
  text-align: center;
  color: var(--am-white);
  background: linear-gradient(135deg, var(--am-black) 0%, #3a2020 55%, var(--am-red) 130%);
  margin-bottom: 1.25rem;
}
.portal-hero > * { position: relative; z-index: 1; }
.portal-hero img { height: 56px; margin-bottom: 0.5rem; }
.portal-hero h1 { font-family: var(--font-display); font-size: 28px; margin: 0.25rem 0; letter-spacing: 0.02em; color: var(--am-white); }
.portal-hero p { margin: 0; color: var(--am-gray-300); font-size: 12px; letter-spacing: 0.12em; text-transform: uppercase; }

.tile-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.75rem;
  margin-bottom: 1.25rem;
}
.tile {
  -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; touch-action: manipulation;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 0.5rem;
  background: var(--am-white);
  border-radius: 14px;
  padding: 1.25rem 0.5rem;
  text-align: center;
  color: var(--am-black);
  box-shadow: var(--shadow);
  font-weight: 700;
  font-size: 12.5px;
  min-height: 92px;
  /* A long-press on a link is also the phone's own gesture for "open in a
     new tab" / a link-preview callout — without suppressing that, it wins
     the race against tile-reorder.js's own hold-to-drag detection. */
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  touch-action: manipulation;
}
.tile:hover { text-decoration: none; opacity: 0.85; }
.tile svg { width: 26px; height: 26px; stroke: var(--am-red); }
.tile-dragging { opacity: 0.55; transform: scale(1.04); box-shadow: 0 8px 20px rgba(0,0,0,0.25); z-index: 5; position: relative; }
.tile-grid-editing a.tile { outline: 2px dashed var(--am-red); outline-offset: -4px; cursor: grab; touch-action: none; }
.tile-edit-bar { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; padding: 0.6rem 0.8rem; margin-bottom: 0.75rem; border-radius: 12px; background: var(--am-black); color: var(--am-white); font-size: 0.9rem; scroll-margin-top: 80px; }
.tile-edit-bar[hidden] { display: none; }
@media (max-width: 480px) {
  .tile-grid { grid-template-columns: repeat(2, 1fr); }
}

/* Day strip */
.day-strip { display: flex; gap: 0.4rem; overflow-x: auto; padding-bottom: 0.25rem; -webkit-overflow-scrolling: touch; }
.day-pill {
  flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; gap: 0.25rem;
  padding: 0.5rem 0.7rem; border-radius: 14px; color: var(--am-black); min-width: 46px;
}
.day-pill:hover { text-decoration: none; background: var(--am-gray-100); }
.day-pill .dow { font-size: 11px; color: var(--am-gray-700); text-transform: uppercase; }
.day-pill .dom { font-size: 16px; font-weight: 800; }
.day-pill.selected { background: var(--am-black); color: var(--am-white); }
.day-pill.selected .dow { color: var(--am-gray-300); }

.filter-row { display: flex; gap: 0.5rem; margin: 0.75rem 0; flex-wrap: wrap; }
.filter-pill { display: inline-flex; }
.filter-pill select {
  border: none; background: var(--am-gray-100); border-radius: 999px;
  padding: 0.45rem 1.75rem 0.45rem 0.9rem; font-size: 12.5px; font-weight: 700; color: var(--am-black);
  appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='%2358595b'%3E%3Cpath fill-rule='evenodd' d='M5.23 7.21a.75.75 0 011.06.02L10 11.293l3.71-4.06a.75.75 0 111.08 1.04l-4.24 4.65a.75.75 0 01-1.08 0l-4.24-4.65a.75.75 0 01.02-1.06z' clip-rule='evenodd'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 0.6rem center; background-size: 14px;
}

.gs-day-header { font-family: var(--font-display); font-size: 18px; margin: 1.25rem 0 0.5rem; }
/* ...but not the staff week calendar's day headers (that big agenda style made them overlap on phones) */
.gs-calendar .gs-day-header { font-family: var(--font-body); font-size: 13px; margin: 0; }
.gs-card {
  display: flex; align-items: center; gap: 0.9rem;
  background: var(--am-white); border-radius: 12px; padding: 0.75rem; margin-bottom: 0.6rem;
  box-shadow: var(--shadow); color: var(--am-black);
}
.gs-card:hover { text-decoration: none; opacity: 0.92; }
.gs-card-thumb {
  width: 60px; height: 60px; border-radius: 10px; flex: 0 0 auto;
  background-size: cover; background-position: center;
  display: flex; align-items: center; justify-content: center;
  color: var(--am-white); font-weight: 800; font-size: 18px;
}
.gs-card-body { flex: 1; min-width: 0; }
.gs-card-body .gs-name { font-weight: 700; font-size: 15px; }
.gs-card-body .gs-meta { font-size: 12.5px; color: var(--am-gray-700); }
.gs-card-status { font-size: 12px; font-weight: 700; }

/* Calendar bottom sheet */
.calendar-scrim {
  position: fixed; inset: 0; background: rgba(0,0,0,0.5); z-index: 200;
  display: flex; align-items: flex-end; justify-content: center;
}
.calendar-sheet {
  background: var(--am-white); border-radius: 20px 20px 0 0; width: 100%; max-width: 480px;
  padding: 1.25rem 1.25rem 1.5rem; max-height: 85vh; overflow-y: auto;
}
.calendar-sheet-handle { width: 40px; height: 4px; background: var(--am-gray-300); border-radius: 999px; margin: 0 auto 1rem; }
.calendar-sheet-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.75rem; }
.calendar-sheet-header h3 { font-family: var(--font-display); font-size: 20px; margin: 0; }
.calendar-sheet-header button { background: none; border: none; cursor: pointer; padding: 0.4rem; color: var(--am-black); }
.calendar-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 0.2rem; text-align: center; }
.calendar-grid .cal-dow { font-size: 11px; color: var(--am-gray-700); text-transform: uppercase; padding: 0.4rem 0; }
.calendar-grid .cal-day {
  padding: 0.5rem 0; border-radius: 999px; cursor: pointer; font-size: 14px; font-weight: 600;
  background: none; border: none; color: var(--am-black);
}
.calendar-grid .cal-day:disabled { color: var(--am-gray-300); cursor: default; }
.calendar-grid .cal-day.today { font-weight: 800; }
.calendar-grid .cal-day.selected { background: var(--am-black); color: var(--am-white); }

/* Star rating — pure-CSS radio trick: DOM order is 5,4,3,2,1 so that with
   row-reverse the visual order is 1..5, and hovering/checking star N lights
   up N and everything before it in DOM order (i.e. visually 1..N). */
.star-rating {
  display: inline-flex;
  flex-direction: row-reverse;
  gap: 0.2rem;
}
.star-rating input { position: absolute; opacity: 0; width: 0; height: 0; }
.star-rating label {
  font-size: 34px;
  line-height: 1;
  color: var(--am-gray-300);
  cursor: pointer;
  transition: color 0.15s, transform 0.1s;
}
.star-rating label:hover,
.star-rating label:hover ~ label,
.star-rating input:checked ~ label {
  color: var(--am-red);
}
.star-rating label:hover { transform: scale(1.15); }
.star-rating.readonly label { cursor: default; }
.star-rating.readonly label:hover,
.star-rating.readonly label:hover ~ label { transform: none; }
.calendar-sheet .btn-primary { width: 100%; margin-top: 1.25rem; border-radius: 999px; justify-content: center; }

/* Phone-friendly tables (see static/js/mobile-tables.js): rows become
   two-line cards instead of a sideways-scrolling table. The helper cells and
   day-heading rows it inserts are hidden everywhere except phones. */
table .m-break, table .m-time, table tr.m-day, table .m-label { display: none; }

@media (max-width: 640px) {
  table.m-stack { display: block; overflow: visible; white-space: normal; }
  table.m-stack thead { display: none; }
  table.m-stack tbody { display: block; }
  table.m-stack tr {
    display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 0.6rem;
    padding: 0.65rem 0.1rem; border-bottom: 1px solid var(--am-gray-100);
  }
  table.m-stack td { display: block; border: none; padding: 0; white-space: normal; font-size: 14px; text-align: left; }
  table.m-stack td.m-title { order: 1; flex: 1 1 0; min-width: 40%; font-weight: 700; overflow-wrap: break-word; }
  table.m-stack td.m-amount { order: 2; margin-left: auto; max-width: 55%; text-align: right; white-space: nowrap; font-weight: 700; }
  /* A long status badge wraps inside itself rather than squeezing the name. */
  table.m-stack td.m-amount .badge { white-space: normal; display: inline-block; text-align: center; }
  table.m-stack td.m-break { display: block; order: 3; flex-basis: 100%; height: 0; }
  table.m-stack td.m-meta { order: 4; font-size: 12.5px; color: var(--am-gray-700); margin-top: 0.15rem; }
  /* meta cells now carry their column name (mobile-tables.js), so no "·" between them (a lone dot started wrapped lines) */
  table.m-stack td.m-meta { margin-right: 0.9rem; }
  table.m-stack td.m-actions { order: 5; flex-basis: 100%; margin-top: 0.45rem; }
  table.m-stack td.m-empty { display: none; }
  table.m-stack td.m-check { order: 0; flex: 0 0 auto; align-self: center; }
  table.m-stack td.m-check input { width: 18px; height: 18px; margin: 0; }
  table.m-stack .m-label { display: inline; color: var(--am-gray-700); font-weight: 400; }
  table.m-stack tr.m-fullrow td { flex-basis: 100%; }
  table.m-stack tr.m-fullrow:not(.open) { display: none; }
  table.m-stack tr.edit-section.open, table.m-stack tr.m-fullrow:not(.edit-section) { display: flex; }

  /* Day-grouped schedules: a heading per day, just the time on each row. */
  table.m-grouped tr.m-day { display: block; border-bottom: none; padding: 0.9rem 0 0.2rem; }
  table.m-grouped tr.m-day td { display: block; font-weight: 800; font-size: 13px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--am-gray-700); }
  table.m-grouped td.m-time-cell { order: 0; flex: 0 0 4.6rem; font-size: 13px; color: var(--am-gray-700); }
  table.m-grouped td.m-time-cell > :not(.m-time) { display: none; }
  table.m-grouped td.m-time-cell { font-size: 0; }
  table.m-grouped td.m-time-cell .m-time { display: inline; font-size: 13px; }
  table.m-grouped td.m-meta-first { margin-left: calc(4.6rem + 0.6rem); }
}

/* Report pop-ups: wide tables shown as one card per row (report-drilldown.js) */
.drill-cards { display: flex; flex-direction: column; gap: 0.5rem; }
.drill-card { border: 1px solid var(--am-gray-300); border-radius: 8px; padding: 0.6rem 0.8rem; }
.drill-card-top { display: flex; justify-content: space-between; align-items: baseline; gap: 0.75rem; }
.drill-card-title { font-weight: 700; overflow-wrap: anywhere; }
.drill-card-amount { font-weight: 700; white-space: nowrap; }
.drill-card-meta { font-size: 13px; color: var(--am-gray-700); margin-top: 0.2rem; overflow-wrap: anywhere; }
.drill-card-links { float: right; margin-left: 0.75rem; font-weight: 600; }
.drill-due { color: var(--am-red-text); font-weight: 600; }
.drill-paid { color: var(--am-green-text); font-weight: 600; }

/* "Billed To" client block on printed invoices/statements (_billed_to.html) */
.billed-to-heading { font-size: 12px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--am-gray-700); margin-bottom: 0.4rem; padding-bottom: 0.3rem; border-bottom: 2px solid var(--am-red); display: inline-block; }
table.billed-to { width: auto; border-collapse: collapse; margin: 0; }
table.billed-to th, table.billed-to td { border: none; padding: 0.15rem 0; background: none; font-size: 14px; text-align: left; vertical-align: top; text-transform: none; letter-spacing: normal; }
table.billed-to th { font-weight: 600; color: var(--am-gray-700); padding-right: 1rem; white-space: nowrap; }
table.billed-to th::after { content: ":"; }
table.billed-to td { color: var(--am-black); white-space: nowrap; }
/* Take the room the email needs; the dates beside it move underneath if the page is too narrow. */
.form-row > .billed-to-block { flex: 1 0 auto; }
@media (max-width: 480px) { table.billed-to td { white-space: normal; overflow-wrap: anywhere; } }
table.billed-to tr:first-child td { font-weight: 700; }
.main:focus { outline: none; }  /* the skip link moves focus here; no ring around the whole page */

/* ---------------------------------------------------------------------
   Phone apps (client portal, Coach, Sales, Partner): one compact top bar and
   a bottom bar of at most 5 tabs. Shared by the 4 shells (UI audit 2026-10-05).
   --------------------------------------------------------------------- */
.app-bar { position: sticky; top: 0; z-index: 90; height: 56px; display: grid; grid-template-columns: 44px 1fr 44px; align-items: center;
           padding: 0 0.75rem; background: var(--am-gray-100); border-bottom: 1px solid var(--am-gray-200, #2e343e); }
.app-side { display: flex; align-items: center; width: 44px; height: 44px; }
.app-back { display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px; border-radius: 50%;
            background: var(--am-gray-200, #2e343e); color: var(--am-black); }
.app-back:hover { text-decoration: none; }
.app-logo { justify-self: center; display: flex; align-items: center; }
.app-logo img { height: 42px; width: auto; display: block; }
.gym .app-logo img { content: url("/static/img/MainLogo-01-dark.png"); }
.bottom-tabs { position: fixed; bottom: 0; left: 0; right: 0; z-index: 100; display: flex;
               background: var(--am-white); border-top: 1px solid var(--am-gray-100);
               padding: 0.25rem 0.25rem calc(0.25rem + env(safe-area-inset-bottom)); }
.bottom-tabs a { flex: 1 1 0; min-width: 0; min-height: 52px; display: flex; flex-direction: column; align-items: center; justify-content: center;
                 gap: 0.2rem; color: var(--am-gray-700); font-size: 12px; font-weight: 700; text-align: center; position: relative; }
.bottom-tabs a:hover { text-decoration: none; }
.bottom-tabs a.active { color: var(--am-black); }
.bottom-tabs a.active::before { content: ""; position: absolute; top: -0.25rem; left: 30%; right: 30%; height: 3px; border-radius: 0 0 3px 3px; background: var(--am-red); }
.bottom-tabs svg { width: 22px; height: 22px; }
.bottom-tabs a.active svg { color: var(--am-red); }
.bottom-tabs .tab-badge { position: absolute; top: 0.2rem; right: 24%; background: var(--am-red); color: #fff; border-radius: 999px; font-size: 10px;
                          min-width: 16px; height: 16px; padding: 0 4px; display: inline-flex; align-items: center; justify-content: center; }

/* Training team chip (Cycles, Assessments, coach app); the builder and client app have their own */
.tm-chip{display:inline-flex;align-items:center;gap:5px;border-radius:999px;padding:2px 8px 2px 6px;font-size:12px;font-weight:700;background:var(--am-gray-100);border:1px solid var(--am-gray-200);color:var(--am-black);white-space:nowrap;vertical-align:middle;line-height:1.5}
.tm-chip i{width:8px;height:8px;border-radius:50%;background:var(--c)}

/* ---------- UI audit 2026-10-06: ONE control height everywhere (Amr: "every button with different dimensions") ---------- */
:root{--ctl-h:40px}
@media (max-width:768px){:root{--ctl-h:44px}}
.btn,.btn-sm,.btn-outline,.type-pill,.period-pill,.tab-btn,.chat-tab,.chat-away-chip,
input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=file]):not([type=color]):not([type=hidden]),select,
.searchable-select-wrapper input{box-sizing:border-box;min-height:var(--ctl-h)}
.btn,.btn-sm,.btn-outline,.type-pill,.period-pill,.tab-btn{display:inline-flex;align-items:center;justify-content:center;gap:.4rem;line-height:1.2}
.btn-sm{padding:0 .9rem}
.tab-btn{padding:0 .9rem}
.type-pill{margin-bottom:0}
.type-pill,.tab-btn{font-size:14px}                      /* re-audit 7 Oct: pills and tabs match .btn text */
.form-row > span.muted{flex:0 0 auto}                   /* inline words ("every", "days") stay beside their box */
.btn:disabled{opacity:.45;cursor:not-allowed}            /* greyed: e.g. Close a Month until payroll is final */
.chat-tab,.chat-away-chip{display:inline-flex;align-items:center}

/* ---------- UI audit 2026-10-06: staff front desk (report 01) ---------- */
.topbar { flex-wrap: wrap; gap: 0.75rem; }
.topbar-actions { display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center; }
.card-toggle { display: none; }                         /* a form card opened by a button in the page header */
.card-toggle.open { display: block; }
.tab-toolbar { display: flex; justify-content: flex-end; margin-bottom: 1rem; }
.field-title { display: block; font-size: 13px; font-weight: 600; margin: 0.7rem 0 0.25rem; }
.back-link { display: inline-block; font-size: 13px; font-weight: 700; color: var(--am-gray-700); margin-bottom: 0.35rem; }
.client-status-line { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; margin-top: 0.4rem; }
.pkg-dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: 0.45rem; vertical-align: middle; flex: none; }
.display .pkg-dot { width: 14px; height: 14px; }
.link-btn { background: none; border: 0; padding: 0; margin: 0; font: inherit; font-weight: 700; color: var(--am-black); text-align: left; text-decoration: underline dotted; text-underline-offset: 3px; cursor: pointer; }
.online-legend { margin-left: 0.75rem; white-space: nowrap; }
.online-dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--am-green); margin-right: 0.35rem; vertical-align: middle; }
.cp-avatar-empty { display: none !important; }          /* "?" next to a client search, until someone is picked */
a.type-pill { color: var(--am-black); text-decoration: none; }
a.type-pill.selected { color: var(--am-white); }
details.see-all > summary { cursor: pointer; font-weight: 700; margin: 0.25rem 0 0.5rem; }
.sidebar-footer details.other-apps > summary { list-style: none; cursor: pointer; }
.sidebar-footer details.other-apps > summary::-webkit-details-marker { display: none; }
.sidebar-footer details.other-apps[open] > summary { opacity: 0.8; }
/* drag dots only on the item being pointed at or focused */
.sidebar nav .nav-item .nav-drag-handle { opacity: 0; transition: opacity .12s; }
.sidebar nav .nav-item:hover > .nav-drag-handle, .sidebar nav .nav-item:focus-within > .nav-drag-handle { opacity: 0.6; }
.topbar-actions .action-menu-list { left: auto; right: 0; }
.topbar-actions .action-menu-list .action-menu-danger { color: #b3141b; }   /* brand red is 4:1 at 13px */
.dash-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(88px, 1fr)); gap: 1rem; }
.client-head h1.display { margin-bottom: 0; }
.cp-group-pills { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
.cp-group-pills::-webkit-scrollbar { display: none; }
.cp-group-pills .period-pill { flex: 0 0 auto; }
@media (max-width: 640px) {
  .badge { white-space: normal; max-width: 100%; }
  td { min-width: 0; overflow-wrap: anywhere; }
  .tab-bar { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  .tab-bar::-webkit-scrollbar { display: none; }
  .tab-bar .tab-btn { flex: 0 0 auto; }
  .checkin-scan-row, .checkin-name-row { flex-wrap: wrap; }
  .checkin-scan-row #scan-input { flex: 1 1 100% !important; }
  .checkin-scan-row #camera-scan-btn { flex: 1 1 100% !important; }
  .checkin-name-row .searchable-select { flex: 1 1 100% !important; max-width: none !important; }
  .checkin-name-row > div:last-child, .checkin-name-row > div:last-child .btn { flex: 1 1 100% !important; width: 100%; }
  .topbar-actions { width: 100%; }
  .cp-group-pills { gap: 0.3rem; }
  .cp-group-pills .period-pill { padding: 0 0.45rem; }
}

/* ---------- UI audit 2026-10-06, round 2 (reports 01 + 02) ---------- */
small { font-size: max(12px, 0.8em); }                    /* browsers draw <small> at 10.8px; 12px is the smallest size */
.scan-box { border-style: solid; }
.scan-box:focus { outline-color: var(--am-gray-700); border-color: var(--am-gray-700); }
.text-green { color: var(--am-green-text); }
.text-red { color: var(--am-red-text); }
/* A small coloured dot before a name: the package/staff colour stays, the name is ink */
.c-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 0.4rem; vertical-align: middle; flex: none; background: var(--c, var(--am-gray-500)); }
/* Shared "are you sure?" pop-up (app/static/js/confirm-dialog.js) */
.confirm-box { width: 420px; max-width: 92vw; }
.confirm-box p { margin: 0 0 1rem; white-space: pre-line; }
.confirm-box .modal-actions { display: flex; justify-content: flex-end; gap: 0.5rem; flex-wrap: wrap; }
@media (max-width: 768px) {
  /* tap areas: the tag "×" and the package name on the profile */
  .tag-pill button { min-width: 44px; min-height: 44px; margin: -12px -10px -12px -4px; font-size: 16px; }
  .link-btn { min-height: 44px; }
  .confirm-box .modal-actions .btn { flex: 1 1 auto; }
}
[data-action-menu-toggle] { min-width: var(--ctl-h); }      /* the "⋮" button is a square tap target */

/* ---------- UI audit 2026-10-07 (bug-fix screens) ---------- */
/* "Ends: After N / End by date" choices in the booking repeat form */
.rep-choice { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; font-weight: 400; margin: 0 0 0.3rem; min-height: var(--ctl-h, 40px); }
.rep-choice input[type="number"], .rep-choice input[type="date"] { margin: 0; }
/* A tick that can't be changed looks it */
label:has(> input:disabled) { opacity: 0.55; cursor: not-allowed; }
@media (max-width: 768px) {
  .role-ticks input[type="checkbox"] { width: 20px !important; height: 20px; }
  .role-ticks > label { min-height: 44px; margin: 0 !important; }
  .rep-choice { min-height: 44px; }
  .rep-choice input[type="radio"] { width: 20px !important; height: 20px; }
}
/* Group class attendee buttons wrap inside their cell instead of running off the screen */
.gs-acts { white-space: normal; }
.gs-acts > form, .gs-acts > .btn { display: inline-flex; margin: 0 0.3rem 0.3rem 0; vertical-align: middle; }
@media (max-width: 768px) {
  .fin-row > div { flex: 1 1 100% !important; min-width: 0 !important; max-width: none !important; }
  .fin-row .btn { width: 100%; }
}
/* One button text size everywhere (small buttons only differ in padding) */
.btn-sm { font-size: 14px; }
/* Yes/No pills in the invoice delete row stay pills on phones */
.refund-row .type-pill { min-width: 64px; padding: 0 1rem; border-radius: 999px; }

/* ---------- Shared partials, inline looks moved here (staff kit 2026-10-07). :where() keeps them weak so the
   staff back office (staff-kit.css, body.sk-app) restyles them; Coach / Sales / Partner keep this look. ---------- */
:where(.pagination-bar .pg-ctl) { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
:where(.pagination-bar .pg-info, .pagination-bar .pg-page, .pagination-bar .pg-ctl > label) { font-size: 12px; color: var(--am-gray-700); }
:where(.pagination-bar .pg-ctl > label) { margin: 0; }
/* _pay_history.html */
:where(.pay-month) { border-top: 1px solid var(--am-gray-200, #e5e5e5); padding: 0.6rem 0; }
:where(.pay-month-sum) { cursor: pointer; display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
:where(.pay-due) { color: var(--am-red-text); font-weight: 700; }
:where(.pay-paid) { color: var(--am-green-text); font-weight: 700; }
:where(.pay-due-text) { color: var(--am-red-text); }
:where(.pay-line) { margin: 0.5rem 0 0 0.3rem; padding: 0.5rem 0.7rem; background: var(--am-gray-100, #f6f6f6); border-radius: 8px; }
:where(.pay-line-head) { display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
:where(.pay-line-desc) { font-size: 13px; margin-top: 0.2rem; color: var(--am-gray-700); }
:where(.pay-line-meta) { font-size: 13px; margin-top: 0.25rem; }
:where(.pay-empty) { margin: 0; }
/* _targets_progress.html */
:where(.tp-row) { margin-bottom: 0.7rem; }
:where(.tp-head) { display: flex; justify-content: space-between; gap: 0.5rem; font-size: 13.5px; }
:where(.tp-bonus) { font-size: 12px; }
:where(.tp-val) { white-space: nowrap; }
:where(.tp-bar) { height: 8px; background: var(--am-gray-100); border-radius: 4px; overflow: hidden; margin-top: 0.25rem; }
:where(.tp-fill) { height: 100%; background: var(--am-red); }
:where(.tp-fill.is-hit) { background: var(--am-green, #1a9c4c); }
:where(.tp-fill.is-track) { background: var(--am-orange, #f7941d); }
:where(.tp-note) { font-size: 12px; margin-top: 0.15rem; }
/* _credits_expiry_report.html / _renewals_report.html */
.text-warn { color: var(--am-warn-text); }
:where(.days-left) { font-size: 12px; }
:where(a.stat-box) { text-decoration: none; color: inherit; }
.form-row.report-presets { gap: 0.5rem; margin-bottom: 0.75rem; }

.form-row > .report-apply { flex: 0 0 auto; }
:where(.report-stats) { margin-bottom: 1rem; }

/* Staff PIN boxes are type="text" (Chrome checks every type="password" box against leaked-password
   lists and warned Amr his PIN was "in a data breach"), so the dots come from here instead. */
input[data-pin] { -webkit-text-security: disc; text-security: disc; }
