/* ============================================================
   Pure Dental — Onboarding Portal
   Design tokens + theming. Drives visual-style tweaks via
   [data-style] and --accent-hue on :root.
   ============================================================ */

@import url('https://fonts.googleapis.com/css2?family=Abril+Fatface&family=Cinzel+Decorative:wght@400;700&family=Rochester&family=Oregano&family=Sixtyfour&family=Kode+Mono:wght@400;500;600;700&family=Manufacturing+Consent&family=Astloch:wght@400;700&family=Jim+Nightshade&family=Sekuya&family=Handjet:wght@400;500;700&family=IBM+Plex+Mono:wght@400;500;600&family=IBM+Plex+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&family=Jost:wght@400;500;600;700&family=Lora:ital,wght@0,400..700;1,400..600&family=Manrope:wght@400;500;600;700&family=Great+Vibes&family=Spectral:ital,wght@0,400;0,500;0,600;1,400&display=swap');

:root {
  --accent-hue: 220;          /* tweakable */
  --accent-chroma: 0.11;
  --accent-l: 0.56;           /* accent lightness — drag a swatch up/down */

  /* Monochrome tint: neutrals lean toward --neutral-hue at a chroma scaled by
     --tint-mult (1 = today's look). When tint is on, --neutral-hue follows the
     accent so the whole "paper" leans that color. Text keeps fixed low chroma. */
  --neutral-hue: 240;
  --tint-mult: 1;
  --ink-tint: 0;
  --paper-l: 0;

  /* Brand: dental blue/teal built from --accent-hue */
  --accent:        oklch(var(--accent-l) var(--accent-chroma) var(--accent-hue));
  --accent-strong: oklch(calc(var(--accent-l) - 0.09) var(--accent-chroma) var(--accent-hue));
  --accent-soft:   oklch(0.95 0.03 var(--accent-hue));
  --accent-softer: oklch(0.975 0.018 var(--accent-hue));
  --accent-ring:   oklch(0.56 var(--accent-chroma) var(--accent-hue) / 0.25);
  --on-accent:     #fff;          /* text/icons on accent fills (flips dark for light accents) */
  --accent-edge:   transparent;   /* border on accent fills, visible only for light accents */
  --teal:          oklch(0.7 0.1 195);
  --teal-soft:     oklch(0.96 0.03 195);

  /* Neutrals — hue + chroma driven by the tint controls; ink keeps low fixed
     chroma so text stays legible at any tint. */
  /* Neutrals — hue + chroma driven by the tint controls; ink keeps low fixed
     chroma so text stays legible at any tint. */
  --bg:        oklch(calc(0.985 - var(--paper-l)) calc(0.006 * var(--tint-mult)) var(--neutral-hue));
  --surface:   oklch(calc(1 - var(--paper-l)) calc(0.003 * var(--tint-mult)) var(--neutral-hue));
  --surface-2: oklch(calc(0.975 - var(--paper-l)) calc(0.007 * var(--tint-mult)) var(--neutral-hue));
  --line:      oklch(0.9 min(0.05, calc(0.012 * var(--tint-mult))) var(--neutral-hue));
  --line-soft: oklch(0.94 min(0.04, calc(0.008 * var(--tint-mult))) var(--neutral-hue));
  --ink:       oklch(0.28 calc(0.025 + var(--ink-tint)) var(--neutral-hue));
  --ink-2:     oklch(0.46 calc(0.022 + var(--ink-tint)) var(--neutral-hue));
  --ink-3:     oklch(0.62 calc(0.018 + var(--ink-tint)) var(--neutral-hue));

  /* Status */
  --ok:    oklch(0.62 0.13 155);
  --ok-soft: oklch(0.95 0.04 155);
  --warn:  oklch(0.74 0.13 75);
  --warn-soft: oklch(0.95 0.05 75);
  --info:  var(--accent);

  /* Shape */
  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 18px;
  --r-xl: 26px;
  --r-pill: 999px;

  /* Density (tweakable) */
  --pad: 22px;
  --gap: 18px;

  --shadow-sm: 0 1px 2px oklch(0.4 0.03 250 / 0.05), 0 1px 3px oklch(0.4 0.03 250 / 0.06);
  --shadow-md: 0 2px 6px oklch(0.4 0.03 250 / 0.06), 0 8px 24px oklch(0.4 0.03 250 / 0.07);
  --shadow-lg: 0 8px 20px oklch(0.4 0.03 250 / 0.08), 0 24px 60px oklch(0.4 0.03 250 / 0.12);

  --font-body: 'Hanken Grotesk', system-ui, sans-serif;
  --font-display: 'Bricolage Grotesque', 'Hanken Grotesk', sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, monospace;

  --maxw: 1120px;
}

/* ---- Appearance: tint strength, corners, dark mode (set by the appearance menu) ---- */
/* Subtle/Tinted punch up the accent-soft family (the "accented elements");
   the neutral wash strength itself is set in applyAppearance. */
[data-tint="subtle"], [data-tint="tinted"], [data-tint="unprofessional"] {
  --accent-soft:   oklch(0.92 0.075 var(--accent-hue));
  --accent-softer: oklch(0.96 0.04 var(--accent-hue));
}

/* ---- Tinted: a true in-between, not a softer Unprofessional ----
   The full-screen wash belongs to Unprofessional alone — here the page bg and the text
   stay neutral. Tinted instead puts color in the CARDS (a whisper of accent muted toward
   white; toward the surface tone in dark) and in the LINEWORK (accent borders/dividers/
   outlines). Chroma rides --accent-chroma so Mono stays achromatic; lightness adapts per
   theme. The card stays brighter+hued while the page keeps its neutral tone, so the accent
   border + shadow do the separating. */
[data-tint="tinted"] {
  /* PAGE: held at (roughly) the OLD card level and deliberately NOT slider-driven — it
     rides only the clamped --accent-chroma, so the background barely shifts as you drag.
     That near-static, white-ish page is what keeps Tinted from becoming Unprofessional. */
  --surface:   oklch(0.99  calc(var(--accent-chroma) * 0.20) var(--accent-hue));
  /* CARDS + LINEWORK: these carry the "oomph". They multiply by --accent-sat so they keep
     gaining tint past the chroma clamp, each capped by a tinted ceiling that sits well
     below Unprofessional's full wash. Cards also sit a touch darker than the page so they
     read as dyed panels. */
  --surface-2: oklch(calc(0.955 - 0.021 * (var(--accent-sat) * var(--accent-sat) - 1)) min(0.160, calc(var(--accent-chroma) * 0.28 * var(--accent-sat) * var(--accent-sat))) var(--accent-hue));
  --line:      oklch(0.85  min(0.230, calc(var(--accent-chroma) * 0.55 * var(--accent-sat) * var(--accent-sat))) var(--accent-hue));
  --line-soft: oklch(0.91  min(0.150, calc(var(--accent-chroma) * 0.40 * var(--accent-sat) * var(--accent-sat))) var(--accent-hue));
}
/* Tinted (light only): the icon chips (--accent-soft squares behind card icons) climb WITH
   the slider too, but land BETWEEN the card behind them and full saturation — a bit past
   halfway at max, so each square reads richer than its card without going fully saturated.
   Anchored at sat=1 to the shared default (0.92 L / 0.075 C), so nothing shifts until you
   drag up. Mono keeps its inline achromatic override. */
html:not([data-theme="dark"])[data-tint="tinted"] {
  --accent-soft: oklch(calc(0.92 - 0.030 * (var(--accent-sat) * var(--accent-sat) - 1)) min(0.190, calc(0.075 * var(--accent-sat) * var(--accent-sat))) var(--accent-hue));
}
/* Yellow is the outlier: it sits very light (L .85), so at max its chip converges with the
   icon on top (--accent-strong ≈ L .76) and its topbar converges with the tooth tile
   (--accent). Yellow-only, light-tinted-only: hold the chip lighter + less saturated than
   its icon, and the topbar paler than the tooth tile — the cap nudged down just for yellow.
   sat=1 stays identical to the general rule, so defaults don't move. */
html:not([data-theme="dark"])[data-tint="tinted"][data-accent="yellow"] {
  --surface-2:   oklch(calc(0.955 - 0.012 * (var(--accent-sat) * var(--accent-sat) - 1)) min(0.105, calc(var(--accent-chroma) * 0.28 * var(--accent-sat) * var(--accent-sat))) var(--accent-hue));
  --accent-soft: oklch(calc(0.92  - 0.015 * (var(--accent-sat) * var(--accent-sat) - 1)) min(0.100, calc(0.075 * var(--accent-sat) * var(--accent-sat))) var(--accent-hue));
}
[data-theme="dark"][data-tint="tinted"] {
  --surface:   oklch(0.255 calc(var(--accent-chroma) * 0.20) var(--accent-hue));
  --surface-2: oklch(0.295 calc(var(--accent-chroma) * 0.26) var(--accent-hue));
  --line:      oklch(0.42  calc(var(--accent-chroma) * 0.45) var(--accent-hue));
  --line-soft: oklch(0.34  calc(var(--accent-chroma) * 0.30) var(--accent-hue));
}

/* Unprofessional: homogenize the nav into the theme — accent-colored labels and a
   faintly accent-tinted bar (surface-2 is already washed at this level). */
[data-tint] .topbar { background: var(--surface-2); }
[data-tint="unprofessional"] .navgroup > button:not(.active),
[data-tint="unprofessional"] .mobile-nav button:not(.active) { color: var(--accent-strong); }

/* Yellow accent sits very light (L .85) so even --accent-strong washes out as nav-bar text
   — every other accent is dark enough. Darken ONLY the nav bar (not popups) to a legible
   gold, for both tinted-inactive labels and the active item. Specificity beats the rules
   above so it applies regardless of tint. */
[data-tint="unprofessional"][data-accent="yellow"] .navgroup > button:not(.active),
[data-tint="unprofessional"][data-accent="yellow"] .mobile-nav button:not(.active) { color: oklch(0.46 0.14 105); }
[data-accent="yellow"] .navgroup > button.active,
[data-accent="yellow"] .mobile-nav button.active { color: oklch(0.43 0.14 105); }

/* Dark mode: same contrast eye, inverted. The bar is dark, so accent-tinted nav labels
   must stay LIGHT (--ink already flips light, covering the non-tinted case). These generic
   accent rules also cover yellow, and are placed last so they win on specificity ties. */
[data-theme="dark"][data-tint="unprofessional"] .navgroup > button:not(.active),
[data-theme="dark"][data-tint="unprofessional"] .mobile-nav button:not(.active) { color: oklch(0.82 var(--accent-c-text, var(--accent-chroma)) var(--accent-hue)); }
[data-theme="dark"] .navgroup > button.active,
[data-theme="dark"] .mobile-nav button.active { color: oklch(0.86 var(--accent-c-text, var(--accent-chroma)) var(--accent-hue)); }

[data-corners="sharp"] { --r-sm: 1px; --r-md: 2px; --r-lg: 4px; --r-xl: 6px; --r-pill: 6px; }
[data-corners="cut"] { --r-sm: 0; --r-md: 0; --r-lg: 0; --r-xl: 0; --r-pill: 5px; }
[data-corners="cut"] .card { border-radius: 0; clip-path: polygon(11px 0, calc(100% - 11px) 0, 100% 11px, 100% calc(100% - 11px), calc(100% - 11px) 100%, 11px 100%, 0 calc(100% - 11px), 0 11px); }
/* Cut corners can't carry a drop-shadow (clip-path clips it), so cut cards render clean. */

/* Contrast (accessibility) — boost ink + borders for legibility, but keep the
   themed surfaces & accent so customization still shows through. */
[data-contrast="high"] {
  --ink: oklch(0.1 calc(0.02 + var(--ink-tint)) var(--neutral-hue));
  --ink-2: oklch(0.26 calc(0.02 + var(--ink-tint)) var(--neutral-hue));
  --ink-3: oklch(0.4 calc(0.015) var(--neutral-hue));
  --line: oklch(0.5 calc(0.02 * var(--tint-mult)) var(--neutral-hue));
  --line-soft: oklch(0.66 calc(0.015 * var(--tint-mult)) var(--neutral-hue));
}
[data-contrast="high"] .card { border: 2px solid var(--line); }
[data-theme="dark"][data-contrast="high"] {
  --ink: oklch(1 0 0);
  --ink-2: oklch(0.9 0.01 var(--neutral-hue));
  --ink-3: oklch(0.78 0.01 var(--neutral-hue));
  --line: oklch(0.76 0.01 var(--neutral-hue));
  --line-soft: oklch(0.56 0.01 var(--neutral-hue));
}

/* Text size — content zoom (inline px sizes ignore font-size, so zoom is needed).
   NOTE: zoom scales geometry too. To stop text size from reflowing/ballooning the stat
   cards, those grids use .statgrid below (fixed column counts via media queries, which
   are immune to this zoom) instead of content-based auto-fit. */
[data-textsize="s"] .main { zoom: 0.9; }
[data-textsize="m"] .main { zoom: 1.0; }
[data-textsize="l"] .main { zoom: 1.1; }

/* Zoom-stable stat-card grid. auto-fit + minmax(px) reflows when the text-size zoom
   scales the px, so cards jump rows as you change size. Fixed column counts keyed to the
   real viewport (media queries ignore .main's zoom) keep the layout put — only the text
   inside the cards scales. */
.statgrid { display: grid; gap: var(--gap); grid-template-columns: 1fr; }
@media (min-width: 620px) { .statgrid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1080px) { .statgrid { grid-template-columns: repeat(4, 1fr); } }
/* 5-up variant (Time & Overtime analytics): five stats in a stable row on wide screens. */
@media (min-width: 1080px) { .statgrid.five { grid-template-columns: repeat(5, 1fr); } }
@media (min-width: 620px) and (max-width: 1079px) { .statgrid.five { grid-template-columns: repeat(3, 1fr); } }

/* Applicant pipeline board: N-up on wide screens, fixed 3-up (wraps to 2 rows) below the
   breakpoint instead of horizontal scroll — flex instead of grid there so a short last row
   (e.g. 5 stages) centers instead of hugging the left edge. */
.ats-board { display: grid; grid-template-columns: repeat(var(--ats-cols, 5), minmax(150px, 1fr)); }
@media (max-width: 900px) {
  .ats-board { display: flex !important; flex-wrap: wrap; justify-content: center; }
  .ats-board > * { flex: 0 1 calc(33.333% - 8px); min-width: 150px; }
}

/* Motion */[data-motion="calm"] * { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.06s !important; }
[data-motion="bouncy"] button, [data-motion="bouncy"] .card { transition: transform .22s cubic-bezier(.34, 1.56, .64, 1); }
[data-motion="bouncy"] button:active { transform: scale(0.94); }

[data-theme="dark"] {
  --bg:        oklch(calc(0.185 - var(--paper-l)) calc(0.006 * var(--tint-mult)) var(--neutral-hue));
  --surface:   oklch(calc(0.235 - var(--paper-l)) calc(0.006 * var(--tint-mult)) var(--neutral-hue));
  --surface-2: oklch(calc(0.275 - var(--paper-l)) calc(0.008 * var(--tint-mult)) var(--neutral-hue));
  --line:      oklch(0.34 min(0.05, calc(0.012 * var(--tint-mult))) var(--neutral-hue));
  --line-soft: oklch(0.30 min(0.04, calc(0.010 * var(--tint-mult))) var(--neutral-hue));
  --ink:       oklch(0.95 calc(0.012 + var(--ink-tint)) var(--neutral-hue));
  --ink-2:     oklch(0.78 calc(0.014 + var(--ink-tint)) var(--neutral-hue));
  --ink-3:     oklch(0.60 calc(0.014 + var(--ink-tint)) var(--neutral-hue));
  --accent-soft:   oklch(0.36 0.07 var(--accent-hue));
  --accent-softer: oklch(0.29 0.05 var(--accent-hue));
  --ok-soft:   oklch(0.33 0.06 155);
  --warn-soft: oklch(0.35 0.07 75);
  --teal-soft: oklch(0.32 0.05 195);
  --shadow-sm: 0 1px 2px oklch(0 0 0 / 0.35);
  --shadow-md: 0 2px 8px oklch(0 0 0 / 0.4);
  --shadow-lg: 0 12px 40px oklch(0 0 0 / 0.55);
  color-scheme: dark;
}
/* Dark-mode status chips: lighten the text so it reads on the dark soft backgrounds. */
[data-theme="dark"] .badge-ok { color: oklch(0.82 0.12 155); }
[data-theme="dark"] .badge-warn { color: oklch(0.84 0.11 75); }

/* Light/near-white accent in light mode → high-contrast outline mode: accent fills become
   ink outlines on a clear background, and accent icons/text drop to ink so nothing washes out. */
[data-accent-tone="light"] {
  --accent: var(--ink);
  --accent-strong: var(--ink);
  --accent-ring: oklch(0.3 0 0 / 0.22);
}
[data-accent-tone="light"] .btn-primary,
[data-accent-tone="light"] .assistant-fab-btn {
  background: var(--surface); color: var(--ink); border: 1.5px solid var(--ink); box-shadow: none;
}
[data-accent-tone="light"] .btn-primary:hover,
[data-accent-tone="light"] .assistant-fab-btn:hover { background: var(--surface-2); color: var(--ink); }
[data-accent-tone="light"] .brand .mark { background: var(--surface); color: var(--ink); border: 1.5px solid var(--ink); }
[data-accent-tone="light"] .navgroup > button.active,
[data-accent-tone="light"] .mobile-nav button.active { background: transparent; color: var(--ink); box-shadow: inset 0 0 0 1.5px var(--ink); }
[data-accent-tone="light"] .badge-prog { background: transparent; color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); }
/* A white tooth suits a dental brand — keep the header tooth WHITE on every colored
   tile (pink, yellow, etc., whose lightness would otherwise flip it to ink). The only
   exception is the genuine near-white "outline" theme (data-accent-tone=light, handled
   above), where an ink tooth on its white tile is correct. */
html:not([data-accent-tone="light"]) .brand .mark { color: #fff; }

/* ---- Visual style variants (tweak: data-style) ----
   Warm/cool is driven by --neutral-hue (set in applyAppearance) so it works in
   light AND dark without overriding neutrals or corners. */
[data-style="modern"] {
  --accent-chroma: 0.14;
  --bg:        oklch(0.97 0.012 250);
  --surface:   oklch(1 0 0);
  --surface-2: oklch(0.965 0.012 250);
  --line:      oklch(0.88 0.016 250);
  --ink:       oklch(0.2 0.03 255);
  --r-sm: 6px; --r-md: 9px; --r-lg: 13px; --r-xl: 18px;
  --shadow-md: 0 2px 6px oklch(0.3 0.04 255 / 0.07), 0 10px 30px oklch(0.3 0.04 255 / 0.1);
  --shadow-lg: 0 10px 24px oklch(0.3 0.04 255 / 0.1), 0 30px 70px oklch(0.3 0.04 255 / 0.16);
}

/* ---- Density (tweak: data-density) ---- */
[data-density="compact"] { --pad: 15px; --gap: 12px; }
[data-density="comfy"]   { --pad: 28px; --gap: 24px; }

* { box-sizing: border-box; }
/* Form controls don't inherit font-family by default — make them follow the theme. */
button, input, select, textarea { font-family: inherit; }
.cust-menu::-webkit-scrollbar { display: none; }
html, body { margin: 0; height: 100%; }
body {
  font-family: var(--font-body);
  background: var(--bg);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
#root { min-height: 100%; }

h1, h2, h3, h4 { font-family: var(--font-display); font-weight: 600; letter-spacing: -0.02em; margin: 0; color: var(--ink); }
p { margin: 0; }
button { font-family: inherit; cursor: pointer; }
.mono { font-family: var(--font-mono); }

::selection { background: var(--accent-ring); }

/* ===== App shell ===== */
.app { min-height: 100vh; display: flex; flex-direction: column; }

.topbar {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; gap: 16px;
  padding: 0 clamp(16px, 4vw, 40px); height: 64px;
  background: oklch(1 0 0 / 0.82);
  backdrop-filter: saturate(1.4) blur(14px);
  border-bottom: 1px solid var(--line);
}
.brand { display: flex; align-items: center; gap: 11px; font-family: var(--font-display); font-weight: 700; font-size: 18px; letter-spacing: -0.03em; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
/* DECORATIVE DISPLAY FACES — weight honesty. The global heading rule (font-weight:600,
   letter-spacing:-0.02em) faux-bolds and crunches single-weight display fonts, so they
   render fatter/rounder than their true design (and than the font picker preview). Each
   ornamental face below is pinned to its real 400 weight with the negative tracking
   removed, so what you pick is what you get. (Modern/Terminal are real multi-weight
   families and keep the 600; Bold/Sekuya is intentionally heavy and stays as tuned.) */

/* Editorial — Abril Fatface, a high-contrast didone display, drawn at a single weight. */
[data-font="editorial"] :is(h1, h2, h3, h4, .brand) { font-weight: 400; letter-spacing: normal; }

/* Sweet — Rochester, an upright, tidy casual script (no connecting loops). Pin 400 and
   normalize x-height so it sizes like a real header. Body is Just Another Hand. */
[data-font="sweet"] :is(h1, h2, h3, h4, .brand) { font-weight: 400; letter-spacing: normal; font-size-adjust: none; }
/* Sweet's body (Oregano) is a casual italic hand with a fairly normal x-height; light
   x-height normalization keeps it comfortable. Glyph-only scaling, layout stays put. */
[data-font="sweet"] .brand small { margin-top: 9px; }
/* Noir's display (Manufacturing Consent) is an ornate single-weight blackletter — the
   global 600 faux-bolds it into mush. Pin 400. Its cap proportions render small, so
   font-size-adjust scales the glyphs up to feel like a real header; tracking stays tight
   since blackletter is dense and looks disconnected when over-spaced. */
[data-font="noir"] :is(h1, h2, h3, h4, .brand) { font-weight: 400; letter-spacing: 0.01em; font-size-adjust: 0.62; }
/* Noir's body (Jim Nightshade) is a script with a small x-height, so it reads smaller and
   harder than the other body faces at the same px. Normalize by x-height to enlarge it for
   readability — font-size-adjust scales glyphs only, so card sizes/layout stay put. */
[data-font="noir"] .app { font-size-adjust: 0.6; }
/* Bold: no lowercase anywhere — force uppercase on every element (buttons/inputs
   don't reliably inherit text-transform, which left them lowercase). */
[data-font="bold"] .app, [data-font="bold"] .app * { text-transform: uppercase; }
/* Sekuya is an all-caps display face — a hair of tracking opens the caps. */
[data-font="bold"] :is(h1, h2, h3, h4, .brand) { letter-spacing: 0.012em; }

/* Bold style — marker-highlight behind headers (a nod to Zilla Slab Highlight, but
   themeable: a translucent accent band drawn behind the text, so it works on any
   surface in light OR dark, and the letters keep their own color on top). Tuned to
   Sekuya's all-caps metrics: caps sit high in the line box, so the band is nudged up
   to wrap the letters evenly with a little breathing room top and bottom. */
[data-font="bold"] .app :is(h1, h2, h3) {
  width: fit-content; max-width: 100%;
  background-image: linear-gradient(
    color-mix(in oklch, var(--accent) 46%, transparent),
    color-mix(in oklch, var(--accent) 46%, transparent));
  background-repeat: no-repeat;
  background-size: 100% 1.12em;
  background-position: 0 38%;
  padding-inline: 0.16em;
  margin-inline: -0.16em;
  border-radius: 4px;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}
.brand > span:not(.mark) { display: flex; flex-direction: column; line-height: 1.12; white-space: nowrap; }
.brand .mark {
  width: 34px; height: 34px; border-radius: 10px; flex: none;
  display: grid; place-items: center;
  background: linear-gradient(150deg, var(--accent), var(--accent-strong));
  color: var(--on-accent); box-shadow: var(--shadow-sm); border: 1px solid var(--accent-edge);
}
.brand .mark svg { width: 19px; height: 19px; }
.brand small { display: block; font-family: var(--font-body); font-weight: 500; font-size: 11px; color: var(--ink-3); letter-spacing: 0; margin-top: 3px; }

/* grouped top nav (app.jsx NAV_GROUPS) */
.navgroups { display: flex; align-items: center; gap: 2px; }
@media (max-width: 800px) { .navgroups { display: none; } }

/* Agent Automations console — two boxes that stretch to fill, stacking on narrow screens */
.agent-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gap); align-items: start; }
@media (max-width: 760px) { .agent-grid { grid-template-columns: 1fr; } }
.navgroup { position: relative; }
.navgroup > button { display: inline-flex; align-items: center; gap: 4px; border: none; background: none; color: var(--ink); font-size: 15px; font-weight: 500; padding: 8px 13px; border-radius: var(--r-pill); transition: all .16s; white-space: nowrap; cursor: pointer; font-family: var(--font-body); }
.navgroup > button:hover { background: var(--surface-2); color: var(--ink); }
.navgroup > button.active { background: var(--accent-soft); color: var(--accent-strong); }
.navgroup > button .caret { width: 13px; height: 13px; opacity: .55; transition: transform .16s; }
.navgroup > button[aria-expanded="true"] .caret { transform: rotate(180deg); }
.navgroup-menu { position: absolute; top: calc(100% + 6px); left: 0; z-index: 70; min-width: 196px; padding: 6px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--shadow-lg); display: flex; flex-direction: column; gap: 2px; }
.navgroup-menu button { text-align: left; border: none; background: none; color: var(--ink-2); font-size: 13.5px; font-weight: 500; padding: 8px 11px; border-radius: var(--r-md); white-space: nowrap; cursor: pointer; font-family: var(--font-body); }
.navgroup-menu button:hover { background: var(--surface-2); color: var(--ink); }
.navgroup-menu button.active { background: var(--accent-soft); color: var(--accent-strong); }
.nav-backdrop { position: fixed; inset: 0; z-index: 64; background: transparent; }

/* flat "all pages" nav (app.jsx navMode='all') — a single horizontally scrollable bar.
   Shares .navgroup button styling; the bar itself scrolls, the Admin dropdown sits
   outside the scroll region so its menu isn't clipped. */
.navflat { display: flex; align-items: center; gap: 2px; flex: 0 1 auto; min-width: 0; overflow-x: auto; overflow-y: hidden; scrollbar-width: none; scroll-behavior: smooth; }
.navflat::-webkit-scrollbar { display: none; }
.navflat .navgroup { flex: none; }
/* edge fades appear only when there's more nav off-screen in that direction */
.navflat.has-more-right { -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 34px), transparent); mask-image: linear-gradient(90deg, #000 calc(100% - 34px), transparent); }
.navflat.has-more-left { -webkit-mask-image: linear-gradient(90deg, transparent, #000 34px); mask-image: linear-gradient(90deg, transparent, #000 34px); }
.navflat.has-more-left.has-more-right { -webkit-mask-image: linear-gradient(90deg, transparent, #000 34px, #000 calc(100% - 34px), transparent); mask-image: linear-gradient(90deg, transparent, #000 34px, #000 calc(100% - 34px), transparent); }
.navflat-admin { flex: none; display: flex; align-items: center; margin-left: 4px; }
.navflat-admin::before { content: ""; height: 22px; width: 1px; background: var(--line); margin-right: 6px; }
.navgroup-menu-right { left: auto; right: 0; }
@media (max-width: 800px) { .navflat, .navflat-admin { display: none; } }

/* floating help launcher */
.assistant-fab { position: fixed; right: 22px; bottom: 22px; z-index: 58; display: flex; flex-direction: column; align-items: flex-end; gap: 10px; }
.assistant-fab-btn { width: 26px; height: 26px; padding: 0; border-radius: 50%; border: 1px solid var(--line); background: var(--surface); color: var(--ink-2); box-shadow: var(--shadow-md); cursor: pointer; display: grid; place-items: center; transition: transform .16s, background .16s, color .16s; }
.assistant-fab-btn:hover { background: var(--surface-2); color: var(--ink); transform: translateY(-2px); }
.assistant-menu { display: flex; flex-direction: column; gap: 7px; align-items: flex-end; }
.assistant-menu button { display: flex; align-items: center; gap: 9px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-pill); padding: 9px 16px 9px 13px; font-size: 13.5px; font-weight: 600; color: var(--ink); box-shadow: var(--shadow-md); cursor: pointer; font-family: var(--font-body); white-space: nowrap; }
.assistant-menu button:hover { background: var(--surface-2); }

/* assistants launcher relocated into the topbar (small icon) — dropdown opens below it */
.asst-topbar { position: relative; display: inline-flex; }
.asst-topbar-menu { position: absolute; top: calc(100% + 8px); right: 0; z-index: 70; display: flex; flex-direction: column; gap: 4px; min-width: 184px; padding: 6px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--shadow-lg); }
.asst-topbar-menu button { display: flex; align-items: center; gap: 9px; text-align: left; border: none; background: none; color: var(--ink-2); font-size: 13.5px; font-weight: 600; padding: 9px 12px; border-radius: var(--r-md); white-space: nowrap; cursor: pointer; font-family: var(--font-body); }
.asst-topbar-menu button:hover { background: var(--surface-2); color: var(--ink); }

.topbar .spacer { flex: 1; }
.userchip { display: flex; align-items: center; gap: 10px; padding: 5px 6px 5px 12px; border-radius: var(--r-pill); border: 1px solid var(--line); background: var(--surface); }
.userchip .meta { text-align: right; line-height: 1.2; }
.userchip .meta b { display: block; font-size: 13px; font-weight: 600; white-space: nowrap; }
.userchip .meta span { display: block; font-size: 11px; color: var(--ink-3); white-space: nowrap; }

.avatar { border-radius: 50%; background: linear-gradient(150deg, var(--teal), var(--accent)); color: var(--on-accent); display: grid; place-items: center; font-weight: 600; font-family: var(--font-display); flex: none; }

.main { flex: 1; width: 100%; max-width: var(--maxw); margin: 0 auto; padding: clamp(20px, 4vw, 40px); }

/* ===== Buttons ===== */
.btn { display: inline-flex; align-items: center; gap: 9px; border: 1px solid transparent; border-radius: var(--r-pill); font-size: 14px; font-weight: 600; padding: 11px 20px; transition: all .16s; white-space: nowrap; }
.btn svg { width: 17px; height: 17px; }
.btn-primary { background: var(--accent); color: var(--on-accent); box-shadow: var(--shadow-sm); border-color: var(--accent-edge); }
.btn-primary:hover { background: var(--accent-strong); transform: translateY(-1px); box-shadow: var(--shadow-md); }
.btn-ghost { background: var(--surface); border-color: var(--line); color: var(--ink); }
.btn-ghost:hover { background: var(--surface-2); border-color: var(--ink-3); }
.btn-quiet { background: none; color: var(--ink-2); padding: 11px 14px; }
.btn-quiet:hover { background: var(--surface-2); color: var(--ink); }
.btn:disabled { opacity: 0.45; pointer-events: none; }
.btn-lg { padding: 14px 26px; font-size: 15px; }

/* ===== Cards & misc ===== */
.card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--shadow-sm); }
.badge { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; padding: 4px 10px; border-radius: var(--r-pill); white-space: nowrap; }
.badge svg { width: 13px; height: 13px; }
.badge-ok { background: var(--ok-soft); color: oklch(0.42 0.12 155); }
.badge-prog { background: var(--accent-soft); color: var(--accent-strong); }
.badge-todo { background: var(--surface-2); color: var(--ink-3); }
.badge-lock { background: var(--surface-2); color: var(--ink-3); }
.badge-warn { background: var(--warn-soft); color: oklch(0.5 0.12 70); }

.eyebrow { font-family: var(--font-mono); font-size: 12px; font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase; color: var(--accent-strong); }

/* progress ring handled inline */

.fade-in { animation: fadeIn .45s cubic-bezier(.2,.7,.3,1) both; }
@keyframes fadeIn { from { transform: translateY(10px); } to { transform: none; } }
@media (prefers-reduced-motion: reduce) { .fade-in { animation: none; } }
.spin { animation: spin .7s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

@keyframes celebFall { 0% { transform: translateY(0) rotate(0); opacity: 1; } 100% { transform: translateY(108vh) rotate(540deg); opacity: 0.9; } }
@keyframes celebBounce { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-12px); } }
@keyframes celebPop { from { transform: scale(.85); opacity: 0; } to { transform: scale(1); opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .celeb-static [style*="celebFall"], .celeb-static [style*="celebBounce"] { animation: none !important; } }

.sched-cell:hover .shift-x { opacity: 1 !important; }
.shiftchip:hover .shift-x { opacity: 1 !important; }
.shift-x:hover { color: oklch(0.55 0.15 25) !important; }
[draggable="true"]:active { cursor: grabbing; }
.copy-item:hover { background: var(--surface-2) !important; }
.wt-bar { height: 10px; animation: wtbar .9s ease-in-out infinite; }
@keyframes wtbar { 0%,100% { height: 3px; } 50% { height: 10px; } }
.wt-avatar { animation: wtpulse 2s ease-in-out infinite; }
@keyframes wtpulse { 0%,100% { box-shadow: 0 0 0 0 oklch(1 0 0 / 0.3); } 50% { box-shadow: 0 0 0 6px oklch(1 0 0 / 0); } }

.hr-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent-strong); display: inline-block; animation: hrDot 1s ease-in-out infinite; }
@keyframes hrDot { 0%,100% { opacity: .3; transform: translateY(0); } 50% { opacity: 1; transform: translateY(-3px); } }
@media (prefers-reduced-motion: reduce) { .hr-dot { animation: none; } }

.riley-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent-strong); display: inline-block; animation: hrDot 1s ease-in-out infinite; }
.riley-dot:nth-child(2) { animation-delay: .15s; }
.riley-dot:nth-child(3) { animation-delay: .3s; }
@media (prefers-reduced-motion: reduce) { .riley-dot { animation: none; } }

@media (min-width: 801px) and (max-width: 1760px) {
  .navgroup > button { padding: 8px 11px; font-size: 13.5px; }
}
@media (max-width: 760px) {
  .userchip .meta { display: none; }
  .brand small { display: none; }
}

/* directory selects */
.dir-select { padding: 6px 12px; border-radius: var(--r-pill); border: 1px solid var(--line); background: var(--surface); color: var(--ink-2); font-size: 12.5px; font-weight: 600; font-family: var(--font-body); cursor: pointer; outline: none; }

/* mobile nav — accordion mirroring the desktop's 5 grouped categories: tap a category to
   reveal its items, others collapse. The active category auto-opens when the menu opens. */
.mobile-nav { display: none; flex-direction: column; gap: 1px; padding: 8px clamp(16px,4vw,40px) 14px; background: var(--surface); border-bottom: 1px solid var(--line); position: sticky; top: 64px; z-index: 25; max-height: calc(100vh - 64px); overflow-y: auto; }
.mobile-nav .mnav-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; width: 100%; text-align: left; border: none; background: none; color: var(--ink); font-size: 16px; font-weight: 600; padding: 13px 12px; border-radius: var(--r-md); font-family: var(--font-body); cursor: pointer; }
.mobile-nav .mnav-top span { white-space: nowrap; }
.mobile-nav .mnav-top:hover { background: var(--surface-2); }
.mobile-nav .mnav-top.active { color: var(--accent-strong); }
.mnav-chev { width: 17px; height: 17px; color: var(--ink-3); flex: none; transition: transform .2s ease; }
.mnav-children { display: flex; flex-direction: column; gap: 1px; margin: 1px 0 6px 11px; padding-left: 11px; border-left: 2px solid var(--line); }
.mnav-children button { text-align: left; border: none; background: none; color: var(--ink-2); font-size: 15px; font-weight: 500; padding: 11px 12px; border-radius: var(--r-md); font-family: var(--font-body); cursor: pointer; width: 100%; }
.mnav-children button:hover { background: var(--surface-2); }
.mnav-children button.active { background: var(--accent-soft); color: var(--accent-strong); }
@media (max-width: 800px) {
  .desktop-nav { display: none; }
  .mobile-menu-btn { display: inline-flex !important; }
  .mobile-nav { display: flex; }
  .dir-dept, .dir-loc { display: none; }
}

/* scrollbar */
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-thumb { background: var(--line); border-radius: 99px; border: 3px solid var(--bg); }
*::-webkit-scrollbar-thumb:hover { background: var(--ink-3); }
