/* AF247 Brand CSS — Anytime Fitness International Brand Guidelines 2022 V2.1
 * Authoritative source: AF Brand Guidelines PDF (Drive folder "Branding"),
 * sections 04 (Color), 05 (Typography), 06 (Graphic Elements).
 *
 * Drop-in: <link rel="stylesheet" href="/static/brand.css"> at the top of
 * every template. Existing per-page CSS still works alongside.
 */

/* PRIMARY DIGITAL FONT FAMILY: Montserrat (free Google Font replaces F37 Moon).
 * Section 05.01 of brand guidelines.
 * "Montserrat should be used in all digital settings and print when F37 Moon
 * is unavailable." */
@import url("https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;600;700;800;900&display=swap");

/* ═══ AF247 SHARED UI LAYER v1 — 2026-06-11 ═══
   Keep the 3 copies identical. Source: _session/ui_overhaul_2026_06_11/shared_layer.css */

:root {
  /* Motion — the ONLY two easings allowed (replaces 3 dialects:
     0.2,0.8,0.2,1 / 0.19,1,0.22,1 / 0.23,1,0.32,1) */
  --ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);
  --ease-out-expo:  cubic-bezier(0.16, 1, 0.3, 1);
  --dur-feedback: 120ms;   /* hover / press */
  --dur-state:    240ms;   /* toggles, fades */
  --dur-layout:   400ms;   /* panels, reflows (still transform-only) */
  --dur-entrance: 600ms;   /* page-load reveals; exits = 75% of entrance */

  /* Z-scale — arbitrary 999/9999 banned */
  --z-base:     1;
  --z-sticky:   50;
  --z-overlay:  100;
  --z-progress: 110;

  /* Tinted neutrals — pure #fff/#000 banned */
  --white-tint:   #FAFAFF;   /* text on dark/violet surfaces */
  --af-bg-tinted: #FAF8FF;   /* light surfaces on violet */

  /* Press language — one across all apps */
  --press-scale: 0.97;
}

/* Table scroll wrapper — EVERY <table> gets one of these as parent */
.table-scroll, .af-table-scroll, .v2-table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  max-width: 100%;
}

/* Text-safety utilities */
.min0       { min-width: 0; }
.truncate-1 { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.break-safe { overflow-wrap: anywhere; }
.break-id   { word-break: break-all; }   /* IDs / emails-as-keys / WA LIDs ONLY */
.tnum       { font-variant-numeric: tabular-nums; }

/* Touch targets — gate on pointer, not viewport width */
@media (pointer: coarse) {
  button, .af-btn, .v2-anchor, a[role="button"], input[type="submit"] {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  input, select, textarea, .af-input { font-size: 16px; }  /* kills iOS focus zoom */
}

/* Scroll progress — ONE transform-based component (replaces both width-animating bars) */
.scroll-progress {
  position: fixed; top: 0; left: 0;
  width: 100%; height: 3px;
  background: var(--country-accent, #6E38D5);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 80ms linear;
  z-index: var(--z-progress);
}
/* ═══ end shared layer ═══ */

:root {
  /* ─────────────────── PRIMARY BRAND COLORS (04.02) ─────────────────── */
  --af-blurple:       #6E38D5;     /* Pantone 2097 C — primary, used boldly */
  --af-violet:        #440099;     /* Pantone Violet C — depth pair w/ Blurple */
  --af-white:         #FFFFFF;     /* silent partner, neutral high-contrast */

  /* ─────────────────── ACCENT COLORS (04.03) ─────────────────── */
  --af-medium-purple: #A42AF9;     /* Pantone 2582 C */
  --af-turquoise:     #00AEC7;     /* Pantone 3125 C */
  --af-red:           #EF3340;     /* Pantone Warm Red C — ACCENT only */
  --af-orange:        #FF7500;     /* Pantone 151 C */

  /* ─────────────────── DERIVED / UI tokens ─────────────────── */
  --af-blurple-dark:  #5A2BB0;
  --af-blurple-pale:  #EFE7FB;
  --af-violet-dark:   #2E0066;
  --af-ink:           #1d1d1f;
  --af-ink-2:         #4a4a4f;
  --af-ink-3:         #86868b;
  --af-line:          #d2d2d7;
  --af-bg:            #f7f5fc;     /* 2026-06-11 overhaul: violet-tinted (was pure-gray #f5f5f7) */
  --af-bg-tinted:     #FAF8FF;     /* very faint blurple wash */
  --af-card:          #fdfcff;     /* 2026-06-11 overhaul: violet-tinted surface (was #ffffff) */
  --af-surface:       #fdfcff;     /* alias used by 2026-06-11 shared utilities */
  --af-success:       #1f8a4a;
  --af-warn:          #c2860c;

  /* Typography — Montserrat per 05.01 PRIMARY DIGITAL FONT FAMILY */
  --af-font-body:    "Montserrat", "Century Gothic", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
  --af-font-display: "Montserrat", "Century Gothic", "Helvetica Neue", Arial, sans-serif;

  /* Headlines per 05.02 — ALL CAPS, BLACK weight, TIGHT LEADING (50/60 ratio) */
  --af-headline-leading: 0.83;     /* 50pt leading on 60pt size */

  --af-radius:    14px;
  --af-radius-sm: 8px;
  --af-shadow:    0 4px 20px rgba(110,56,213,0.10);
  --af-shadow-lg: 0 12px 36px rgba(68,0,153,0.16);

  /* ─────────────────── LINE BLEND GRADIENTS (06.01) ─────────────────── */
  /* "Each gradient build uses Blurple and Medium Purple as a base, blending
   *  equally toward each of our accent colors (Aqua, Orange & Red)." */
  --af-blend-turquoise: linear-gradient(135deg, var(--af-blurple) 0%, var(--af-medium-purple) 50%, var(--af-turquoise) 100%);
  --af-blend-orange:    linear-gradient(135deg, var(--af-blurple) 0%, var(--af-medium-purple) 50%, var(--af-orange) 100%);
  --af-blend-red:       linear-gradient(135deg, var(--af-blurple) 0%, var(--af-medium-purple) 50%, var(--af-red) 100%);
  --af-blend-violet:    linear-gradient(135deg, var(--af-violet) 0%, var(--af-blurple) 60%, var(--af-medium-purple) 100%);

  /* ─────────────────── MOTION + INTERACTION TOKENS (2026-05-17) ─────────────────── */
  /* Added during the Emil Kowalski staff-portal refresh. The four redesigned
   * pages (queue quickadd, login, lead detail, staff leave) each declared a
   * page-local --<prefix>-ease-out duplicating the same cubic-bezier. Now
   * shared here so new pages can reach for --af-ease-out instead.
   * See docs/brand_guidelines.md for the full system.
   * Page-prefix vars (--qa-ease-out, --lo-ease-out, --ld-ease-out,
   * --sl-ease-out, --sv-ease-out) are kept as aliases below for back-compat. */
  --af-ease-out:    var(--ease-out-quart, cubic-bezier(0.25, 1, 0.5, 1));  /* 2026-06-11: unified on ease-out-quart (was 0.23,1,0.32,1) */
  --af-ease-expo:   var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1));   /* entrances */
  --af-ease-in-out: cubic-bezier(0.77, 0, 0.175, 1); /* strong ease-in-out for on-screen movement */
  --af-ease-shake:  cubic-bezier(0.36, 0.07, 0.19, 0.97); /* error-feedback shake */
  --af-press-scale: 0.97;                              /* :active scale for buttons */
  --af-focus-ring:  0 0 0 3px rgba(110, 56, 213, 0.15); /* keyboard focus glow */
}

/* Reset + body baseline */
html, body {
  margin: 0;
  padding: 0;
  background: var(--af-bg);
  color: var(--af-ink);
  font-family: var(--af-font-body);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

a { color: var(--af-blurple); text-decoration: none; font-weight: 500; }
a:hover { color: var(--af-violet); text-decoration: underline; }

/* ════════════════════════════════════════════════════════════════════
   AF brand header — Blurple Line Blend Background per 06.01 + 07.01
   ════════════════════════════════════════════════════════════════════ */

.af-shell {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.af-header {
  background: var(--af-blend-violet);
  color: var(--af-white);
  padding: 16px 24px;
  display: flex;
  flex-wrap: wrap;   /* 2026-06-11: wrap at ALL widths — fixes the 641–900px collision band */
  align-items: center;
  gap: 18px;
  box-shadow: 0 2px 12px rgba(68,0,153,0.20);
  position: relative;
  /* subtle texture stripes — references "Line Blend pattern" 06.01.02 */
  background-image:
    linear-gradient(135deg, var(--af-violet) 0%, var(--af-blurple) 60%, var(--af-medium-purple) 100%),
    repeating-linear-gradient(105deg, rgba(255,255,255,0.04) 0 2px, transparent 2px 14px);
  background-blend-mode: overlay;
}

.af-header__brand {
  display: flex; align-items: center; gap: 14px;
  text-decoration: none; color: var(--af-white);
}
.af-header__brand:hover { text-decoration: none; color: var(--af-white); }
.af-header__brand img.af-mark {
  height: 42px; width: auto; display: block;
  filter: drop-shadow(0 1px 3px rgba(0,0,0,0.30));
}
.af-header__wordmark {
  font-family: var(--af-font-display);
  font-weight: 900;                       /* BLACK weight per 05.02 */
  font-size: 17px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  line-height: var(--af-headline-leading);
}
.af-header__wordmark .sub {
  display: block;
  font-size: 10px;
  letter-spacing: 0.20em;
  font-weight: 400;
  opacity: 0.88;
  margin-top: 4px;
  text-transform: uppercase;
}

.af-header__title {
  margin-left: auto;
  font-family: var(--af-font-display);
  font-weight: 900;
  font-size: 16px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-align: right;
  /* 2026-06-11: titles can wrap — 0.83 leading made wrapped lines overlap.
     0.83 stays ONLY on guaranteed single-line lockups (wordmark). */
  line-height: 1.1;
  min-width: 0;
  max-width: 60%;
}
.af-header__title .ctx {
  display: block;
  font-size: 10px;
  font-weight: 400;
  letter-spacing: 0.18em;
  opacity: 0.88;
  margin-top: 4px;
}

/* Per-club crest */
.af-header__club {
  display: flex; align-items: center; gap: 10px;
  padding-left: 16px; margin-left: 6px;
  min-width: 0;   /* 2026-06-11: long club names wrap instead of blowing out the header */
  border-left: 1px solid rgba(255,255,255,0.30);
}
.af-header__club img {
  height: 36px; width: auto; display: block;
  background: var(--af-white);
  border-radius: 6px;
  padding: 3px 5px;
}
.af-header__club .name {
  font-family: var(--af-font-display);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  line-height: 1.2;
  text-transform: uppercase;
}
.af-header__club .name small {
  display: block;
  opacity: 0.85;
  font-weight: 400;
  font-size: 10px;
  letter-spacing: 0.12em;
  margin-top: 2px;
}

/* Mobile */
@media (max-width: 640px) {
  .af-header { flex-wrap: wrap; padding: 14px 16px; gap: 10px; }
  .af-header__title { margin-left: 0; text-align: left; max-width: 100%; font-size: 13px; }
  .af-header__wordmark { font-size: 15px; }
}

.af-main {
  flex: 1;
  padding: 22px 16px 60px;
  max-width: 980px;
  width: 100%;
  margin: 0 auto;
  box-sizing: border-box;
}

.af-card {
  background: var(--af-card);
  border: 1px solid var(--af-line);
  border-radius: var(--af-radius);
  box-shadow: var(--af-shadow);
  padding: 24px;
  margin-bottom: 18px;
}

/* Headlines per 05.03 hierarchy.
   2026-06-11: leading 0.83 removed from wrappable headings (wrapped lines
   overlapped — Eugenio's recurring text-overlap class). 1.1 floor instead. */
.af-card h1, .af-card h2, .af-card h3, .af-headline {
  font-family: var(--af-font-display);
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  line-height: 1.1;
  color: var(--af-violet);
  margin: 0 0 14px;
}
.af-card h1, .af-headline { font-size: 28px; }
.af-card h2 { font-size: 20px; color: var(--af-blurple); }
.af-card h3 { font-size: 14px; color: var(--af-ink-2); letter-spacing: 0.06em; }

/* .af-tagline removed 2026-05-17 — zero references across templates/static/JS.
 * (af-tagline-ribbon stays — it IS used on 8 pages.) */

.af-footer {
  text-align: center;
  font-size: 11px;
  color: var(--af-ink-3);
  padding: 22px 12px 28px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 500;
}
.af-footer .copy { display: block; margin-top: 6px; opacity: 0.75; text-transform: none; letter-spacing: 0.02em; font-weight: 400; }

/* Buttons — primary uses Blurple (the workhorse), accent variants for callouts */
.af-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;   /* 2026-06-11: unconditional 44px touch floor on this mobile-first portal */
  padding: 12px 22px;
  background: var(--af-blurple);
  color: var(--af-white);
  border: 0;
  border-radius: 10px;
  font-family: var(--af-font-display);
  font-weight: 800;
  font-size: 13px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.15s ease, transform 0.1s ease, box-shadow 0.15s ease;
  box-shadow: 0 2px 8px rgba(110,56,213,0.25);
}
.af-btn:hover { background: var(--af-violet); color: var(--af-white); text-decoration: none;
                box-shadow: 0 4px 14px rgba(68,0,153,0.30); }
.af-btn:active { transform: scale(var(--af-press-scale)); }  /* 2026-06-11: one press language (was translateY(1px)) */
/* .af-btn--ghost / .af-btn--accent-{red,orange,turq} / .af-pill +
 * .af-pill--{turquoise,red,orange} removed 2026-05-17 — zero references
 * anywhere. .af-pill-status--* (which IS used dynamically via Jinja
 * `class="af-pill-status--{{ r.status }}"`) is a separate rule block
 * kept below. */

/* .af-details — shared <details> styling with rotating chevron.
 * Added 2026-05-17 part 8. Hoisted from staff_leave.html's
 * .sl-policy-details pattern so any admin page can opt in by adding
 * class="af-details" to a <details> element.
 *
 * Adopts --af-ease-in-out (on-screen morph per Emil's framework) for
 * the chevron rotation. Default browser triangle is hidden. */
/* Typography for summaries that DON'T already have af-section-title
 * (or similar) on them. Adopting templates that put `class="af-section-title"`
 * on the summary keep their existing font/color treatment — only the
 * chevron + cursor + list-style behaviours are added. */
.af-details summary:not(.af-section-title) {
  font-family: var(--af-font-display);
  font-size: 14px;
  font-weight: 700;
  color: var(--af-violet);
}
.af-details summary {
  cursor: pointer;
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
}
.af-details summary::-webkit-details-marker { display: none; }
.af-details summary::before {
  content: '▸';
  color: var(--af-blurple);
  transition: transform 200ms var(--af-ease-in-out, cubic-bezier(0.77, 0, 0.175, 1));
}
.af-details[open] summary::before {
  transform: rotate(90deg);
}
.af-details summary:focus-visible {
  outline: 2px solid var(--af-blurple);
  outline-offset: 2px;
  border-radius: 4px;
}
.af-details > *:not(summary) { margin-top: 12px; }

/* Form input default */
.af-input {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--af-line);
  border-radius: var(--af-radius-sm);
  font-size: 16px;   /* 2026-06-11: 16px floor kills iOS focus-zoom (was 15px) */
  font-family: var(--af-font-body);
  background: var(--af-white);
  box-sizing: border-box;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.af-input:focus {
  outline: none;
  border-color: var(--af-blurple);
  box-shadow: 0 0 0 3px var(--af-blurple-pale);
}

/* .af-blend-strip + .af-blend-strip--{orange,red} removed 2026-05-17 —
 * zero references. .af-blend-rainbow below IS used (9 pages). */

/* Section divider with all four accent stops */
.af-blend-rainbow {
  height: 4px;
  background: linear-gradient(90deg,
    var(--af-violet) 0%,
    var(--af-blurple) 25%,
    var(--af-medium-purple) 50%,
    var(--af-turquoise) 70%,
    var(--af-orange) 85%,
    var(--af-red) 100%);
}

/* ════════════════════════════════════════════════════════════════════
   LINE BLEND PATTERNS (06.01.02) — used as full-frame or border backgrounds
   per Brand Applications 07.01. Implemented as inline SVG via background
   so they work without external assets.
   ════════════════════════════════════════════════════════════════════ */

/* .af-line-blend-bg removed 2026-05-17 — zero references. */

/* Hero panel — recommended layout per 07.01 (anatomy of basic layout) */
.af-hero {
  position: relative;
  padding: 40px 28px;
  border-radius: 18px;
  overflow: hidden;
  background:
    radial-gradient(ellipse at top right, rgba(0,174,199,0.30), transparent 60%),
    radial-gradient(ellipse at bottom left, rgba(255,117,0,0.18), transparent 55%),
    var(--af-blend-violet);
  color: var(--af-white);
  box-shadow: 0 12px 40px rgba(68,0,153,0.25);
  margin-bottom: 22px;
}
.af-hero::after {
  /* Diagonal Line Blend striping per 06.01 */
  content: "";
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(115deg,
    rgba(255,255,255,0.05) 0 2px,
    transparent 2px 16px);
  pointer-events: none;
}
.af-hero > * { position: relative; z-index: 1; }

.af-hero h1, .af-hero .af-headline {
  color: var(--af-white);
  font-family: var(--af-font-display);
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  line-height: 1.1;   /* 2026-06-11: was 0.83 — wrapped hero titles overlapped */
  margin: 0 0 8px;
  font-size: 32px;
  text-shadow: 0 2px 8px rgba(0,0,0,0.20);
}
.af-hero p { color: rgba(255,255,255,0.92); margin: 4px 0 0; font-size: 14px; max-width: 560px; }

/* Monogram pattern (06.01.03) — secondary tile background */
.af-monogram-bg {
  background-image:
    radial-gradient(circle at 25% 25%, rgba(110,56,213,0.07) 1px, transparent 1.5px),
    radial-gradient(circle at 75% 75%, rgba(68,0,153,0.06) 1px, transparent 1.5px);
  background-size: 28px 28px, 28px 28px;
  background-color: var(--af-bg-tinted);
}

/* .af-card--accent + its ::before + @keyframes af-gradient-pan
 * removed 2026-05-17 — zero references anywhere. The reduced-motion
 * block below also no longer needs to disable af-card--accent::before. */

/* Hover lift on tiles — sleek micro-interaction.
   2026-06-11: gated to real hover devices (kills sticky lift-on-tap) and
   scoped to interactive cards only — static .af-card no longer lifts. */
.af-card, .tile, .af-tile {
  transition: transform 0.18s var(--af-ease-out), box-shadow 0.18s var(--af-ease-out), border-color 0.18s var(--af-ease-out);
}
@media (hover: hover) and (pointer: fine) {
  a.af-tile:hover, a.tile:hover, [data-clickable]:hover {
    transform: translateY(-2px);
    box-shadow: var(--af-shadow-lg);
  }
}

/* Underline reveal on links */
.af-link {
  position: relative; color: var(--af-blurple); font-weight: 600;
  text-decoration: none;
}
.af-link::after {
  content: "";
  position: absolute;
  left: 0; bottom: -2px;
  width: 100%; height: 2px;
  background: var(--af-blend-turquoise);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.25s ease;
}
.af-link:hover::after { transform: scaleX(1); }
.af-link:hover { text-decoration: none; color: var(--af-violet); }

/* Headline reveal on page load — 2026-06-11: unified on ease-out-expo entrances,
   80–120ms stagger steps, capped ~300ms total. */
@keyframes af-rise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}
.af-rise   { animation: af-rise 0.5s var(--af-ease-expo, cubic-bezier(0.16,1,0.3,1)) both; }
.af-rise-1 { animation: af-rise 0.5s var(--af-ease-expo, cubic-bezier(0.16,1,0.3,1)) 0.08s both; }
.af-rise-2 { animation: af-rise 0.5s var(--af-ease-expo, cubic-bezier(0.16,1,0.3,1)) 0.16s both; }
.af-rise-3 { animation: af-rise 0.5s var(--af-ease-expo, cubic-bezier(0.16,1,0.3,1)) 0.24s both; }
.af-rise-4 { animation: af-rise 0.5s var(--af-ease-expo, cubic-bezier(0.16,1,0.3,1)) 0.30s both; }

/* Glow on primary buttons — subtle brand-coloured shadow that intensifies on hover */
.af-btn { box-shadow: 0 4px 14px rgba(110,56,213,0.30); }
.af-btn:hover { box-shadow: 0 6px 22px rgba(68,0,153,0.40); }

/* Tagline ribbon (the Real AF tagline per 03.08, used as decorative element) */
.af-tagline-ribbon {
  display: inline-block;
  font-family: var(--af-font-display);
  font-weight: 900;
  font-style: italic;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 12px;
  padding: 6px 14px;
  background: var(--af-blend-orange);
  color: var(--af-white);
  border-radius: 999px;
  box-shadow: 0 4px 12px rgba(255,117,0,0.30);
}

/* .af-stat + .af-stat .num + .af-stat .label + .af-stat-row removed
 * 2026-05-17 — zero references. .af-stat-card (a different class, used
 * in admin_scorecard_lesley.html) stays below. */

/* Reduced motion respect */
@media (prefers-reduced-motion: reduce) {
  .af-card, .tile, .af-tile, .af-link::after, .af-rise, .af-rise-1, .af-rise-2, .af-rise-3, .af-rise-4 {
    animation: none !important;
    transition: none !important;
  }
  /* af-card--accent::before stripped 2026-05-17 along with its parent class. */
}
/* ════════════════════════════════════════════════════════════════════
   PORTAL REDESIGN ADDENDUM (2026-05-07)
   Adds the missing utilities so every template uses brand.css instead
   of redeclaring local styles. Builds on existing af-hero/af-card/af-btn.
   ════════════════════════════════════════════════════════════════════ */

/* Page wrapper — every interior page should sit inside this */
.af-page {
  min-height: 100vh;
  background: var(--af-bg);
  color: var(--af-ink);
  font-family: var(--af-font-body);
  -webkit-tap-highlight-color: transparent;
}
.af-page-wrap {
  max-width: 1080px;
  margin: 0 auto;
  padding: 18px 16px 40px;
}
.af-page-wrap--narrow { max-width: 760px; }
.af-page-wrap--wide { max-width: 1280px; }

/* Compact page hero (for interior pages — shorter than landing .af-hero) */
.af-page-hero {
  position: relative;
  padding: 24px 24px;
  border-radius: 16px;
  overflow: hidden;
  background:
    radial-gradient(ellipse at top right, rgba(0,174,199,0.25), transparent 55%),
    radial-gradient(ellipse at bottom left, rgba(255,117,0,0.15), transparent 50%),
    var(--af-blend-violet);
  color: var(--af-white);
  box-shadow: 0 8px 24px rgba(68,0,153,0.20);
  margin-bottom: 18px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.af-page-hero::after {
  content: "";
  position: absolute; inset: 0;
  background-image: repeating-linear-gradient(115deg,
    rgba(255,255,255,0.05) 0 2px, transparent 2px 16px);
  pointer-events: none;
}
.af-page-hero > * { position: relative; z-index: 1; }
.af-page-hero h1 {
  color: var(--af-white);
  font-family: var(--af-font-display);
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  line-height: 1.05;
  margin: 0 0 4px;
  font-size: 24px;
}
.af-page-hero .sub {
  color: rgba(255,255,255,0.92);
  font-size: 13px;
  font-weight: 400;
}
.af-page-hero .hero-actions { display: flex; gap: 10px; flex-wrap: wrap; }
.af-page-hero .hero-actions a {
  color: var(--af-white);
  text-decoration: none;
  font-weight: 600;
  font-size: 13px;
  padding: 8px 14px;
  border-radius: 8px;
  background: rgba(255,255,255,0.15);
  border: 1px solid rgba(255,255,255,0.25);
  backdrop-filter: blur(6px);
  transition: background 0.15s;
}
.af-page-hero .hero-actions a:hover { background: rgba(255,255,255,0.25); }
@media (max-width: 600px) {
  .af-page-hero { padding: 18px 18px; }
  .af-page-hero h1 { font-size: 20px; }
}

/* Stat grid — replaces the .kpis pattern duplicated across templates */
.af-stat-grid {
  display: grid;
  gap: 12px;
  /* 2026-05-28 (Lesley L4): min 230px (was 180) so cards don't cram into too
     many narrow columns and force label text to wrap under the absolute
     weight badge. auto-fit wraps to fewer rows when width is tight. */
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  margin: 0 0 18px;
}
.af-stat-card {
  background: var(--af-card);
  border: 1px solid var(--af-line);
  border-radius: var(--af-radius);
  padding: 16px 18px;
  position: relative;
  min-width: 0;            /* grid-item overflow safety — never let content push past the cell */
  overflow-wrap: anywhere; /* long numbers / words break instead of overflowing */
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.af-stat-card:hover {
  transform: translateY(-1px);
  box-shadow: var(--af-shadow);
}
.af-stat-card .label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--af-ink-3);
  font-weight: 600;
  margin-bottom: 6px;
  /* 2026-05-28 (Lesley L4): reserve the top-right corner so a long label that
     wraps to a second line never runs under the absolute .weight badge. */
  padding-right: 70px;
  overflow-wrap: break-word;
}
.af-stat-card .num {
  font-family: var(--af-font-display);
  font-weight: 900;
  font-size: 30px;
  color: var(--af-violet);
  line-height: 1;
  letter-spacing: 0.01em;
}
.af-stat-card .meta {
  font-size: 12px;
  color: var(--af-ink-2);
  margin-top: 6px;
  line-height: 1.4;
}
.af-stat-card .weight {
  position: absolute;
  top: 12px;
  right: 14px;
  font-size: 10px;
  color: var(--af-ink-3);
  font-weight: 600;
  letter-spacing: 0.04em;
}
.af-stat-card.met .num { color: var(--af-success); }
.af-stat-card.miss .num { color: var(--af-blurple); }
/* 2026-06-11: accent stripes (border-left) are banned — full border + bg tint */
.af-stat-card.miss { border: 1px solid var(--af-blurple); background: rgba(110,56,213,0.06); }
.af-stat-card.met  { border: 1px solid var(--af-success); background: rgba(31,138,74,0.06); }

/* Section heading — replaces the duplicated h2 / h3.section pattern */
.af-section-title {
  font-family: var(--af-font-display);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.10em;
  color: var(--af-blurple);
  margin: 24px 0 10px;
}

/* Brand-styled data table */
.af-data-table {
  width: 100%;
  border-collapse: collapse;
  background: var(--af-card);
  border-radius: var(--af-radius);
  overflow: hidden;
  font-size: 13px;
  box-shadow: 0 2px 8px rgba(110,56,213,0.04);
  border: 1px solid var(--af-line);
}
.af-data-table thead th {
  background: var(--af-bg);
  padding: 10px 14px;
  text-align: left;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--af-ink-3);
  border-bottom: 1px solid var(--af-line);
}
.af-data-table tbody td {
  padding: 12px 14px;
  border-bottom: 1px solid #f0f0f3;
  vertical-align: middle;
}
.af-data-table td { overflow-wrap: break-word; }  /* 2026-06-11: long emails/names wrap; use .break-id for IDs */
.af-data-table tbody tr:last-child td { border-bottom: 0; }
.af-data-table tbody tr:hover { background: var(--af-blurple-pale); }
.af-data-table .right { text-align: right; font-variant-numeric: tabular-nums; }

/* Form group — replaces label/input duplication */
.af-form-group { margin: 14px 0 0; }
.af-form-group label {
  display: block;
  font-weight: 600;
  font-size: 13px;
  color: var(--af-violet);
  margin-bottom: 6px;
  letter-spacing: 0.02em;
}
.af-form-group .help {
  font-size: 12px;
  color: var(--af-ink-3);
  margin-top: 6px;
  line-height: 1.45;
}
.af-form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
/* .af-form-row--3 removed 2026-05-17 — zero references. */
@media (max-width: 540px) {
  .af-form-row { grid-template-columns: 1fr; }
}

/* Leave status pills — single source of truth, replace inline color blocks */
.af-pill-status {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  padding: 4px 10px;
  border-radius: 999px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  border: 1px solid transparent;
}
.af-pill-status--pending   { background: #fef3c7; color: #92400e; border-color: #fde68a; }
.af-pill-status--approved  { background: #d1fae5; color: #065f46; border-color: #6ee7b7; }
.af-pill-status--rejected  { background: #fee2e2; color: #b91c1c; border-color: #fecaca; }
.af-pill-status--cancelled { background: #e5e7eb; color: #4b5563; border-color: #d1d5db; }

/* Alert banners — for form messages */
.af-alert {
  padding: 12px 14px;
  border-radius: var(--af-radius-sm);
  font-size: 14px;
  margin-bottom: 14px;
  border: 1px solid;
  font-weight: 500;
}
.af-alert--ok  { background: #d1fae5; color: #065f46; border-color: #6ee7b7; }
.af-alert--err { background: #fee2e2; color: #b91c1c; border-color: #fecaca; }
.af-alert--info { background: var(--af-blurple-pale); color: var(--af-violet); border-color: rgba(110,56,213,0.30); }

/* Empty state — 2026-06-11: designed (dashed panel + optional title/action), icon-free */
.af-empty {
  text-align: center;
  color: var(--af-ink-3);
  font-size: 13px;
  padding: 22px 16px;
  font-style: normal;
  background: var(--af-surface, #fdfcff);
  border: 1px dashed var(--af-line);
  border-radius: 12px;
}
.af-empty a { color: var(--af-blurple); font-weight: 600; }
.af-empty__title { display: block; font-weight: 600; color: var(--af-ink-2); margin-bottom: 4px; }
.af-empty__action {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: 10px 18px; margin-top: 10px;
  border: 1px solid var(--af-blurple); border-radius: 10px;
  background: transparent; color: var(--af-blurple);
  font-weight: 700; font-size: 13px; text-decoration: none;
}

/* Footer */
.af-page-footer {
  text-align: center;
  padding: 32px 0 18px;
  color: var(--af-ink-3);
  font-size: 11px;
  letter-spacing: 0.04em;
}
.af-page-footer .copy { display: block; margin-top: 4px; opacity: 0.7; }

/* Top breadcrumb — unified back-link pattern */
.af-breadcrumb {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0 0 12px;
  font-size: 13px;
  color: var(--af-ink-2);
}
.af-breadcrumb a {
  color: var(--af-blurple);
  text-decoration: none;
  font-weight: 600;
}
.af-breadcrumb a:hover { color: var(--af-violet); text-decoration: underline; }
.af-breadcrumb .sep { color: var(--af-ink-3); }

/* Tile (portal grid) — refactor of the .tile pattern */
.af-tile {
  background: var(--af-card);
  border-radius: var(--af-radius);
  padding: 18px 14px;
  text-decoration: none;
  color: var(--af-ink);
  box-shadow: 0 2px 8px rgba(110,56,213,0.06);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  min-height: 116px;
  position: relative;
  border: 1px solid transparent;
}
.af-tile:hover {
  box-shadow: var(--af-shadow);
  border-color: var(--af-blurple-pale);
}
.af-tile .icon { font-size: 28px; line-height: 1; }
.af-tile .label { font-weight: 700; font-size: 14px; line-height: 1.2; color: var(--af-ink); }
.af-tile .blurb { font-size: 11px; color: var(--af-ink-3); line-height: 1.4; }
.af-tile--desktop { background: var(--af-bg-tinted); }
.af-tile--desktop::after {
  content: "🖥";
  position: absolute; bottom: 10px; right: 12px; opacity: 0.35; font-size: 11px;
}
.af-tile-badge {
  position: absolute; top: 10px; right: 10px;
  min-width: 22px; height: 22px; padding: 0 7px;
  border-radius: 11px;
  background: var(--af-red);
  color: var(--af-white);
  font-size: 11px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  letter-spacing: 0;
}
.af-tile-grid {
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 600px) { .af-tile-grid { grid-template-columns: repeat(3, 1fr); gap: 12px; } }
@media (min-width: 900px) { .af-tile-grid { grid-template-columns: repeat(4, 1fr); gap: 14px; } }

/* Today strip — branded clock-status block on portal */
.af-today {
  background: var(--af-blend-violet);
  border-radius: var(--af-radius);
  padding: 18px 20px;
  color: var(--af-white);
  margin: 8px 0 18px;
  box-shadow: 0 6px 18px rgba(110,56,213,0.22);
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  position: relative;
  overflow: hidden;
}
.af-today::after {
  content: "";
  position: absolute; inset: 0;
  background-image: repeating-linear-gradient(115deg,
    rgba(255,255,255,0.05) 0 2px, transparent 2px 14px);
  pointer-events: none;
}
.af-today > * { position: relative; z-index: 1; }
.af-today .label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.10em;
  font-weight: 700;
  opacity: 0.88;
  margin-right: 8px;
}
.af-today .status-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 14px;
  border-radius: 999px;
  font-weight: 700;
  font-size: 13px;
  background: rgba(255,255,255,0.18);
  border: 1px solid rgba(255,255,255,0.20);
}
.af-today .status-dot {
  width: 8px; height: 8px; border-radius: 50%;
}
.af-today .status-dot--working { background: #34d399; box-shadow: 0 0 0 3px rgba(52,211,153,0.30); }
.af-today .status-dot--on_break { background: #fbbf24; }
.af-today .status-dot--off_duty,
.af-today .status-dot--never_clocked_in { background: rgba(255,255,255,0.55); }
.af-today .shift-info { font-size: 13px; opacity: 0.92; }
.af-today .cta-clock {
  background: var(--af-white);
  color: var(--af-violet);
  border: 0;
  padding: 10px 18px;
  border-radius: 10px;
  font-weight: 800;
  font-size: 13px;
  cursor: pointer;
  text-decoration: none;
  display: inline-block;
  margin-left: auto;
  box-shadow: 0 2px 6px rgba(0,0,0,0.15);
}
.af-today .cta-clock:hover { background: var(--af-bg-tinted); }

/* ════════════════════════════════════════════════════════════════════
   UI OVERHAUL 2026-06-11 — portal shared layer (FIX_PLAN_pt §1B)
   For pages that do NOT include _admin_styles.html. Builds on the
   shared UI layer at the top of this file.
   ════════════════════════════════════════════════════════════════════ */
:root {
  --af-bg-tint: #f7f5fc;
  --z-raised: 1; --z-dropdown: 20; --z-banner: 30; --z-toast: 40;
}

/* table wrapper skin (base overflow rules live in the shared layer above) */
.table-scroll { border-radius: 12px; }
.table-scroll > table { margin: 0; border-radius: 0; }

/* 44px hit area on small text links, zero layout shift */
.tap { display: inline-block; padding: 12px 10px; margin: -12px -10px; }

.af-num { font-variant-numeric: tabular-nums; }

/* real-red error alert (violet is never an error color) */
.af-alert-error, .alert.error { background: #fef2f2; border: 1px solid #fecaca; color: #b91c1c; }

/* me_book / me_classes Evolt banner — flat violet, no gradient */
.af-promo-banner { background: var(--af-blurple); color: #f3eefc; border-radius: 12px; padding: 12px 16px; }
.af-demo-banner { background: #4b2e57; color: #f3eefc; padding: 8px 12px; font-size: 12px; text-align: center; }

/* single shared footer (see templates/_portal_footer.html) */
.af-footer.cp-ip, .af-shared-footer { text-align: center; color: var(--af-ink-3); font-size: 12px; margin: 24px 0 12px; }
.af-shared-footer p { margin: 4px 0; }
.af-shared-footer .cp-ip { opacity: 0.75; }

/* header overflow safety (_brand_header L46) */
.af-header__wordmark, .af-header__title { min-width: 0; overflow-wrap: anywhere; }

/* eyebrow label — shared typography utility (referenced by admin_hr_overview P2,
   elevation pass §3 item 7: uppercase only for short letter-spaced labels) */
.af-eyebrow {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--af-blurple);
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

/* portal tile badge (portal.html L104) */
.af-tile-badge { min-width: 20px; padding: 1px 6px; border-radius: 999px; text-align: center;
  font-variant-numeric: tabular-nums; }

/* stat grid responsiveness (kills the !important in admin_scorecard_lesley L61) */
.af-stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr)); gap: 12px; }
.af-stat-grid > * { min-width: 0; }

/* touch floor for brand.css-only pages (checkbox/radio/range excluded —
   a 44px min-height would distort them; their hit area comes from the label) */
@media (pointer: coarse) {
  .af-btn, button { min-height: 44px; }
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]), select, textarea {
    font-size: 16px; min-height: 44px;
  }
}

/* ── Elevation pass (FIX_PLAN_css §3) — one motion language ── */
/* page-load reveal choreography (CSS-first; tiny IO script adds .in;
   no-JS fallback: templates render with .in by default) */
.reveal { opacity: 0; transform: translateY(12px); }
.reveal.in { opacity: 1; transform: none;
             transition: opacity var(--dur-entrance, 600ms) var(--ease-out-expo, cubic-bezier(0.16,1,0.3,1)),
                         transform var(--dur-entrance, 600ms) var(--ease-out-quart, cubic-bezier(0.25,1,0.5,1)); }
.reveal:nth-child(2) { transition-delay: 90ms; }   /* 80–120ms stagger steps */
.reveal:nth-child(3) { transition-delay: 180ms; }

/* micro-interactions */
.press { transition: transform var(--dur-feedback, 120ms) var(--ease-out-quart, cubic-bezier(0.25,1,0.5,1)); }
.press:active { transform: scale(var(--press-scale, 0.97)); }
.lift:hover { transform: translateY(-1px); box-shadow: 0 4px 16px rgba(110,56,213,0.18); }
@media (hover: none) { .lift:hover { transform: none; box-shadow: none; } }
.focus-ring:focus-visible { outline: 2px solid rgba(110,56,213,0.55); outline-offset: 2px; }

/* table-row hover tint */
tbody tr { transition: background-color var(--dur-feedback, 120ms) var(--ease-out-quart, cubic-bezier(0.25,1,0.5,1)); }
tbody tr:hover { background: rgba(110,56,213,0.05); }

/* reduced-motion: this layer is self-sufficient (extends brand.css's own block) */
@media (prefers-reduced-motion: reduce) {
  .table-scroll *, .af-rise, .af-rise-1, .af-rise-2, .af-rise-3, .af-rise-4,
  .af-btn, button, .meter > span, .reveal, .reveal.in, .press, .lift, tbody tr {
    animation: none !important;
    transition: none !important;
  }
  .reveal { opacity: 1; transform: none; }
}
