/* ─── Webfont · Inter (self-hosted variable) ────────────────────────────── */
/* Without this, Inter only renders on machines that already have it
   installed system-wide (Ubuntu users typically do; Windows falls
   through to Segoe UI and the app looks notably different there).
   Self-hosted to avoid any third-party request — fits the GDPR posture
   of the Serbian clinic target. One ~340 KB woff2 covers weights
   100–900 via the wght axis. */
@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url('fonts/InterVariable.woff2') format('woff2-variations'),
         url('fonts/InterVariable.woff2') format('woff2');
}

/* ─── Design tokens (Direction 4 — Sharp & Editorial) ───────────────────── */
/* The application now runs on a single accent driving every "primary" surface
   — buttons, active nav, focused fields, selected day, ThemeService emits
   --accent into :root via inline style on <html>. Everything else (sidebar, surfaces,
   text) is fixed by the design system. The --clr-primary alias is preserved
   so older selectors that still reference it pick up the accent until they
   are touched in subsequent PRs. */
:root {
    /* Accent — overridden per-clinic via inline style on <html>. Default = near-black. */
    --accent:        #1A1A1A;
    --accent-hover:  #000000;
    --on-accent:     #FFFFFF;

    /* Back-compat alias so existing selectors using --clr-primary still
       resolve to the active accent without per-file changes. */
    --clr-primary:        var(--accent);
    --clr-primary-hover:  var(--accent-hover);
    --clr-on-primary:     var(--on-accent);

    /* Surfaces — white-led editorial palette */
    --clr-surface:        #FAFAFA;
    --clr-surface-card:   #FFFFFF;
    --clr-border:         #C8C9CE;
    --clr-border-subtle:  #E6E6E8;
    /* Aliases the new shell rules use; thin, single-pixel by default. */
    --hairline:           #E6E6E8;
    --hairline-strong:    #C8C9CE;

    /* Text — near-black with two muted variants */
    --clr-text:           #060709;
    --clr-text-secondary: #404249;
    --clr-text-muted:     #8E909A;

    /* Sidebar — D4 inverts the old dark sidebar to white with a hairline
       right border. Aliases kept so the existing brand-mask CSS still works.
       Active nav items pick up --accent via their own rules below. */
    --clr-sidebar-bg:        #FFFFFF;
    --clr-sidebar-fg:        var(--clr-text-secondary);
    --clr-sidebar-active-fg: var(--clr-text);

    /* Status — colour stays only as small dots / outlines on chips;
       the chips themselves are white. */
    --clr-status-requested:    #F59E0B;
    --clr-status-confirmed:    #3B82F6;
    --clr-status-in-progress:  #8B5CF6;
    --clr-status-completed-ni: #F97316;
    --clr-status-completed:    #10B981;
    --clr-status-cancelled:    #EF4444;
    --clr-status-no-show:      #6B7280;

    /* Layout — square corners across the board. Radii kept as tokens but
       biased to 0 / 2 / 4 so the sharp editorial feel cascades automatically
       through anything still using var(--radius). Avatars override to 50%
       inline. */
    --sidebar-width:           220px;
    --sidebar-width-collapsed: 67px;
    --radius:    0;
    --radius-sm: 0;
    --radius-lg: 2px;

    /* Shadows — D4 is flat. Tokens kept for backwards compatibility but
       resolved to transparent so any leftover usage doesn't introduce a
       drop shadow into the new visual language. */
    --shadow-sm:  none;
    --shadow:     none;
    --shadow-md:  none;

    /* 4-px spacing scale. */
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 24px;
    --space-6: 32px;

    /* Type-size scale. */
    --font-size-xs:  11px;
    --font-size-sm:  12px;
    --font-size-md:  13.5px;
    --font-size-lg:  16px;
    --font-size-xl:  20px;
    --font-size-2xl: 22px;
}

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

html, body {
    height: 100%;
    margin: 0;
    padding: 0;
    font-family: 'Inter', 'Segoe UI', system-ui, -apple-system, sans-serif;
    font-size: 14px;
    line-height: 1.5;
    color: var(--clr-text);
    background: var(--clr-surface);
    -webkit-font-smoothing: antialiased;
    /* No accidental page-level horizontal scrolling. `clip` (rather
       than the older `hidden`) is important: `overflow: hidden` on
       the root creates a scroll-containment context that breaks
       position: sticky inside descendants on Safari. `clip` does the
       same visual clipping without that side effect. */
    overflow-x: clip;
}

a {
    color: var(--clr-primary);
    text-decoration: none;
}

a:hover {
    text-decoration: underline;
}

/* ─── App shell ──────────────────────────────────────────────────────────── */
/* 100dvh matches the *visible* viewport on mobile Safari/Chrome — the
   collapsing address bar otherwise leaves the last rows hidden behind it.
   The 100vh line above is the fallback for browsers that don't support
   dvh yet (very rare on the FirmBite target list as of 2026). */
.app-shell {
    display: flex;
    height: 100vh;
    height: 100dvh;
    overflow: hidden;
}

.sidebar {
    width: var(--sidebar-width);
    min-width: var(--sidebar-width);
    background: var(--clr-sidebar-bg);
    border-right: 1px solid var(--hairline);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.app-body {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.main-content {
    flex: 1;
    /* Explicit overflow-x is the load-bearing line here: per the CSS
       Overflow spec, if overflow-y is non-`visible` and overflow-x is
       left at `visible`, overflow-x is *computed* to `auto`. That
       silently turned every page into a horizontal scroller whenever
       any child (the odontogram's tooth row, the calendar grid before
       it owned its own scroller, etc.) was wider than .main-content's
       visible area. `clip` rather than `hidden` keeps position: sticky
       working inside descendants on Safari, same trade-off as the
       html/body rule above.
       Local horizontal scrollers (.calendar-grid-scroll,
       .odontogram-chart) still work — they're scroll containers in
       their own right, this only stops .main-content itself from
       scrolling sideways. */
    overflow-x: clip;
    overflow-y: auto;
    padding: 24px;
    padding-top: 10px;
}

/* ─── App loading ────────────────────────────────────────────────────────── */
.app-loading {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100vh;
    height: 100dvh;
    background: var(--clr-surface);
}

.app-loading-spinner {
    width: 36px;
    height: 36px;
    border: 3px solid var(--clr-border);
    border-top-color: var(--clr-primary);
    border-radius: 50%;
    animation: spin 0.7s linear infinite;
}

@keyframes spin {
    to { transform: rotate(360deg); }
}

/* ─── Sidebar brand ──────────────────────────────────────────────────────── */
/* Left padding is set so the brand icon (≈31.5px wide at 24px tall) is
   centred above the 16px nav-link glyphs below, whose centre sits at
   x≈26px from the sidebar edge (8px nav-group + 10px link + 8px). The
   wordmark moves with it because both share this container. */
.sidebar-brand {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 22px 22px 18px 21px;
    border-bottom: 1px solid var(--hairline);
    cursor: pointer;
    user-select: none;
    outline: none;
}

.sidebar-brand:hover { background: var(--clr-surface); }

.sidebar-brand:focus-visible {
    box-shadow: inset 0 0 0 2px var(--accent);
}

/* Brand marks switched from CSS-masked silhouettes to plain <img> tags
   pointing at the new identity PNGs (brand/logo.png, brand/logotext.png).
   D4's sidebar is fixed white with near-black brand assets, so the masked
   recolour-with-theme trick is no longer earning its keep. The natural
   aspect ratios live in the PNGs themselves — only height is forced. */
.sidebar-brand-icon {
    height: 26px;
    width: auto;
    flex-shrink: 0;
    display: block;
}

.sidebar-brand-name {
    height: 18px;
    width: auto;
    flex: 0 1 auto;
    min-width: 0;
    display: block;
}

.sidebar-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    padding: 0;
    border: none;
    background: transparent;
    color: var(--clr-text-muted);
    border-radius: 0;
    cursor: pointer;
    flex-shrink: 0;
    transition: background 0.15s, color 0.15s;
}

.sidebar-toggle:hover {
    background: var(--clr-surface);
    color: var(--clr-text);
}

.sidebar-toggle-icon {
    width: 14px;
    height: 14px;
    transition: transform 0.15s;
}

/* ─── Sidebar navigation ─────────────────────────────────────────────────── */
.sidebar-nav {
    flex: 1;
    overflow-x: hidden;
    overflow-y: auto;
    padding: 12px 0 24px;
    scrollbar-width: thin;
    scrollbar-color: var(--clr-border) transparent;
}

.nav-group {
    padding: 0;
    margin-bottom: 4px;
}

/* D4 group label: small uppercase, generous letter-spacing, hairline above
   after the first group so the eye reads them as section breaks. */
.nav-group-label {
    padding: 22px 24px 6px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--clr-text-muted);
}

/* D4 nav link: text-led, no row background. Active = bold + a 3-px accent
   bar on the very left edge. The icon stays (per the chosen option) but
   thinned to 1.5 stroke and muted via opacity until the link is active. */
.sidebar-link {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 24px;
    border-radius: 0;
    font-size: 13px;
    font-weight: 500;
    color: var(--clr-text-secondary);
    cursor: pointer;
    text-decoration: none;
    white-space: nowrap;
    position: relative;
    transition: color 0.12s;
}

.sidebar-link svg {
    width: 15px;
    height: 15px;
    flex-shrink: 0;
    stroke-width: 1.6;
    opacity: 0.6;
}

.sidebar-link:hover {
    color: var(--clr-text);
    text-decoration: none;
}

.sidebar-link:hover svg { opacity: 0.85; }

.sidebar-link.active {
    color: var(--clr-text);
    font-weight: 700;
}

.sidebar-link.active::before {
    content: '';
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 3px;
    height: 16px;
    background: var(--accent);
}

.sidebar-link.active svg { opacity: 1; }

/* ─── Sidebar footer — D4 hairline + muted type ─────────────────────────── */
.sidebar-footer {
    border-top: 1px solid var(--hairline);
    padding: 16px 24px;
}

.sidebar-footer-clinic {
    font-size: 12px;
    font-weight: 700;
    color: var(--clr-text-secondary);
    line-height: 1.3;
    word-wrap: break-word;
    overflow-wrap: break-word;
}

.sidebar-footer-version {
    font-size: 11px;
    color: var(--clr-text-muted);
    font-weight: 500;
    margin-top: 4px;
    letter-spacing: 0.02em;
}

/* ─── Top bar ────────────────────────────────────────────────────────────── */
.topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 22px;
    height: 64px;
    padding: 0 32px;
    background: var(--clr-surface-card);
    border-bottom: 1px solid var(--hairline);
    flex-shrink: 0;
}

.topbar-left {
    display: flex;
    align-items: center;
    gap: 16px;
    flex: 1;
    min-width: 0;
}

/* D4 clinic pill: text-only label with leading status dot — no card, no
   border. Reads as part of the topbar's typographic chrome, not a chip. */
.clinic-pill {
    background: transparent;
    color: var(--clr-text);
    padding: 0 0 0 14px;
    border-radius: 0;
    font-size: var(--font-size-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    white-space: nowrap;
    border: 0;
    position: relative;
}

.clinic-pill::before {
    content: '';
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--clr-status-completed);
}

/* D4 search: underline-style. Hairline bottom border instead of a boxed
   input — reads as editorial type, not a UI control. */
.topbar-search {
    flex: 1;
    max-width: 380px;
    height: auto;
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--hairline);
    border-radius: 0;
    display: flex;
    align-items: center;
    padding: 6px 0;
    gap: 8px;
    transition: border-color 0.15s;
}

.topbar-search:focus-within {
    border-bottom-color: var(--accent);
}

.topbar-search svg {
    width: 15px;
    height: 15px;
    color: var(--clr-text-muted);
    flex-shrink: 0;
    stroke-width: 1.6;
}

.topbar-search input {
    flex: 1;
    border: none;
    outline: none;
    background: transparent;
    font-size: 13px;
    color: var(--clr-text);
    min-width: 0;
}

.topbar-search input::placeholder {
    color: var(--clr-text-muted);
}

.topbar-kbd {
    font-size: 10.5px;
    color: var(--clr-text-muted);
    padding: 1px 6px;
    border: 1px solid var(--hairline);
    border-radius: 0;
    background: var(--clr-surface-card);
    font-family: 'SFMono-Regular', Consolas, monospace;
    white-space: nowrap;
}

.topbar-right {
    display: flex;
    align-items: center;
    gap: 8px;
}

.topbar-icon-btn {
    width: 32px;
    height: 32px;
    border-radius: 0;
    border: none;
    background: transparent;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--clr-text-secondary);
    transition: color 0.15s;
}

.topbar-icon-btn svg {
    width: 17px;
    height: 17px;
    stroke-width: 1.6;
}

.topbar-icon-btn:hover { color: var(--clr-text); }

.topbar-user {
    position: relative;
    /* Sit above the open-menu backdrop so a second click on the widget
       reaches its own @onclick (toggle-closed) rather than being swallowed
       by the backdrop. Backdrop is at z-index 40. */
    z-index: 45;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 4px 4px 4px 8px;
    border-radius: 0;
    cursor: pointer;
    transition: opacity 0.15s;
    border: 0;
}

.topbar-user:hover,
.topbar-user.open { opacity: 0.78; }

.topbar-user-avatar {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--clr-primary);
    color: var(--clr-on-primary);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    font-weight: 600;
    flex-shrink: 0;
}

.topbar-user-info {
    display: flex;
    flex-direction: column;
    line-height: 1.2;
}

.topbar-user-name {
    font-size: 13px;
    font-weight: 600;
    color: var(--clr-text);
}

.topbar-user-role {
    font-size: 10px;
    color: var(--clr-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
}

.topbar-user-caret {
    width: 14px;
    height: 14px;
    color: var(--clr-text-muted);
}

.topbar-user-menu {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    min-width: 200px;
    background: var(--clr-surface-card);
    border: 1px solid var(--hairline-strong);
    border-radius: 0;
    box-shadow: 0 8px 24px rgba(0,0,0,0.06);
    overflow: hidden;
    z-index: 50;
    cursor: default;
}

/* Transparent click-catcher behind the user menu — clicking anywhere
   outside the menu closes it. Sits under the menu in z-order but above
   the rest of the page. */
.topbar-user-menu-backdrop {
    position: fixed;
    inset: 0;
    background: transparent;
    z-index: 40;
}

.topbar-user-menu-item {
    display: block;
    width: 100%;
    text-align: left;
    padding: 10px 14px;
    font-size: 13px;
    color: var(--clr-text);
    background: transparent;
    border: none;
    cursor: pointer;
    text-decoration: none;
    transition: background 0.15s;
}

.topbar-user-menu-item:hover {
    background: var(--clr-surface);
    text-decoration: none;
}

.topbar-user-menu-item-danger {
    color: var(--clr-status-cancelled);
}

.topbar-user-menu-sep {
    height: 1px;
    background: var(--clr-border);
    margin: 0;
}

/* ─── Page header ────────────────────────────────────────────────────────── */
/* Three-area page header.
   - Title (left, always visible)
   - Toolbar (secondary controls — view toggles, date pickers, etc.)
   - Primary actions (right) — at least one button always shares the
     title row, even on the narrowest phones; additional buttons in
     .page-actions wrap into a multi-row stack within the primary
     cell rather than dropping the whole group below the title.
   Cascade as the viewport narrows:
     ≥901px: one row → [title][toolbar][primary]
     ≤900px: two rows → [title …………… primary] / [toolbar]
   When a page omits the toolbar, the empty area collapses cleanly. */
.page-header {
    display: grid;
    grid-template-areas: "title toolbar primary";
    grid-template-columns: auto 1fr auto;
    align-items: center;
    column-gap: var(--space-5);
    row-gap: var(--space-3);
    /* D4 page-header uses a hairline rule below it instead of a margin —
       gives every page a magazine-spread "section break" at the top. */
    padding-block: var(--space-3);
    margin-bottom: var(--space-3);
    border-bottom: 1px solid var(--hairline);
}

/* Anything inside .page-header lands in the primary area by default,
   then specific selectors below override title and toolbar. This makes
   pages that put a bare <a class="btn"> directly under .page-header
   (no .page-actions wrapper) still work correctly — without the
   fallback, grid auto-flow drops the bare button into the toolbar
   cell, where it stretches to fill 1fr. */
.page-header > * {
    grid-area: primary;
    justify-self: end;
}

.page-header > .page-title,
.page-header > .page-header-main {
    grid-area: title;
    justify-self: start;
}

.page-header > .page-toolbar {
    grid-area: toolbar;
    justify-self: start;
}

@media (max-width: 900px) {
    .page-header {
        grid-template-areas:
            "title    primary"
            "toolbar  toolbar";
        grid-template-columns: 1fr auto;
    }
    /* Multiple primary buttons on a narrow viewport stack vertically
       inside the primary cell instead of pushing the whole group below
       the title. Justify-end keeps the (now stacked) buttons against
       the right edge so the title still owns the leading 1fr. */
    .page-actions {
        flex-wrap: wrap;
        justify-content: flex-end;
    }
}

.page-header-main {
    display: flex;
    align-items: center;
    gap: 14px;
    min-width: 0;
    min-height: 32px;
}

.page-header-back {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    border-radius: 6px;
    background: var(--clr-surface-card);
    border: 1px solid var(--clr-border);
    color: var(--clr-text-secondary);
    font-size: 12.5px;
    font-weight: 500;
    cursor: pointer;
    text-decoration: none;
    transition: background 0.15s, color 0.15s;
}

.page-header-back:hover {
    background: var(--clr-surface);
    color: var(--clr-text);
    text-decoration: none;
}

.page-header-back svg {
    width: 13px;
    height: 13px;
}

.page-title {
    font-size: 32px;
    font-weight: 800;
    color: var(--clr-text);
    margin: 0;
    line-height: 1.05;
    letter-spacing: -0.025em;
}

/* Optional small all-caps label that sits ABOVE the .page-title — D4 calls
   it an "eyebrow". Pages opt in by adding <div class="page-eyebrow">…</div>
   above their h1. */
.page-eyebrow {
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 0.16em;
    color: var(--clr-text-muted);
    text-transform: uppercase;
    margin-bottom: 6px;
}

.page-subtitle {
    /* Hidden globally — descriptive subtitles under page titles were eating
       vertical space without earning their keep. Kept in markup for now so
       the source still reads cleanly; remove the rule to bring them back. */
    display: none;
    font-size: 13px;
    color: var(--clr-text-secondary);
    margin: 4px 0 0;
}

/* Subtle accent line under the page title — small detail that signals
   "we're our own product, not a clone" without being loud. */
.page-header::after {
    content: none;
}

.page-header-main {
    position: relative;
}

.page-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
}

/* Secondary controls that sit *below* the title row — date pickers,
   view toggles, filters, anything that isn't a primary action. Wraps
   freely so individual groups (e.g. .recepcija-date-controls) cascade
   to a new line on narrow viewports instead of being forced into the
   title row. The contract: title + primary actions always share one
   row; everything else lives down here.

   Each group inside is expected to be its own inline-flex container
   so its items stay grouped, while the .page-toolbar itself is the
   wrapping flex parent that lets groups break across lines. */
.page-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}


.btn-link {
    background: transparent;
    border: none;
    color: var(--clr-text-secondary);
    cursor: pointer;
    font-size: 13px;
    font-weight: 500;
    padding: 6px 10px;
    border-radius: 6px;
    transition: background 0.15s, color 0.15s;
}

.btn-link:hover {
    background: var(--clr-surface);
    color: var(--clr-text);
}

/* ─── Cards (D4) ─────────────────────────────────────────────────────────── */
/* Square corners, hairline border, no shadow, no accent-bar gimmick.
   The card is just a quiet container — readability comes from the type
   hierarchy inside, not the wrapper. */
.card {
    background: var(--clr-surface-card);
    border-radius: 0;
    border: 1px solid var(--hairline);
    box-shadow: none;
    margin-bottom: var(--space-4);
}

.card:last-child { margin-bottom: 0; }
.card:hover { /* No hover state — cards aren't interactive. */ }

.card-header {
    padding: 16px 20px 12px;
    border-bottom: 1px solid var(--hairline);
    display: flex;
    align-items: center;
    justify-content: space-between;
}

/* D4 card title: all-caps with generous letter-spacing — same idiom as the
   nav-group labels and status labels in event chips. */
.card-title {
    font-size: 11.5px;
    font-weight: 700;
    color: var(--clr-text);
    margin: 0;
    text-transform: uppercase;
    letter-spacing: 0.12em;
}

.card-body {
    padding: 16px 18px;
}

.card-subtitle {
    font-size: 11.5px;
    color: var(--clr-text-muted);
    margin-top: 2px;
    font-weight: 400;
}

.card-header-pill {
    background: color-mix(in srgb, var(--accent) 8%, transparent);
    color: var(--clr-primary);
    padding: 4px 10px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
}

.card-header-link {
    font-size: 12px;
    color: var(--clr-primary);
    font-weight: 500;
}

/* ─── Dashboard grid ─────────────────────────────────────────────────────── */
.dashboard-grid {
    display: grid;
    /* Left column flexes to take whatever's left; right column is a fixed
       320px side panel. Stops the kanban + side panel from competing for
       horizontal room at laptop widths. */
    grid-template-columns: minmax(0, 1fr) 320px;
    gap: 16px;
    align-items: start;
}

.dashboard-col {
    display: flex;
    flex-direction: column;
    gap: 16px;
    min-width: 0;
}

.snapshot-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 0;
    gap: 12px;
}

.snapshot-row + .snapshot-row {
    border-top: 1px solid var(--clr-border-subtle);
}

.snapshot-label {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--clr-text-muted);
}

.snapshot-value {
    font-size: 22px;
    font-weight: 700;
    color: var(--clr-text);
    margin-top: 4px;
    line-height: 1;
}

@media (max-width: 1280px) {
    /* Below 1280px, the kanban can't share width with the 320px side panel
       without horizontal scroll — stack the side panel below the kanban. */
    .dashboard-grid { grid-template-columns: 1fr; }
}

/* ─── Invoice / Payment portfolio strip ──────────────────────────────────── */
.invoice-portfolio {
    display: grid;
    grid-template-columns: minmax(220px, 1fr) 2.5fr;
    gap: 24px;
    padding: 20px 24px;
    align-items: center;
}

.invoice-portfolio-label {
    font-size: 11px;
    color: var(--clr-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
}

.invoice-portfolio-name {
    font-size: 18px;
    font-weight: 700;
    color: var(--clr-text);
    margin-top: 4px;
}

.invoice-portfolio-sub {
    font-size: 12px;
    color: var(--clr-text-muted);
    margin-top: 4px;
}

.invoice-portfolio-stats {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 0;
    border-left: 1px solid var(--clr-border-subtle);
}

.invoice-stat {
    padding: 6px 20px;
    border-left: 1px solid var(--clr-border-subtle);
}

.invoice-stat:first-child {
    border-left: none;
}

.invoice-stat-label {
    font-size: 11px;
    color: var(--clr-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-weight: 600;
}

.invoice-stat-value {
    font-size: 22px;
    font-weight: 700;
    color: var(--clr-text);
    margin-top: 4px;
    line-height: 1;
}

.invoice-stat-sub {
    font-size: 11px;
    color: var(--clr-text-muted);
    margin-top: 4px;
}

.text-success { color: var(--clr-status-completed); }
.text-danger  { color: var(--clr-status-cancelled); }

/* ─── Filter row ─────────────────────────────────────────────────────────── */
.filter-row {
    display: flex;
    gap: 12px;
    align-items: flex-end;
    flex-wrap: wrap;
}

.filter-checkbox {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    color: var(--clr-text);
    cursor: pointer;
    padding: 8px 12px;
    border: 1px solid var(--clr-border);
    border-radius: 6px;
    background: var(--clr-surface);
    user-select: none;
    height: 38px;
}

.filter-checkbox input {
    margin: 0;
}

@media (max-width: 900px) {
    .invoice-portfolio { grid-template-columns: 1fr; }
    .invoice-portfolio-stats { grid-template-columns: repeat(2, 1fr); border-left: none; border-top: 1px solid var(--clr-border-subtle); padding-top: 16px; }
    .invoice-stat:nth-child(3) { border-left: none; }
}

/* ─── Hours rows (clinic / provider hours) ───────────────────────────────── */
.hours-row {
    display: grid;
    grid-template-columns: 1.5fr 110px auto 110px auto;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    border: 1px solid var(--clr-border);
    border-radius: 8px;
    background: var(--clr-surface-card);
}

.hours-row-day { min-width: 0; }
.hours-row-name { font-weight: 600; font-size: 14px; color: var(--clr-text); }
.hours-row-sub { font-size: 11.5px; color: var(--clr-text-muted); margin-top: 2px; }
.hours-row-sep { font-size: 12px; color: var(--clr-text-muted); }

/* ─── Toggle switch ──────────────────────────────────────────────────────── */
.toggle {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
    user-select: none;
}

.toggle input { display: none; }

/* D4 toggle: square not pill. Hairline outline track, hairline thumb that
   becomes the accent when checked. Reads as a deliberate editorial control,
   not a candy switch. */
.toggle-slider {
    width: 32px;
    height: 16px;
    border-radius: 0;
    background: var(--clr-surface-card);
    border: 1px solid var(--hairline-strong);
    position: relative;
    transition: border-color 0.15s;
    box-sizing: border-box;
}

.toggle-slider::after {
    content: '';
    width: 12px;
    height: 12px;
    background: var(--clr-text-muted);
    border-radius: 0;
    position: absolute;
    top: 1px;
    left: 1px;
    transition: transform 0.15s, background 0.15s;
}

.toggle input:checked + .toggle-slider {
    border-color: var(--accent);
}

.toggle input:checked + .toggle-slider::after {
    background: var(--accent);
    transform: translateX(16px);
}

.toggle-label {
    font-size: 12.5px;
    color: var(--clr-text-secondary);
    font-weight: 500;
    min-width: 60px;
}

/* Compact variant — for toolbars where the toggle is a secondary
   control next to a primary action (e.g. the calendar header's
   "Boja osoblja"). Smaller switch, muted label, no min-width on the
   label so the row stays tight. */
.toggle.toggle-compact {
    gap: var(--space-2);
}

.toggle.toggle-compact .toggle-slider {
    width: 26px;
    height: 14px;
}

.toggle.toggle-compact .toggle-slider::after {
    width: 10px;
    height: 10px;
}

.toggle.toggle-compact input:checked + .toggle-slider::after {
    transform: translateX(12px);
}

.toggle.toggle-compact .toggle-label {
    font-size: var(--font-size-sm);
    color: var(--clr-text-muted);
    font-weight: 500;
    min-width: 0;
}

/* ─── Provider tabs (provider hours) ─────────────────────────────────────── */
.provider-tabs {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

.provider-tab {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 14px;
    border: 1px solid var(--clr-border);
    border-radius: 8px;
    background: var(--clr-surface-card);
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s;
}

.provider-tab:hover {
    border-color: var(--clr-primary);
}

.provider-tab.selected {
    border-color: var(--clr-primary);
    background: color-mix(in srgb, var(--accent) 5%, transparent);
}

.provider-tab-avatar {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--clr-primary);
    color: var(--clr-on-primary);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    font-weight: 600;
    flex-shrink: 0;
}

.provider-tab-name { font-size: 13px; font-weight: 600; color: var(--clr-text); text-align: left; }
.provider-tab-role { font-size: 11px; color: var(--clr-text-muted); text-align: left; }

/* ─── Cancellation reason row ────────────────────────────────────────────── */
.reason-row {
    display: flex;
    gap: 12px;
    align-items: flex-end;
    padding: 10px;
    border: 1px solid var(--clr-border);
    border-radius: 8px;
    background: var(--clr-surface-card);
}

.reason-row .form-field { flex: 1; min-width: 120px; }

/* ─── Service chip grid (online booking) ─────────────────────────────────── */
.service-chip-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 10px;
}

.service-chip {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 14px;
    border: 1px solid var(--clr-border);
    border-radius: 8px;
    background: var(--clr-surface-card);
    cursor: pointer;
}

.service-chip-name { font-size: 13px; font-weight: 600; color: var(--clr-text); }
.service-chip-sub  { font-size: 11px; color: var(--clr-text-muted); margin-top: 2px; }

/* ─── Subscription / plans ───────────────────────────────────────────────── */
.sub-current {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 24px;
}

.sub-current-label {
    font-size: 11px;
    color: var(--clr-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-weight: 600;
}

.sub-current-value {
    font-size: 15px;
    font-weight: 600;
    color: var(--clr-text);
    margin-top: 4px;
}

.plan-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
}

.plan-tier {
    position: relative;
    border: 1px solid var(--clr-border);
    border-radius: 10px;
    padding: 20px;
    background: var(--clr-surface-card);
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.plan-tier-current {
    border-color: var(--clr-primary);
    background: color-mix(in srgb, var(--accent) 3%, transparent);
}

.plan-tier-name {
    font-size: 14px;
    font-weight: 700;
    color: var(--clr-text);
}

.plan-tier-price {
    font-size: 24px;
    font-weight: 700;
    color: var(--clr-primary);
}

.plan-tier-features {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-size: 12.5px;
    color: var(--clr-text-secondary);
    flex: 1;
}

.plan-tier-features li {
    padding-left: 18px;
    position: relative;
}

.plan-tier-features li::before {
    content: '✓';
    color: var(--clr-status-completed);
    position: absolute;
    left: 0;
    font-weight: 700;
}

.plan-tier-badge {
    position: absolute;
    top: 14px;
    right: 14px;
    background: var(--clr-primary);
    color: var(--clr-on-primary);
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

@media (max-width: 900px) {
    .plan-grid { grid-template-columns: 1fr; }
    .sub-current { grid-template-columns: repeat(2, 1fr); }
    .hours-row { grid-template-columns: 1fr 1fr 1fr; }
}

/* ─── Calendar weekly grid ──────────────────────────────────────────────── */
/* Segmented control. Pill outer, individual segments lose their own
   borders so the row reads as one continuous control. Active segment
   uses a tinted primary background (color-mix 12%) instead of the
   solid btn-primary fill — quieter, more "segmented control" than
   "primary action". */
.btn-toggle-group {
    display: inline-flex;
    gap: 2px;
    padding: 2px;
    border: 1px solid var(--clr-border);
    border-radius: 999px;
    background: var(--clr-surface-card);
}

.btn-toggle-group .btn {
    border-radius: 999px;
    border: none;
    padding: var(--space-1) var(--space-3);
    font-size: var(--font-size-sm);
    font-weight: 600;
    transition: background 0.12s ease, color 0.12s ease;
}

.btn-toggle-group .btn-ghost {
    background: transparent;
    color: var(--clr-text-secondary);
}

.btn-toggle-group .btn-ghost:hover {
    background: var(--clr-surface);
    color: var(--clr-text);
}

/* Selected segment — override the standalone .btn-primary's solid fill. */
.btn-toggle-group .btn-primary,
.btn-toggle-group .btn-primary:hover {
    background: color-mix(in srgb, var(--clr-primary) 12%, var(--clr-surface-card));
    color: var(--clr-primary);
    border-color: transparent;
}

/* Two-column row: fixed time-axis on the left, horizontally scrolling grid
   on the right. The time axis lives OUTSIDE .calendar-grid-scroll so it
   stays anchored when the user scrolls the week / per-staff grid
   horizontally — no CSS sticky, no JS scroll listener. Shared sizing vars
   live on this container so the axis and the grid can't drift apart. */
.calendar-layout {
    --hour-label-w: 56px;
    --header-h: 56px;
    --slot-h: 28px;
    --col-min-w: 120px;
    /* CSS Grid (not flex) so the second track can shrink to 0 cleanly while
       the inner .calendar-grid renders at its full intrinsic width and the
       wrapper's overflow-x scrolls. Flex's auto-basis + min-width:0 combo
       was collapsing the inner grid columns to a single visible track. */
    display: grid;
    grid-template-columns: var(--hour-label-w) minmax(0, 1fr);
    background: var(--clr-surface-card);
}

.calendar-time-axis {
    background: var(--clr-surface-card);
    border-right: 1px solid var(--clr-border);
}

.calendar-time-axis .calendar-corner {
    height: var(--header-h);
    background: var(--clr-surface);
    border-bottom: 1px solid var(--clr-border);
}

/* Horizontal scroll wrapper for the week / per-staff grid. Same idea as
   .daily-timeline-scroll: the grid itself stays content-sized via
   minmax(120px, 1fr) per column, and this wrapper provides the scroll
   when the total grid width exceeds the card's width. */
.calendar-grid-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.calendar-grid {
    --col-count: 7;

    display: grid;
    grid-template-columns: repeat(var(--col-count), minmax(var(--col-min-w), 1fr));
    /* Pin the first row to --header-h. Without this, grid-auto-rows applies
       to row 1 too — the col-headers overflow their row, shifting every
       hour row up by (header - slot)px and breaking the chip/cell
       alignment that the PositionFor() math assumes. */
    grid-template-rows: var(--header-h);
    grid-auto-rows: var(--slot-h);
    position: relative;
    font-size: 12px;
    background: var(--clr-surface-card);
}

.calendar-col-header {
    grid-row: 1;
    height: var(--header-h);
    background: var(--clr-surface);
    border-bottom: 1px solid var(--clr-border);
    border-right: 1px solid var(--clr-border-subtle);
    position: sticky;
    top: 0;
    /* Sticky header row sits above hovered / drag-selected events (z 5–6)
       so the chrome never gets obscured by content. */
    z-index: 11;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 4px 6px;
}

.calendar-col-header-main {
    font-weight: 600;
    color: var(--clr-text);
    line-height: 1.1;
}

.calendar-col-header-sub {
    font-size: 11px;
    color: var(--clr-text-muted);
    margin-top: 2px;
}

.calendar-hour-label {
    height: var(--slot-h);
    padding: 1px 6px 0 0;
    text-align: right;
    color: var(--clr-text-muted);
    font-family: 'SFMono-Regular', Consolas, monospace;
    font-size: 11px;
    /* Top-aligned so the label sits AT the row's top boundary — matches the
       hour grid line in the scrolling grid and how Outlook/Google Calendar
       render the axis. */
    line-height: 1.1;
    box-sizing: border-box;
}

.calendar-cell {
    height: var(--slot-h);
    border-right: 1px solid var(--clr-border-subtle);
    border-bottom: 1px dashed transparent;
}

/* every other slot (the :30 ones) gets a dashed bottom for visual rhythm */
.calendar-cell:nth-child(odd) {
    /* nth-child counts within grid auto-flow rows; this approximation just
       picks every other row for the dashed line */
}

.calendar-grid > .calendar-cell:nth-of-type(2n) {
    border-bottom: 1px dashed var(--clr-border-subtle);
}

.calendar-cell.is-closed {
    background: repeating-linear-gradient(
        45deg,
        var(--clr-surface) 0,
        var(--clr-surface) 6px,
        rgba(0,0,0,0.02) 6px,
        rgba(0,0,0,0.02) 12px);
}

.calendar-events {
    grid-column: 1 / -1;
    grid-row: 1 / -1;
    display: grid;
    grid-template-columns: repeat(var(--col-count), minmax(var(--col-min-w), 1fr));
    position: relative;
    pointer-events: none;
}

.calendar-event,
.calendar-block {
    position: absolute;
    left: 2px;
    right: 2px;
    border-radius: 4px;
    padding: 3px 6px;
    overflow: hidden;
    pointer-events: auto;
    cursor: pointer;
    font-size: 11px;
    line-height: 1.25;
    box-shadow: 0 1px 2px rgba(15, 27, 45, .06);
}

.calendar-event {
    background: var(--clr-status-confirmed);
    color: white;
    border-left: 3px solid rgba(0,0,0,0.18);
}

/* --ev-color exposes the status colour as a custom property so per-direction
   overlays can build tinted backgrounds (color-mix on --ev-color) without
   having to repeat the per-status selector list. The status rules below still
   set background directly for the d4 default. */
.calendar-event.status-requested        { background: var(--clr-status-requested);    --ev-color: var(--clr-status-requested); }
.calendar-event.status-confirmed        { background: var(--clr-status-confirmed);    --ev-color: var(--clr-status-confirmed); }
.calendar-event.status-in-progress      { background: var(--clr-status-in-progress);  --ev-color: var(--clr-status-in-progress); }
.calendar-event.status-completed-ni     { background: var(--clr-status-completed-ni); --ev-color: var(--clr-status-completed-ni); }
.calendar-event.status-completed        { background: var(--clr-status-completed);    --ev-color: var(--clr-status-completed); }
.calendar-event.status-cancelled        { background: var(--clr-status-cancelled);    --ev-color: var(--clr-status-cancelled); }
.calendar-event.status-no-show          { background: var(--clr-status-no-show);      --ev-color: var(--clr-status-no-show); }

.calendar-event-time {
    font-weight: 700;
    font-size: 10.5px;
    opacity: 0.95;
}

.calendar-event-name {
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.calendar-event-sub {
    font-size: 10px;
    opacity: 0.85;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.calendar-block {
    background: repeating-linear-gradient(
        135deg,
        rgba(107, 114, 128, 0.35) 0,
        rgba(107, 114, 128, 0.35) 6px,
        rgba(107, 114, 128, 0.5) 6px,
        rgba(107, 114, 128, 0.5) 12px);
    color: var(--clr-text);
    border-left: 3px solid var(--clr-text-secondary);
}

.calendar-block-reason {
    font-weight: 600;
    font-size: 10.5px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.calendar-legend {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--clr-text-secondary);
}

.calendar-legend > i {
    display: inline-block;
    width: 14px;
    height: 14px;
    border-radius: 3px;
    position: static;
    box-shadow: none;
    padding: 0;
}

.calendar-shade-swatch {
    display: inline-block;
    width: 14px;
    height: 14px;
    border-radius: 3px;
    background: repeating-linear-gradient(
        45deg,
        var(--clr-surface) 0,
        var(--clr-surface) 4px,
        rgba(0,0,0,0.08) 4px,
        rgba(0,0,0,0.08) 8px);
    border: 1px solid var(--clr-border);
}

/* ─── Calendar v2 — screenshot-matched look ─────────────────────────────── */
.calendar-grid.v2 {
    /* Sizing vars (--slot-h, --header-h) live on .calendar-layout so the
       time axis and the grid can't drift apart. Keep --slot-h there in
       sync with Calendar.razor's SlotHeightPx constant. */
    user-select: none;       /* drag-select shouldn't highlight text */
}

.calendar-grid.v2 .calendar-col-header.v2 {
    height: var(--header-h);
    display: flex;
    /* The general .calendar-col-header rule sets flex-direction: column.
       Override it here so avatar + name end up on the same row, with the
       subtitle stacked below the name inside the text wrapper. */
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: 8px;
    padding: 0 8px;
    background: var(--clr-surface-card);
    border-bottom: 1px solid var(--clr-border);
    text-align: left;
    /* Lets the flex item shrink to the column width so the text inside can
       ellipsis instead of pushing past the column boundary. */
    min-width: 0;
    overflow: hidden;
}

/* Text wrapper (name + subtitle) inside the v2 header — flex child that
   shrinks and clips so long names truncate rather than spill into the
   neighbouring column. */
.calendar-grid.v2 .calendar-col-header.v2 > div:last-child {
    flex: 1;
    min-width: 0;
    overflow: hidden;
}

.calendar-grid.v2 .calendar-col-header.v2 .calendar-col-header-main,
.calendar-grid.v2 .calendar-col-header.v2 .calendar-col-header-sub {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.calendar-grid.v2 .calendar-col-header.v2 .calendar-col-header-main {
    font-size: 12.5px;
}

.calendar-grid.v2 .calendar-col-header.v2 .calendar-col-header-sub {
    font-size: 10.5px;
}

.calendar-col-avatar {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--staff-colour, var(--clr-primary));
    color: #fff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 10px;
    font-weight: 700;
    flex-shrink: 0;
}

/* Light cards with status-coloured left bar — overrides the v1 solid look.
   Background is a soft tint of the staff colour blended into the surface
   so each dentist's appointments are visually grouped without overpowering
   the status indicators. Falls back cleanly to the plain surface when no
   staff colour is set.
   The toolbar "Boja osoblja" switch can turn the tint off; the override
   below restores the plain surface when data-calendar-tint="off" is set
   on <html> by firmbiteCalendar.setTint. */
.calendar-event.v2 {
    background: color-mix(in srgb, var(--staff-colour, transparent) 12%, var(--clr-surface-card));
    color: var(--clr-text);
    border: 1px solid var(--clr-border);
    border-left-width: 4px;
    padding: 3px 6px;
    line-height: 1.2;
    box-shadow: 0 1px 3px rgba(15, 27, 45, 0.06);
}

.calendar-event.v2:hover {
    box-shadow: 0 3px 8px rgba(15, 27, 45, 0.12);
    z-index: 5;
}

html[data-calendar-tint="off"] .calendar-event.v2 {
    background: var(--clr-surface-card);
}

.calendar-event.v2.status-requested        { border-left-color: var(--clr-status-requested); }
.calendar-event.v2.status-confirmed        { border-left-color: var(--clr-status-confirmed); }
.calendar-event.v2.status-in-progress      { border-left-color: var(--clr-status-in-progress); }
.calendar-event.v2.status-completed-ni     { border-left-color: var(--clr-status-completed-ni); }
.calendar-event.v2.status-completed        { border-left-color: var(--clr-status-completed); }
.calendar-event.v2.status-cancelled        { border-left-color: var(--clr-status-cancelled); opacity: 0.55; }
.calendar-event.v2.status-no-show          { border-left-color: var(--clr-status-no-show); opacity: 0.65; }

.calendar-event.v2 {
    display: flex;
    flex-direction: column;
    /* Hard overflow guard — nothing inside ever paints beyond the slot's
       inline-style height; the procedures line clamps to fit. */
    overflow: hidden;
}

/* Line 1 — time and patient name share the same row, both ellipsis if
   the slot is narrow. */
.calendar-event.v2 .calendar-event-header {
    display: flex;
    align-items: baseline;
    gap: 6px;
    white-space: nowrap;
    overflow: hidden;
    flex-shrink: 0;
}

.calendar-event.v2 .calendar-event-time {
    font-weight: 600;
    font-size: 10.5px;
    color: var(--clr-text-secondary);
    opacity: 1;
    flex-shrink: 0;
}

.calendar-event.v2 .calendar-event-name {
    font-weight: 700;
    color: var(--clr-text);
    font-size: 11.5px;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
    flex: 1;
}

.calendar-event.v2 .calendar-event-dentist {
    font-weight: 500;
    color: var(--clr-text-secondary);
    font-size: 10.5px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    flex-shrink: 0;
}

/* Dentist avatar — small filled circle pinned to the bottom-right of
   each event chip. Replaces the previous full-name row so the chip's
   text content has more room. The native title attribute carries the
   full name on hover. */
.calendar-event.v2 .calendar-event-avatar {
    position: absolute;
    bottom: 2px;
    right: 3px;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: var(--staff-colour, var(--clr-primary));
    color: #fff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 8.5px;
    font-weight: 700;
    line-height: 1;
    pointer-events: auto;
    box-shadow: 0 1px 2px rgba(15, 27, 45, 0.18);
}

/* Line 2+ — list of procedures, joined with commas. Multi-line with
   line-clamp so the text never paints past the slot's bottom edge; the
   clamp limit is intentionally generous (12 lines) since the parent's
   overflow:hidden plus the line-clamp's box constraint stop earlier
   when the slot is shorter. Word breaking keeps long procedure names
   from forcing horizontal overflow. */
.calendar-event.v2 .calendar-event-procedures {
    flex: 1;
    min-height: 0;
    color: var(--clr-text-muted);
    font-size: 10.5px;
    line-height: 1.25;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 12;
    line-clamp: 12;
    -webkit-box-orient: vertical;
    overflow-wrap: anywhere;
}

/* When the dentist avatar is pinned to the bottom-right, reserve room
   so the last visible line of procedures doesn't paint under it. */
.calendar-event.v2 .calendar-event-procedures.has-avatar {
    padding-right: 22px;
}

/* Drag-select rectangle for click-and-drag create */
.calendar-grid.v2.is-selecting {
    cursor: ns-resize;
}

.calendar-drag-select {
    position: absolute;
    left: 2px;
    right: 2px;
    border-radius: 4px;
    background: color-mix(in srgb, var(--accent) 18%, transparent);
    border: 1.5px dashed var(--clr-primary);
    padding: 4px 8px;
    pointer-events: none;
    z-index: 6;
}

.calendar-drag-select-label {
    font-size: 11px;
    font-weight: 600;
    color: var(--clr-primary);
}

/* ─── Calendar interactivity (drag, modal, popover) ─────────────────────── */
.calendar-cell {
    cursor: pointer;
}

.calendar-cell:hover {
    background: color-mix(in srgb, var(--accent) 4%, transparent);
}

.calendar-grid.is-dragging .calendar-cell {
    cursor: copy;
}

.calendar-grid.is-dragging .calendar-cell:hover {
    background: color-mix(in srgb, var(--accent) 12%, transparent);
    outline: 1px dashed var(--clr-primary);
    outline-offset: -2px;
}

.calendar-event {
    cursor: grab;
}

.calendar-event:active {
    cursor: grabbing;
    opacity: 0.6;
}

.calendar-modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(15, 27, 45, 0.32);
    z-index: 90;
}

.calendar-modal {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 560px;
    max-width: calc(100vw - 24px);
    max-height: calc(100vh - 24px);
    overflow-y: auto;
    background: var(--clr-surface-card);
    border-radius: var(--radius-lg);
    border: 1px solid var(--clr-border);
    box-shadow: var(--shadow-md);
    z-index: 91;
    display: flex;
    flex-direction: column;
}

.calendar-modal-header {
    padding: 16px 20px;
    border-bottom: 1px solid var(--clr-border-subtle);
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
}

.calendar-modal-title {
    font-size: 16px;
    font-weight: 700;
    color: var(--clr-text);
}

.calendar-modal-sub {
    font-size: 12px;
    color: var(--clr-text-muted);
    margin-top: 2px;
    text-transform: capitalize;
}

.calendar-modal-body {
    padding: 16px 20px;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.calendar-modal-footer {
    padding: 12px 20px;
    border-top: 1px solid var(--clr-border-subtle);
    display: flex;
    justify-content: flex-end;
    gap: 8px;
}

.calendar-popover-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(15, 27, 45, 0.18);
    z-index: 90;
}

.calendar-popover {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 420px;
    max-width: calc(100vw - 24px);
    background: var(--clr-surface-card);
    border-radius: var(--radius-lg);
    border: 1px solid var(--clr-border);
    box-shadow: var(--shadow-md);
    z-index: 91;
    padding: 16px 20px;
}

.calendar-popover-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 12px;
}

.calendar-popover-name {
    font-size: 15px;
    font-weight: 700;
    color: var(--clr-text);
}

.calendar-popover-name-link {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: var(--clr-primary);
    text-decoration: none;
    cursor: pointer;
}

.calendar-popover-name-link svg {
    width: 14px;
    height: 14px;
    opacity: 0.7;
}

.calendar-popover-name-link:hover {
    text-decoration: underline;
}

.calendar-popover-name-link:hover svg {
    opacity: 1;
}

.calendar-popover-meta {
    font-size: 12px;
    color: var(--clr-text-secondary);
    margin-top: 2px;
}

.calendar-popover-proc {
    font-size: 12px;
    color: var(--clr-text-muted);
    margin-top: 4px;
    font-style: italic;
}

.calendar-popover-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 12px;
}

.calendar-conflicts {
    border-radius: 6px;
    border: 1px solid var(--clr-status-requested);
    background: rgba(245, 158, 11, 0.08);
    color: var(--clr-text);
    padding: 8px 12px;
    font-size: 12.5px;
}

.calendar-conflicts ul {
    margin: 4px 0 0 0;
    padding-left: 18px;
}

.calendar-conflicts li {
    margin: 2px 0;
}

.calendar-conflicts-ok {
    border-color: var(--clr-status-completed);
    background: rgba(16, 185, 129, 0.08);
    color: var(--clr-status-completed);
    font-weight: 600;
}

/* ─── Calendar monthly view ──────────────────────────────────────────────── */
.month-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    border-top: 1px solid var(--hairline);
}

.month-grid-header {
    padding: 8px 4px;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    text-align: center;
    color: var(--clr-text-muted);
    border-bottom: 1px solid var(--hairline);
    background: var(--clr-surface);
}

.month-day {
    min-height: 100px;
    padding: 4px;
    border-right: 1px solid var(--hairline);
    border-bottom: 1px solid var(--hairline);
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.month-day:nth-child(7n+7) {
    border-right: none;
}

.month-day.is-other-month {
    background: var(--clr-surface);
}

.month-day.is-other-month .month-day-number,
.month-day.is-other-month .month-chip {
    opacity: 0.4;
}

.month-day.is-today {
    background: color-mix(in srgb, var(--accent) 4%, transparent);
}

.month-day.is-today .month-day-number {
    background: var(--accent);
    color: var(--on-accent, #fff);
    border-radius: 999px;
}

.month-day.is-closed {
    background: repeating-linear-gradient(
        135deg,
        transparent,
        transparent 4px,
        color-mix(in srgb, var(--clr-text-muted) 6%, transparent) 4px,
        color-mix(in srgb, var(--clr-text-muted) 6%, transparent) 5px
    );
}

.month-day-number {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    border-radius: 4px;
    flex-shrink: 0;
}

.month-day-number:hover {
    text-decoration: underline;
    background: color-mix(in srgb, var(--accent) 8%, transparent);
}

.month-day-events {
    display: flex;
    flex-direction: column;
    gap: 1px;
    flex: 1;
    min-width: 0;
}

.month-chip {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 1px 4px;
    font-size: 11px;
    line-height: 1.4;
    border-radius: 2px;
    cursor: pointer;
    border-left: 3px solid color-mix(in srgb, var(--staff-colour, var(--accent)) 60%, transparent);
    background: color-mix(in srgb, var(--staff-colour, var(--accent)) 8%, transparent);
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

html[data-calendar-tint="off"] .month-chip {
    border-left-color: var(--clr-border);
    background: var(--clr-surface);
}

.month-chip:hover {
    background: color-mix(in srgb, var(--staff-colour, var(--accent)) 16%, transparent);
}

html[data-calendar-tint="off"] .month-chip:hover {
    background: var(--clr-border-subtle);
}

.month-chip-time {
    font-weight: 600;
    flex-shrink: 0;
}

.month-chip-name {
    overflow: hidden;
    text-overflow: ellipsis;
}

.month-overflow {
    font-size: 10px;
    color: var(--clr-text-muted);
    padding: 1px 4px;
    cursor: pointer;
    font-weight: 600;
}

.month-overflow:hover {
    color: var(--accent);
    text-decoration: underline;
}

.month-block-indicator {
    position: absolute;
    bottom: 4px;
    right: 4px;
    color: var(--clr-text-muted);
    opacity: 0.6;
}

@media (max-width: 768px) {
    .month-day {
        min-height: 60px;
        padding: 2px;
    }

    .month-chip-first {
        display: none;
    }

    .month-day-number {
        font-size: 11px;
        width: 20px;
        height: 20px;
    }
}

/* ─── Reports grid ───────────────────────────────────────────────────────── */
.report-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 14px;
}

.report-tile {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 16px 18px;
    text-decoration: none;
    color: var(--clr-text);
    transition: transform 0.15s, border-color 0.15s, box-shadow 0.15s;
}

.report-tile:hover {
    text-decoration: none;
    border-color: var(--clr-primary);
    transform: translateY(-1px);
    box-shadow: var(--shadow);
}

.report-tile-icon {
    width: 44px;
    height: 44px;
    border-radius: 10px;
    background: color-mix(in srgb, var(--accent) 8%, transparent);
    color: var(--clr-primary);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.report-tile-icon svg {
    width: 20px;
    height: 20px;
}

.report-tile-title {
    font-size: 14px;
    font-weight: 600;
    color: var(--clr-text);
}

.report-tile-sub {
    font-size: 11.5px;
    color: var(--clr-text-muted);
    margin-top: 2px;
}

/* ─── Buttons ────────────────────────────────────────────────────────────── */
/* D4 button family. Square corners, uppercase label with generous
   letter-spacing — reads as a structural part of the page rather than a
   pill. Primary = solid accent; ghost = hairline outline. */
.btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 10px 20px;
    border-radius: 0;
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    border: 1px solid transparent;
    cursor: pointer;
    transition: background 0.15s, color 0.15s, opacity 0.15s;
    text-decoration: none;
    white-space: nowrap;
}

.btn-primary {
    background: var(--accent);
    color: var(--on-accent);
    border-color: var(--accent);
}

.btn-primary:hover {
    background: var(--accent-hover);
    border-color: var(--accent-hover);
}

.btn-ghost {
    background: transparent;
    color: var(--clr-text-secondary);
    border-color: var(--hairline-strong);
}

.btn-ghost:hover {
    background: transparent;
    color: var(--clr-text);
    border-color: var(--clr-text);
}

.btn svg {
    width: 13px;
    height: 13px;
    stroke-width: 1.8;
}

/* ─── Stats strip ────────────────────────────────────────────────────────── */
.stats-strip {
    display: flex;
    gap: 12px;
    margin-bottom: 20px;
    flex-wrap: wrap;
}

.stat-card {
    position: relative;
    background: var(--clr-surface-card);
    border: 1px solid var(--clr-border);
    border-radius: var(--radius);
    padding: 14px 16px 14px 20px;
    min-width: 120px;
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    overflow: hidden;
}

/* Vertical accent bar on the left — FirmBite's tell. Each status uses
   its own colour so the strip becomes a quick-read traffic light. */
.stat-card::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 4px;
    background: var(--clr-primary);
}

.stat-card.stat-confirmed::before  { background: var(--clr-status-confirmed); }
.stat-card.stat-progress::before   { background: var(--clr-status-in-progress); }
.stat-card.stat-done::before       { background: var(--clr-status-completed); }
.stat-card.stat-noshow::before     { background: var(--clr-status-no-show); }
.stat-card.stat-danger::before     { background: var(--clr-status-cancelled); }

.stat-card-body {
    min-width: 0;
}

.stat-label {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--clr-text-muted);
    margin-bottom: 4px;
}

.stat-value {
    font-size: 26px;
    font-weight: 700;
    color: var(--clr-text);
    line-height: 1;
}

.stat-sub {
    font-size: 11px;
    color: var(--clr-text-muted);
    margin-top: 4px;
}

.stat-icon {
    width: 38px;
    height: 38px;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    background: color-mix(in srgb, var(--accent) 8%, transparent);
    color: var(--clr-primary);
}

.stat-icon svg {
    width: 18px;
    height: 18px;
}

.stat-icon.stat-icon-success { background: rgba(16, 185, 129, 0.1); color: var(--clr-status-completed); }
.stat-icon.stat-icon-danger  { background: rgba(239, 68, 68, 0.1);  color: var(--clr-status-cancelled); }
.stat-icon.stat-icon-warning { background: rgba(245, 158, 11, 0.1); color: var(--clr-status-requested); }
.stat-icon.stat-icon-info    { background: rgba(59, 130, 246, 0.1); color: var(--clr-status-confirmed); }

.stat-card.stat-primary .stat-value   { color: var(--clr-primary); }
.stat-card.stat-confirmed .stat-value  { color: var(--clr-status-confirmed); }
.stat-card.stat-progress .stat-value   { color: var(--clr-status-in-progress); }
.stat-card.stat-done .stat-value       { color: var(--clr-status-completed); }
.stat-card.stat-noshow .stat-value     { color: var(--clr-status-no-show); }
.stat-card.stat-danger .stat-value     { color: var(--clr-status-cancelled); }

/* ─── Kanban board ───────────────────────────────────────────────────────── */
.kanban-board {
    display: flex;
    gap: 10px;
    align-items: flex-start;
    /* No horizontal page scroll at common laptop widths — the columns
       shrink down to their min-width and only scroll inside the board
       itself if the viewport is genuinely too narrow. */
    overflow-x: auto;
    padding-bottom: 8px;
}

.kanban-column {
    min-width: 0;
    flex: 1 1 0;
    background: var(--clr-border-subtle);
    border-radius: var(--radius);
    border: 1px solid var(--clr-border);
    overflow: hidden;
}

.kanban-column-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 14px;
    background: var(--clr-surface-card);
    border-bottom: 1px solid var(--clr-border);
}

.kanban-column-title {
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--clr-text-secondary);
}

.kanban-column-count {
    font-size: 11px;
    font-weight: 700;
    background: var(--clr-border);
    color: var(--clr-text-secondary);
    padding: 1px 7px;
    border-radius: 999px;
}

.kanban-cards {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 10px;
    min-height: 80px;
}

/* ─── Appointment card ───────────────────────────────────────────────────── */
.appt-card {
    background: var(--clr-surface-card);
    border-radius: var(--radius-sm);
    border: 1px solid var(--clr-border);
    padding: 10px 12px;
    cursor: pointer;
    transition: box-shadow 0.15s, border-color 0.15s;
}

.appt-card:hover {
    box-shadow: var(--shadow);
    border-color: var(--clr-primary);
}

/* Clickable variant — used today on "Spremno za naplatu" cards which
   navigate to /billing/za-naplatu when clicked. A subtle accent on the
   left edge signals the affordance without making the card look like
   a different type altogether. */
.appt-card-clickable {
    border-left: 3px solid var(--clr-status-completed-ni);
    padding-left: 9px;
}

.appt-time {
    font-size: 11px;
    font-weight: 700;
    color: var(--clr-text-secondary);
    letter-spacing: 0.02em;
    margin-bottom: 4px;
}

.appt-patient {
    font-size: 13.5px;
    font-weight: 600;
    color: var(--clr-text);
    margin-bottom: 4px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.appt-procedures {
    font-size: 11.5px;
    color: var(--clr-text-secondary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ─── Status badges ──────────────────────────────────────────────────────── */
.status-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.02em;
}

.status-badge::before {
    content: '';
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
}

.status-requested    { color: #92400E; background: #FEF3C7; }
.status-confirmed    { color: #1E40AF; background: #DBEAFE; }
.status-in-progress  { color: #5B21B6; background: #EDE9FE; }
.status-completed-ni { color: #9A3412; background: #FFEDD5; }
.status-completed    { color: #065F46; background: #D1FAE5; }
.status-cancelled    { color: #991B1B; background: #FEE2E2; }
.status-no-show      { color: #374151; background: #F3F4F6; }

/* ─── Empty state ────────────────────────────────────────────────────────── */
.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 32px 16px;
    text-align: center;
    color: var(--clr-text-muted);
    font-size: 12px;
}

/* ─── Blazor error UI ────────────────────────────────────────────────────── */
#blazor-error-ui {
    background: #FECACA;
    border: 1px solid #F87171;
    border-radius: var(--radius-sm);
    bottom: 16px;
    right: 16px;
    position: fixed;
    padding: 12px 16px;
    font-size: 13px;
    color: #991B1B;
    display: none;
    z-index: 1000;
}

#blazor-error-ui .reload {
    font-weight: 600;
    color: #991B1B;
    margin-left: 8px;
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    margin-left: 12px;
    opacity: 0.7;
}

/* ─── Form styles (used in Blazor forms) ─────────────────────────────────── */
.valid.modified:not([type=checkbox]) { outline: 1px solid #10B981; }
.invalid { outline: 1px solid #EF4444; }
.validation-message { color: #EF4444; font-size: 12px; margin-top: 4px; }

.blazor-error-boundary {
    padding: 12px 16px;
    background: #FEE2E2;
    color: #991B1B;
    border-radius: var(--radius-sm);
    font-size: 13px;
}

.blazor-error-boundary::after {
    content: "An error occurred in this component.";
}

/* ─── Color scheme picker (Settings > Theme) ─────────────────────────────── */
/* ─── Theme page — accent picker (D4) ─────────────────────────────────── */
/* Replaces the older .scheme-grid / .scheme-option markup. The theme model
   collapsed to a single accent colour; the picker is a row of preset
   swatches + a custom-hex input. The selected swatch reads as a button-
   shaped chip with a 2-px outline (same width as our button borders) so
   the picker visually echoes the rest of the chrome. */
.accent-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: var(--space-3);
}

.accent-option {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-2);
    padding: var(--space-3);
    cursor: pointer;
    background: var(--clr-surface-card);
    border: 1px solid var(--hairline);
    border-radius: 0;
    transition: border-color 0.12s;
    font-family: inherit;
    text-align: left;
}

.accent-option:hover {
    border-color: var(--clr-text-muted);
}

.accent-option.is-active {
    border-color: var(--accent);
    border-width: 2px;
    padding: calc(var(--space-3) - 1px);
}

.accent-swatch {
    display: block;
    height: 36px;
    background: var(--swatch, var(--accent));
    border-radius: 0;
}

.accent-label {
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--clr-text);
}

.accent-custom {
    margin-top: var(--space-4);
}

.accent-custom-label {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--clr-text-muted);
}

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

.accent-custom-color {
    -webkit-appearance: none;
    appearance: none;
    width: 36px;
    height: 36px;
    padding: 0;
    border: 1px solid var(--hairline-strong);
    background: transparent;
    cursor: pointer;
}

.accent-custom-color::-webkit-color-swatch-wrapper { padding: 0; }
.accent-custom-color::-webkit-color-swatch { border: 0; }

.accent-custom-hex {
    flex: 1;
    max-width: 180px;
    font-family: 'SFMono-Regular', Consolas, monospace;
    text-transform: uppercase;
}

/* ─── UI style selector (per-user, on /settings/theme) ──────────────────────
   Direction-style card grid. Each card carries the style key (D4, D2A, …),
   the display name, and a one-line description. Active state mirrors the
   accent picker so the two sections feel like one settings page. */
.ui-style-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: var(--space-3);
}

.ui-style-option {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-2);
    padding: var(--space-3);
    cursor: pointer;
    background: var(--clr-surface-card);
    border: 1px solid var(--hairline);
    border-radius: 0;
    transition: border-color 0.12s;
    font-family: inherit;
    text-align: left;
    min-height: 120px;
}

.ui-style-option:hover {
    border-color: var(--clr-text-muted);
}

.ui-style-option.is-active {
    border-color: var(--accent);
    border-width: 2px;
    padding: calc(var(--space-3) - 1px);
}

.ui-style-key {
    font-family: 'SFMono-Regular', Consolas, monospace;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.08em;
    color: var(--clr-text-muted);
}

.ui-style-name {
    font-size: 13px;
    font-weight: 700;
    color: var(--clr-text);
    line-height: 1.3;
}

.ui-style-desc {
    font-size: 12px;
    font-weight: 400;
    color: var(--clr-text-muted);
    line-height: 1.4;
}

/* ─── Data table ─────────────────────────────────────────────────────────── */
.data-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13.5px;
}

.data-table th {
    padding: 10px 16px;
    text-align: left;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--clr-text-muted);
    border-bottom: 1px solid var(--clr-border);
    background: var(--clr-border-subtle);
    white-space: nowrap;
}

.data-table td {
    padding: 11px 16px;
    border-bottom: 1px solid var(--clr-border-subtle);
    color: var(--clr-text);
    vertical-align: middle;
}

.data-table tbody tr:last-child td {
    border-bottom: none;
}

.data-row-clickable {
    cursor: pointer;
    transition: background 0.1s;
}

.data-row-clickable:hover td {
    background: var(--clr-border-subtle);
}

/* ─── Forms ──────────────────────────────────────────────────────────────── */
.form-grid-2 {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
}

.form-grid-3 {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 16px;
}

.form-span-2 {
    grid-column: span 2;
}

.form-span-3 {
    grid-column: span 3;
}

.form-field {
    display: flex;
    flex-direction: column;
    gap: 5px;
}

.form-label {
    font-size: 12px;
    font-weight: 600;
    color: var(--clr-text-secondary);
}

.required {
    color: var(--clr-status-cancelled);
}

.form-input {
    padding: 8px 12px;
    border: 1px solid var(--clr-border);
    border-radius: var(--radius-sm);
    font-size: 14px;
    color: var(--clr-text);
    background: var(--clr-surface-card);
    outline: none;
    transition: border-color 0.15s, box-shadow 0.15s;
    width: 100%;
}

.form-input:focus {
    border-color: var(--clr-primary);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 12%, transparent);
}

.form-input:disabled {
    background: var(--clr-border-subtle);
    color: var(--clr-text-muted);
    cursor: not-allowed;
}

textarea.form-input {
    resize: vertical;
    min-height: 72px;
}

.form-select {
    padding: 8px 12px;
    border: 1px solid var(--clr-border);
    border-radius: var(--radius-sm);
    font-size: 14px;
    color: var(--clr-text);
    background: var(--clr-surface-card);
    outline: none;
    width: 100%;
    cursor: pointer;
}

.form-select:focus {
    border-color: var(--clr-primary);
}

.form-fieldset {
    border: 1px solid var(--clr-border);
    border-radius: var(--radius-sm);
    padding: 12px 16px;
    margin-top: 12px;
}

.form-help {
    font-size: 12px;
    color: var(--clr-text-muted);
}

/* ─── Staff colour picker ────────────────────────────────────────────────── */
.staff-colour-picker {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}

.staff-colour-swatch {
    width: 26px;
    height: 26px;
    padding: 0;
    border: 2px solid transparent;
    border-radius: 50%;
    cursor: pointer;
    outline: none;
    transition: transform 0.1s, border-color 0.1s;
    box-shadow: inset 0 0 0 1px rgba(0,0,0,.12);
}

.staff-colour-swatch:hover {
    transform: scale(1.08);
}

.staff-colour-swatch.selected {
    border-color: var(--clr-text);
}

.staff-colour-swatch-custom {
    position: relative;
    overflow: hidden;
    background:
        conic-gradient(from 0deg, #ff0000, #ffea00, #00ff66, #00d4ff, #6a00ff, #ff00aa, #ff0000);
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.staff-colour-swatch-custom > span {
    position: absolute;
    inset: 4px;
    border-radius: 50%;
    border: 1px solid rgba(255,255,255,.8);
}

.staff-colour-swatch-custom input[type="color"] {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
    padding: 0;
    border: none;
}

.staff-colour-clear {
    background: transparent;
    border: 1px solid var(--clr-border);
    color: var(--clr-text-secondary);
    padding: 4px 10px;
    border-radius: var(--radius-sm);
    font-size: 12px;
    cursor: pointer;
}

.staff-colour-clear:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

.staff-colour-clear:not(:disabled):hover {
    background: var(--clr-border-subtle);
}

.form-legend {
    font-size: 11px;
    font-weight: 600;
    color: var(--clr-text-secondary);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    padding: 0 4px;
}

.form-checkbox-label {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13.5px;
    cursor: pointer;
}

/* ─── Alerts ─────────────────────────────────────────────────────────────── */
.alert {
    padding: 12px 16px;
    border-radius: var(--radius-sm);
    font-size: 13.5px;
}

.alert-error {
    background: #FEE2E2;
    color: #991B1B;
    border: 1px solid #FECACA;
}

.alert-success {
    /* Derived from the active theme's primary so the success banner reads as
       part of the chosen brand colour, not a generic mint green. color-mix
       computes the soft tint at render time using the existing CSS variable;
       no theme-service plumbing needed. */
    background: color-mix(in srgb, var(--clr-primary) 12%, white);
    color: var(--clr-primary-hover);
    border: 1px solid color-mix(in srgb, var(--clr-primary) 28%, white);
}

/* ─── Info rows (detail pages) ───────────────────────────────────────────── */
.info-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    padding: 7px 0;
    border-bottom: 1px solid var(--clr-border-subtle);
    font-size: 13.5px;
}

.info-row:last-child { border-bottom: none; }

.info-label {
    font-size: 11px;
    font-weight: 600;
    color: var(--clr-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    flex-shrink: 0;
    margin-right: 12px;
}

/* ─── Pagination ─────────────────────────────────────────────────────────── */
.pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 16px;
    padding: 16px;
    border-top: 1px solid var(--clr-border-subtle);
}

.pagination-info {
    font-size: 12px;
    color: var(--clr-text-muted);
}

/* ─── Search bar ─────────────────────────────────────────────────────────── */
.search-bar {
    display: flex;
    align-items: center;
    gap: 8px;
    background: var(--clr-surface);
    border: 1px solid var(--clr-border);
    border-radius: var(--radius-sm);
    padding: 6px 12px;
    flex: 1;
    max-width: 480px;
}

.search-bar svg {
    width: 16px;
    height: 16px;
    color: var(--clr-text-muted);
    flex-shrink: 0;
}

.search-input {
    border: none;
    outline: none;
    background: transparent;
    font-size: 13.5px;
    color: var(--clr-text);
    width: 100%;
}

/* ─── Patient/procedure search dropdown ──────────────────────────────────── */
.dropdown-list {
    position: relative;
    background: var(--clr-surface-card);
    border: 1px solid var(--clr-border);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow);
    margin-top: 4px;
    z-index: 50;
    overflow: hidden;
}

.dropdown-item {
    padding: 10px 14px;
    cursor: pointer;
    font-size: 13.5px;
    border-bottom: 1px solid var(--clr-border-subtle);
    transition: background 0.1s;
}

.dropdown-item:last-child { border-bottom: none; }
.dropdown-item:hover { background: var(--clr-surface); }

.selected-tag {
    display: inline-flex;
    align-items: center;
    background: var(--clr-primary);
    color: var(--clr-on-primary);
    padding: 4px 12px;
    border-radius: 999px;
    font-size: 12.5px;
    font-weight: 600;
    margin-top: 8px;
}

/* ─── Procedure chips (booking form) ─────────────────────────────────────── */
.procedure-chip {
    padding: 6px 12px;
    border-radius: 999px;
    font-size: 12.5px;
    font-weight: 500;
    border: 1px solid var(--clr-border);
    background: var(--clr-surface-card);
    color: var(--clr-text-secondary);
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s, color 0.15s;
}

.procedure-chip:hover {
    border-color: var(--clr-primary);
    color: var(--clr-primary);
}

.procedure-chip-selected {
    background: var(--clr-primary);
    border-color: var(--clr-primary);
    color: var(--clr-on-primary);
}

/* ─── Appointment card actions ───────────────────────────────────────────── */
.appt-actions {
    display: flex;
    gap: 4px;
    margin-top: 8px;
    flex-wrap: wrap;
}

.appt-action-btn {
    font-size: 11px;
    font-weight: 600;
    padding: 3px 8px;
    border-radius: 999px;
    border: 1px solid var(--clr-border);
    background: var(--clr-surface);
    color: var(--clr-text-secondary);
    cursor: pointer;
    transition: background 0.1s, color 0.1s, border-color 0.1s;
    text-decoration: none;
    display: inline-block;
}

.appt-action-btn:hover {
    background: var(--clr-primary);
    border-color: var(--clr-primary);
    color: var(--clr-on-primary);
    text-decoration: none;
}

.appt-action-patient {
    color: var(--clr-text-muted);
}

/* ─── Auth (login / register) shell ──────────────────────────────────────── */
.auth-shell {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--clr-bg);
    padding: 24px;
}

.auth-card {
    width: 100%;
    max-width: 380px;
    background: var(--clr-surface);
    border: 1px solid var(--clr-border);
    border-radius: 12px;
    padding: 28px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.06);
}

.auth-brand {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 24px;
}

.auth-brand-mark {
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.auth-brand-mark img {
    width: 36px;
    height: 36px;
}

.auth-brand-name {
    font-weight: 700;
    font-size: 18px;
    color: var(--clr-text);
}

.auth-brand-tag {
    font-size: 12px;
    color: var(--clr-text-muted);
}

.auth-hint {
    margin-top: 16px;
    font-size: 12px;
    color: var(--clr-text-muted);
    text-align: center;
}

/* ─── Utility ────────────────────────────────────────────────────────────── */
.text-mono  { font-family: 'SFMono-Regular', Consolas, monospace; }
.text-muted { color: var(--clr-text-muted); }

/* ─── Calendar — Daily View ─────────────────────────────────────────────── */
.day-pill-bar {
    display: flex;
    gap: var(--space-2);
    flex-wrap: wrap;
    align-items: center;
}

.day-pill {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-1);
    min-width: 100px;
    padding: var(--space-2) var(--space-4);
    font-size: var(--font-size-md);
    font-weight: 600;
    color: var(--clr-text);
    background: var(--clr-surface-card);
    border: 1px solid var(--clr-border-subtle);
    /* Fully pilled — matches the segmented control's rounding so the whole
       header reads as one family of controls. */
    border-radius: 999px;
    cursor: pointer;
    transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}

.day-pill:hover {
    border-color: var(--clr-border);
    color: var(--clr-primary);
    background: color-mix(in srgb, var(--clr-primary) 4%, var(--clr-surface-card));
}

/* Selected day uses a tinted primary background + primary text + primary
   outline rather than a solid primary fill — quieter contrast, lets the
   surrounding pills stay readable at the same weight. */
.day-pill.is-selected,
.day-pill.is-selected:hover {
    background: color-mix(in srgb, var(--clr-primary) 12%, var(--clr-surface-card));
    color: var(--clr-primary);
    border-color: var(--clr-primary);
}

.day-pill-picker {
    position: relative;
    min-width: 44px;
    padding: var(--space-2) var(--space-3);
    color: var(--clr-text-muted);
}

/* The pill renders both labels in the markup; CSS picks which one is
   visible based on viewport. Desktop sees the full "Pon, 18. maj"
   format; ≤768px gets the compact "P 18" form (first letter of the
   weekday + day number, no month). */
.day-pill-short {
    display: none;
}

.day-pill-picker:hover {
    color: var(--clr-primary);
}

.day-pill-picker input[type="date"] {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
    border: 0;
    padding: 0;
}

/* The timeline grid is content-sized — provider column max-content +
   slot grid. On narrow viewports it exceeds the viewport width, so we
   wrap it in .daily-timeline-scroll which provides the horizontal
   scroll within the card. The grid itself no longer carries the
   overflow rule; putting it on a constrained wrapper is what actually
   creates a scrollbar (a grid with overflow:auto still expands to fit
   its content). */
.daily-timeline-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

/* ─── Staff picker (Po osoblju view multi-select) ────────────────────────── */
.staff-picker {
    position: relative;
    display: inline-block;
}

.staff-picker-toggle svg {
    width: 12px;
    height: 12px;
    margin-left: 4px;
}

.staff-picker-backdrop {
    position: fixed;
    inset: 0;
    z-index: 40;
}

.staff-picker-panel {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    z-index: 50;
    min-width: 220px;
    max-height: 320px;
    overflow-y: auto;
    background: var(--clr-surface-card);
    border: 1px solid var(--clr-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-md);
    padding: 6px;
}

.staff-picker-actions {
    display: flex;
    gap: 6px;
    padding: 2px 6px 6px;
    border-bottom: 1px solid var(--clr-border-subtle);
    margin-bottom: 4px;
}

.staff-picker-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    user-select: none;
}

.staff-picker-row:hover {
    background: var(--clr-border-subtle);
}

.staff-picker-row input[type="checkbox"] {
    margin: 0;
    flex-shrink: 0;
}

.staff-picker-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--staff-colour, var(--clr-primary));
    flex-shrink: 0;
}

.staff-picker-name {
    flex: 1;
    min-width: 0;
    font-size: 13px;
    color: var(--clr-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.daily-timeline {
    --slot-count: 20;
    /* CSS Grid lets the browser size the provider column to the longest
       cell content natively — no JS char-width heuristic, no over-padding
       on the right. `max-content` shrinks to the widest provider name +
       its symmetric 16px padding. */
    display: grid;
    grid-template-columns: max-content 1fr;
    background: var(--clr-surface-card);
}

/* Rows are layout-transparent so their children participate in the
   parent grid directly. The row-level border-bottom + min-height
   migrates to per-cell rules below; row selectors that target child
   cells via `>` still work because the DOM hierarchy is preserved. */
.dt-row {
    display: contents;
}

.dt-row > .dt-provider-cell,
.dt-row > .dt-hours {
    min-height: 72px;
    border-bottom: 1px solid var(--clr-border-subtle);
}

.dt-row:last-child > .dt-provider-cell,
.dt-row:last-child > .dt-hours {
    border-bottom: none;
}

.dt-header-row > .dt-provider-cell,
.dt-header-row > .dt-hours {
    min-height: 36px;
    background: var(--clr-surface);
    border-bottom: 1px solid var(--clr-border);
}

.dt-provider-cell {
    padding: 12px 16px;
    border-right: 1px solid var(--clr-border);
    background: var(--clr-surface-card);
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 2px;
    white-space: nowrap;
    position: relative;
}

/* Staff-colour stripe on the left edge of the provider cell. Driven by
   the --staff-colour CSS variable set per .dt-row in CalendarDailyView;
   transparent when no colour is assigned, or when the user has flipped
   the toolbar "Boja osoblja" switch off. Pseudo-element keeps the
   layout intact — no shifts when the colour is added or removed. */
.dt-provider-cell::before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 4px;
    background: var(--staff-colour, transparent);
    pointer-events: none;
}

.dt-header-row .dt-provider-cell::before {
    background: transparent;
}

html[data-calendar-tint="off"] .dt-provider-cell::before {
    background: transparent;
}

.dt-header-row .dt-provider-cell {
    background: var(--clr-surface);
    padding: 8px 16px;
}

.dt-provider-head {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.04em;
    color: var(--clr-text-muted);
    text-transform: uppercase;
}

.dt-provider-name {
    font-weight: 700;
    font-size: 14px;
    color: var(--clr-text);
}

.dt-provider-role {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.06em;
    color: var(--clr-text-muted);
    text-transform: uppercase;
}

.dt-hours {
    /* flex:1 no longer needed — parent is grid and this cell occupies
       the 1fr column. min-width:0 is still important so the inner
       slot grid can shrink below its intrinsic content width. */
    display: grid;
    grid-template-columns: repeat(var(--slot-count), 1fr);
    position: relative;
    min-width: 0;
}

.dt-hours-head {
    grid-template-columns: repeat(var(--slot-count), 1fr);
}

.dt-hour-head {
    grid-column: span 2;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    font-weight: 700;
    color: var(--clr-text-muted);
    border-left: 1px solid var(--clr-border);
}

.dt-hour-head:first-child {
    border-left: none;
}

.dt-slot-cell {
    height: 100%;
    cursor: pointer;
    transition: background 100ms ease;
    user-select: none;
}

.dt-hours.is-selecting .dt-slot-cell {
    cursor: ew-resize;
}

.dt-slot-cell:hover:not(.is-closed) {
    background: color-mix(in srgb, var(--accent) 5%, transparent);
}

.dt-slot-hour {
    border-left: 1px solid var(--clr-border);
}

.dt-slot-half {
    border-left: 1px dashed var(--clr-border-subtle);
}

.dt-slot-cell:first-child {
    border-left: none;
}

.dt-slot-cell.is-closed {
    background: repeating-linear-gradient(
        135deg,
        rgba(133, 147, 166, 0.06),
        rgba(133, 147, 166, 0.06) 6px,
        rgba(133, 147, 166, 0.12) 6px,
        rgba(133, 147, 166, 0.12) 12px
    );
    cursor: not-allowed;
}

.dt-drag-select {
    position: absolute;
    top: 8px;
    bottom: 8px;
    background: color-mix(in srgb, var(--accent) 18%, transparent);
    border: 1.5px dashed var(--clr-primary);
    border-radius: 4px;
    pointer-events: none;
    z-index: 6;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 6px;
}

.dt-drag-select-label {
    font-size: 11px;
    font-weight: 600;
    color: var(--clr-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dt-drag-select-dur {
    color: var(--clr-text-muted);
    font-weight: 500;
    margin-left: 4px;
}

.dt-event {
    position: absolute;
    top: 8px;
    bottom: 8px;
    padding: 6px 10px;
    /* Soft tint of the row's staff colour, same 12% mix as the
       .calendar-event.v2 chips in the week/staff views. Falls back to
       the plain surface when no --staff-colour is set, and is overridden
       to the plain surface when the toolbar "Boja osoblja" switch is
       off (see rule below). */
    background: color-mix(in srgb, var(--staff-colour, transparent) 12%, var(--clr-surface-card));
    border: 1px solid var(--clr-border);
    border-left-width: 4px;
    border-radius: 6px;
    box-shadow: var(--shadow-sm);
    display: flex;
    flex-direction: column;
    gap: 2px;
    overflow: hidden;
    cursor: grab;
    transition: box-shadow 120ms ease, transform 120ms ease;
}

html[data-calendar-tint="off"] .dt-event {
    background: var(--clr-surface-card);
}

.dt-event:hover {
    box-shadow: var(--shadow);
    transform: translateY(-1px);
}

.dt-event:active {
    cursor: grabbing;
}

/* --ev-color mirrors the week-grid pattern so the per-direction daily-view
   overlays can build status-tinted backgrounds / rails / dots from one var. */
.dt-event.status-requested        { border-left-color: var(--clr-status-requested);    --ev-color: var(--clr-status-requested); }
.dt-event.status-confirmed        { border-left-color: var(--clr-status-confirmed);    --ev-color: var(--clr-status-confirmed); }
.dt-event.status-in-progress      { border-left-color: var(--clr-status-in-progress);  --ev-color: var(--clr-status-in-progress); }
.dt-event.status-completed-ni     { border-left-color: var(--clr-status-completed-ni); --ev-color: var(--clr-status-completed-ni); }
.dt-event.status-completed        { border-left-color: var(--clr-status-completed);    --ev-color: var(--clr-status-completed); }
.dt-event.status-cancelled        { border-left-color: var(--clr-status-cancelled);    --ev-color: var(--clr-status-cancelled); }
.dt-event.status-no-show          { border-left-color: var(--clr-status-no-show);      --ev-color: var(--clr-status-no-show); }

/* Status label is hidden by default; only the editorial (d4) overlay reveals
   it (the airy/rounded directions convey status with the coloured rail). */
.dt-event-status { display: none; }

.dt-event-time {
    font-size: 11px;
    font-weight: 600;
    color: var(--clr-text-muted);
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
}

.dt-event-name {
    font-size: 13px;
    font-weight: 700;
    color: var(--clr-text);
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
}

.daily-empty-card .card-body {
    text-align: center;
    padding: 32px 20px;
}

.daily-empty-title {
    font-weight: 700;
    color: var(--clr-text);
    margin-bottom: 4px;
}

.daily-empty-sub {
    color: var(--clr-text-muted);
    font-size: 13px;
}

/* ─── Patient Workspace ─────────────────────────────────────────────────── */
.patient-workspace-band {
    background: linear-gradient(135deg, var(--clr-primary), var(--clr-primary-hover));
    color: var(--clr-on-primary);
    border-radius: var(--radius-md, 10px);
    box-shadow: var(--shadow);
    margin-bottom: 16px;
    overflow: hidden;
}

.patient-workspace-band-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 20px 24px;
    flex-wrap: wrap;
}

.patient-workspace-identity {
    display: flex;
    align-items: center;
    gap: 16px;
    min-width: 0;
}

.patient-workspace-avatar {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.18);
    color: var(--clr-on-primary);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 20px;
    font-weight: 700;
    flex-shrink: 0;
    border: 2px solid rgba(255, 255, 255, 0.28);
}

.patient-workspace-identity-text {
    min-width: 0;
}

.patient-workspace-name {
    font-size: 22px;
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -0.01em;
}

.patient-workspace-sub {
    margin-top: 4px;
    font-size: 12.5px;
    color: rgba(255, 255, 255, 0.85);
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.patient-workspace-sub-sep {
    opacity: 0.5;
}

.patient-status-chip {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 4px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.06em;
    margin-left: 4px;
}

.patient-status-active {
    background: rgba(16, 185, 129, 0.85);
    color: white;
}

.patient-status-inactive {
    background: rgba(255, 255, 255, 0.18);
    color: rgba(255, 255, 255, 0.7);
}

.patient-workspace-actions {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

.patient-workspace-actions .btn-ghost {
    background: rgba(255, 255, 255, 0.12);
    color: var(--clr-on-primary);
    border-color: rgba(255, 255, 255, 0.2);
}

.patient-workspace-actions .btn-ghost:hover {
    background: rgba(255, 255, 255, 0.22);
    color: var(--clr-on-primary);
}

.patient-workspace-actions .btn-primary {
    background: var(--clr-on-primary);
    color: var(--clr-primary);
    border-color: var(--clr-on-primary);
}

.patient-workspace-actions .btn-primary:hover {
    background: rgba(255, 255, 255, 0.92);
    color: var(--clr-primary-hover);
}

.patient-stats-strip {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    background: rgba(255, 255, 255, 0.08);
    border-top: 1px solid rgba(255, 255, 255, 0.16);
}

.patient-stat {
    padding: 14px 18px;
    border-right: 1px solid rgba(255, 255, 255, 0.12);
}

.patient-stat:last-child {
    border-right: none;
}

.patient-stat-label {
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.7);
    margin-bottom: 6px;
}

.patient-stat-value {
    font-size: 16px;
    font-weight: 700;
    color: var(--clr-on-primary);
    line-height: 1.1;
}

.patient-stat-value-warn {
    color: #fde68a;
}

/* Tab navigation */
.patient-tabs {
    display: flex;
    gap: 4px;
    border-bottom: 1px solid var(--clr-border);
    margin-bottom: 16px;
    overflow-x: auto;
}

.patient-tab {
    padding: 10px 16px;
    font-size: 13px;
    font-weight: 600;
    color: var(--clr-text-secondary);
    text-decoration: none;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    white-space: nowrap;
    transition: color 120ms ease, border-color 120ms ease;
}

.patient-tab:hover {
    color: var(--clr-primary);
    text-decoration: none;
}

.patient-tab.is-active {
    color: var(--clr-primary);
    border-bottom-color: var(--clr-primary);
}

.patient-tab-content {
    min-height: 200px;
    /* Cascadeable containment: any patient tab (odontogram, billing
       table, etc.) that's wider than the column gets clipped here
       rather than pushing the page sideways. min-width: 0 lets the
       block actually shrink below its intrinsic content width inside
       its parent's grid/flex track. */
    min-width: 0;
    overflow-x: clip;
}

/* Overview tab layout */
.patient-overview-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
    align-items: start;
}

.patient-overview-col {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.patient-overview-wide {
    grid-column: span 1;
}

.patient-financial-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 8px 0;
    border-bottom: 1px dashed var(--clr-border-subtle);
}

.patient-financial-row:last-child {
    border-bottom: none;
}

.patient-financial-label {
    font-size: 13px;
    color: var(--clr-text-secondary);
}

.patient-financial-value {
    font-size: 14px;
    font-weight: 600;
    color: var(--clr-text);
}

.patient-financial-warn {
    color: var(--clr-status-cancelled);
}

.patient-card-cta {
    font-size: 12px;
    font-weight: 600;
    color: var(--clr-primary);
    text-decoration: none;
    background: none;
    border: none;
    cursor: pointer;
    padding: 0;
}

.patient-card-cta:hover {
    text-decoration: underline;
}

.patient-empty-tab {
    text-align: center;
    color: var(--clr-text-muted);
    font-size: 13px;
}

.patient-edit-note {
    background: var(--clr-surface);
    border-left: 3px solid var(--clr-text-muted);
    padding: 10px 12px;
    font-size: 12px;
    color: var(--clr-text-secondary);
    border-radius: 4px;
    margin-bottom: 14px;
}

.patient-edit-prefs {
    display: flex;
    gap: 14px;
    padding-top: 8px;
}

.patient-edit-pref {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    color: var(--clr-text);
    cursor: pointer;
}

.patient-edit-pref input[type="checkbox"] {
    cursor: pointer;
}

@media (max-width: 768px) {
    .form-grid-2 { grid-template-columns: 1fr; }
    .form-grid-3 { grid-template-columns: 1fr; }
    .form-span-2 { grid-column: span 1; }
    .kanban-board { flex-direction: column; }
    .kanban-column { min-width: unset; }
    .daily-timeline { min-width: 800px; }
    /* Compact day pills on mobile: first letter of the weekday + day
       number (rendered via .day-pill-short), tighter padding, smaller
       font. .day-pill-picker matches the compact size so the row reads
       as one consistent strip of square-ish buttons. */
    .day-pill {
        min-width: 36px;
        padding: 6px 8px;
        font-size: 12px;
        font-weight: 700;
        gap: 4px;
    }

    .day-pill-full { display: none; }
    .day-pill-short { display: inline; }

    .day-pill-picker {
        min-width: 36px;
        padding: 6px 8px;
    }
    .patient-stats-strip { grid-template-columns: repeat(2, 1fr); }
    .patient-stat { border-right: none; border-bottom: 1px solid rgba(255,255,255,0.12); }
    .patient-overview-grid { grid-template-columns: 1fr; }
    .patient-workspace-band-row { flex-direction: column; align-items: flex-start; }
}

/* ─── Sidebar collapsed mode ─────────────────────────────────────────────── */
/* Triggered by setting data-sidebar="collapsed" on <html>. Set synchronously
   by an inline script in App.razor (read from localStorage) so the collapsed
   layout paints on first render with no expanded→collapsed flash. */
html[data-sidebar="collapsed"] .sidebar {
    width: var(--sidebar-width-collapsed);
    min-width: var(--sidebar-width-collapsed);
}

/* Collapsing the sidebar must not move a single icon. Text-only elements
   (brand wordmark, link labels, group headings) and the toggle button
   keep their layout box via visibility:hidden, so nothing shifts up or
   right when the user toggles. Only the footer drops out of flow since
   it sits below the scroll region and has no aligned icon. */
html[data-sidebar="collapsed"] .sidebar-brand-name,
html[data-sidebar="collapsed"] .sidebar-toggle,
html[data-sidebar="collapsed"] .sidebar-link span,
html[data-sidebar="collapsed"] .nav-group-label {
    visibility: hidden;
}

html[data-sidebar="collapsed"] .sidebar-footer {
    display: none;
}

html[data-sidebar="collapsed"] .sidebar-toggle-icon {
    transform: rotate(180deg);
}

/* ─── Calendar: inactive dentist column ──────────────────────────────────── */
/* Deactivated dentists still appear in the calendar so admins can see and
   reassign any remaining appointments. The column header is greyed and the
   conflict checker refuses new bookings against this dentist. */
.calendar-col-header.is-inactive {
    opacity: 0.5;
    filter: grayscale(1);
}

.calendar-col-header.is-inactive::after {
    content: "neaktivan";
    display: inline-block;
    margin-left: 8px;
    padding: 1px 6px;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--clr-text-muted);
    background: var(--clr-border);
    border-radius: 999px;
}

/* Recepcija date controls + mini calendar popover. No outer margin —
   the .page-header grid (row-gap) owns vertical spacing now; a stray
   margin-top here used to add a few px to the toolbar cell's height
   and nudged the title + primary button down via align-items:center. */
.recepcija-date-controls {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}

.recepcija-date-label {
    font-weight: 600;
    text-transform: capitalize;
    /* Sit above the popover backdrop (z-index 40) so a click on the
       label always reaches the @onclick handler and toggles the popover
       open / closed. Without this the backdrop swallows the click while
       the popover is open, and the rapid open→close→open dance leaves
       the user feeling the button is unreliable. */
    position: relative;
    z-index: 50;
}

.recepcija-date-popover-wrap {
    position: relative;
    display: inline-block;
}

.recepcija-date-popover-backdrop {
    position: fixed;
    inset: 0;
    z-index: 40;
}

.recepcija-date-popover {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    z-index: 50;
    background: var(--clr-surface-card);
    border: 1px solid var(--clr-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-md);
    padding: 12px;
    min-width: 260px;
}

.recepcija-date-popover-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 8px;
}

.recepcija-date-popover-title {
    font-weight: 600;
    text-transform: capitalize;
    color: var(--clr-text);
}

.recepcija-date-popover-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 2px;
}

.recepcija-date-popover-dow {
    font-size: 10.5px;
    font-weight: 600;
    color: var(--clr-text-muted);
    text-align: center;
    padding: 4px 0;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.recepcija-date-popover-day {
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    padding: 6px 0;
    font-size: 12.5px;
    font-weight: 500;
    color: var(--clr-text);
    cursor: pointer;
    text-align: center;
}

.recepcija-date-popover-day:hover {
    background: var(--clr-surface);
}

.recepcija-date-popover-day.is-other-month {
    color: var(--clr-text-muted);
    opacity: 0.5;
}

.recepcija-date-popover-day.is-today {
    border-color: var(--clr-primary);
    color: var(--clr-primary);
}

/* Selected day uses the same 12% primary tint + primary outline pattern
   as the calendar header's segmented control and day pills, so all
   "selected one-of-many" states in the app read consistently. */
.recepcija-date-popover-day.is-selected,
.recepcija-date-popover-day.is-selected:hover {
    background: color-mix(in srgb, var(--clr-primary) 12%, var(--clr-surface-card));
    color: var(--clr-primary);
    border-color: var(--clr-primary);
}

/* ─── Odontogram ────────────────────────────────────────────────────────── */
.odontogram-panel {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 340px;
    gap: 16px;
    align-items: start;
}

.odontogram-chart-wrap {
    background: var(--clr-surface-card);
    border: 1px solid var(--clr-border);
    border-radius: var(--radius);
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.odontogram-chart-header {
    display: flex;
    justify-content: flex-end;
}

.odontogram-chart {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    /* Chart owns the horizontal scroll so a 16-tooth row stays readable on
       a phone without forcing the whole patient page to scroll sideways.
       The html/body rule sets overflow-x: clip page-wide; this scroller
       opts the chart back in to local horizontal scrolling. */
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.odontogram-jaw-label {
    font-size: 10.5px;
    font-weight: 600;
    color: var(--clr-text-muted);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-align: center;
    margin: 4px 0;
}

.odontogram-row {
    display: flex;
    /* `safe center` centers the row when the chart is wider than 16 teeth
       (desktop) but falls back to `start` when content overflows so the
       leftmost teeth (FDI 18, 48) stay reachable inside .odontogram-chart's
       horizontal scroll. Plain `center` pushes overflow into the
       unscrollable area to the left of the container. */
    justify-content: safe center;
    gap: 4px;
    flex-wrap: nowrap;
    min-width: max-content;
}

.odontogram-row-frontal {
    align-items: stretch;
}

.odontogram-row-occlusal {
    align-items: center;
    margin: 2px 0;
}

.odontogram-jaw-divider {
    height: 1px;
    margin: 4px 0;
    background: var(--clr-border);
}

.odontogram-tooth {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 44px;
    flex-shrink: 0;
    cursor: pointer;
    padding: 2px;
    border-radius: var(--radius-sm);
    border: 1px solid transparent;
    transition: background 0.1s, border-color 0.1s;
    position: relative;
}

.odontogram-tooth:hover {
    background: var(--clr-surface);
}

.odontogram-tooth.is-selected {
    background: color-mix(in srgb, var(--clr-primary) 10%, white);
    border-color: var(--clr-primary);
}

.odontogram-tooth.is-mid-left { margin-right: 8px; }
.odontogram-tooth.is-mid-right { margin-left: 8px; }

.odontogram-frontal-img-wrap {
    position: relative;
    height: 68px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.odontogram-frontal-img {
    height: 68px;
    width: auto;
    display: block;
}

.odontogram-frontal-overlay {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
}

.odontogram-occlusal-wrap {
    position: relative;
    width: 40px;
    height: 40px;
    display: block;
}

.odontogram-occlusal-img {
    width: 100%;
    height: 100%;
    display: block;
    object-fit: contain;
}

.odontogram-occlusal-overlay {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
}

/* Surfaces are layered over the traced silhouette so the underlying
   anatomy still reads through when a surface is marked. */
.odontogram-occlusal-overlay .odontogram-surface {
    fill-opacity: 0.5;
}

.odontogram-surface {
    stroke: transparent;
    stroke-width: 2;
    cursor: pointer;
    transition: stroke 0.1s, filter 0.1s;
}

/* Real outline on hover — replaces the previous opacity dimming. */
.odontogram-surface:hover {
    stroke: var(--clr-primary);
    filter: brightness(0.95);
}

/* Persistent outline for the currently selected surface — same visual as
   the hover state but stays painted until another surface is clicked on
   the chart or a different surface tab is picked in the sidebar. */
.odontogram-surface.is-selected {
    stroke: var(--clr-primary);
    filter: brightness(0.95);
}

.odontogram-silhouette {
    fill: none;
    stroke: #333333;
    stroke-width: 1.5;
    stroke-linecap: round;
    stroke-linejoin: round;
    pointer-events: none;
}

.odontogram-inner-detail {
    fill: none;
    stroke: #888888;
    stroke-width: 1;
    stroke-linecap: round;
    stroke-linejoin: round;
    pointer-events: none;
}

.odontogram-tooth-label {
    margin-top: 2px;
    font-size: 10.5px;
    font-family: ui-monospace, monospace;
    color: var(--clr-text-muted);
}

/* Hover popup — single, fixed at the top-right of the chart wrap so it
   never overlaps the tooth the user is interacting with. */
.odontogram-chart-wrap {
    position: relative;
}

.odontogram-popup {
    position: absolute;
    top: 12px;
    right: 12px;
    z-index: 30;
    min-width: 180px;
    max-width: 240px;
    padding: 10px 12px;
    background: var(--clr-text);
    color: #fff;
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-md);
    font-size: 11.5px;
    line-height: 1.4;
    pointer-events: none;
}

.odontogram-popup-header {
    font-weight: 600;
    margin-bottom: 4px;
    color: #fff;
}

.odontogram-popup-empty {
    color: rgba(255,255,255,0.6);
    font-style: italic;
}

.odontogram-popup-row {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 4px;
}

.odontogram-popup-label {
    font-weight: 500;
}

.odontogram-popup-meta {
    color: rgba(255,255,255,0.7);
    font-size: 11px;
}

.odontogram-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    padding: 8px 0 0;
    border-top: 1px solid var(--clr-border-subtle);
    margin-top: 4px;
}

.odontogram-legend-item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: var(--clr-text-secondary);
}

.odontogram-legend-swatch {
    display: inline-block;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    border: 1px solid rgba(0,0,0,0.15);
}

/* Sidebar */
.odontogram-sidebar {
    background: var(--clr-surface-card);
    border: 1px solid var(--clr-border);
    border-radius: var(--radius);
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 16px;
    position: sticky;
    top: 16px;
}

.odontogram-sidebar-placeholder {
    text-align: center;
    padding: 24px 8px;
    color: var(--clr-text-muted);
}

.odontogram-sidebar-placeholder-title {
    font-weight: 600;
    color: var(--clr-text);
    margin-bottom: 6px;
}

.odontogram-sidebar-placeholder-sub {
    font-size: 12.5px;
    line-height: 1.5;
}

.odontogram-sidebar-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 8px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--clr-border-subtle);
}

.odontogram-sidebar-tooth {
    font-size: 18px;
    font-weight: 700;
    color: var(--clr-text);
}

.odontogram-sidebar-sub {
    font-size: 12px;
    color: var(--clr-text-muted);
    margin-top: 2px;
}

.odontogram-sidebar-section-title {
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--clr-text-muted);
    margin-bottom: 8px;
}

.odontogram-sidebar-surfaces {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
}

.odontogram-surface-tab {
    padding: 5px 10px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--clr-border);
    background: var(--clr-surface-card);
    cursor: pointer;
    font-size: 12px;
    color: var(--clr-text);
}

.odontogram-surface-tab:hover {
    border-color: var(--clr-primary);
}

/* Active surface tab matches the segmented-control + day-pill + date
   picker selected pattern — 12% primary tint over the card surface,
   primary border + text. */
.odontogram-surface-tab.is-active {
    background: color-mix(in srgb, var(--clr-primary) 12%, var(--clr-surface-card));
    color: var(--clr-primary);
    border-color: var(--clr-primary);
}

.odontogram-sidebar-empty {
    font-size: 12.5px;
    color: var(--clr-text-muted);
    font-style: italic;
}

.odontogram-current-mark {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 10px;
    background: var(--clr-surface);
    border-radius: var(--radius-sm);
    font-size: 13px;
    font-weight: 500;
    color: var(--clr-text);
}

.odontogram-quick-actions {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 6px;
}

.odontogram-quick-action {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 10px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--clr-border);
    background: var(--clr-surface-card);
    cursor: pointer;
    font-size: 12.5px;
    color: var(--clr-text);
    text-align: left;
    transition: border-color 0.1s, background 0.1s;
}

.odontogram-quick-action:hover:not(:disabled) {
    border-color: var(--clr-primary);
    background: color-mix(in srgb, var(--clr-primary) 6%, var(--clr-surface-card));
}

.odontogram-quick-action:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

.odontogram-sidebar-help {
    margin-top: 8px;
    font-size: 11.5px;
    color: var(--clr-text-muted);
    line-height: 1.4;
}

@media (max-width: 1100px) {
    /* `minmax(0, 1fr)` (not plain `1fr`) lets the chart column shrink
       below the row's intrinsic max-content width. Without this, the
       grid track sticks at the 16-tooth row width and .odontogram-chart's
       overflow-x: auto has nothing to scroll — the row just overflows
       and the patient-tab-content's clip crops it instead. */
    .odontogram-panel { grid-template-columns: minmax(0, 1fr); }
    .odontogram-sidebar { position: static; }
}

@media (max-width: 768px) {
    .odontogram-tooth { width: 32px; }
    .odontogram-frontal-img-wrap { height: 52px; }
    .odontogram-frontal-img { height: 52px; }
    .odontogram-occlusal-wrap { width: 30px; height: 30px; }
    .odontogram-quick-actions { grid-template-columns: 1fr; }
}

/* ─── Mobile dentist day view (/m/dentist) ────────────────────────────────── */
/* Hand-built for the phone — read-mostly "my schedule today" page.
   Caps content width on desktop so the page is still usable in a browser
   tab without looking absurd. */
.mobile-page {
    max-width: 520px;
    margin: 0 auto;
    padding: 8px 14px 32px;
}

.mobile-day-header {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 4px 14px;
    border-bottom: 1px solid var(--clr-border);
}

.mobile-day-nav {
    width: 40px;
    height: 40px;
    flex-shrink: 0;
    border: 1px solid var(--clr-border);
    background: var(--clr-surface-card);
    color: var(--clr-text);
    border-radius: 999px;
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
}

.mobile-day-nav:hover {
    background: var(--clr-border-subtle);
}

.mobile-day-header-main {
    flex: 1;
    min-width: 0;
    text-align: center;
}

.mobile-day-title {
    font-size: 16px;
    font-weight: 700;
    color: var(--clr-text);
    text-transform: capitalize;
}

.mobile-day-dentist {
    margin-top: 2px;
    font-size: 12.5px;
    color: var(--clr-text-secondary);
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.mobile-day-dentist-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--staff-colour, var(--clr-primary));
    display: inline-block;
}

.mobile-day-back-to-today {
    display: flex;
    justify-content: center;
    padding: 8px 0 4px;
}

.mobile-empty {
    text-align: center;
    padding: 48px 16px;
    color: var(--clr-text-muted);
}

.mobile-empty-title {
    font-size: 15px;
    font-weight: 600;
    color: var(--clr-text-secondary);
    margin-bottom: 4px;
}

.mobile-empty-sub {
    font-size: 13px;
}

.mobile-appt-list {
    list-style: none;
    margin: 12px 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.mobile-appt-card {
    display: grid;
    grid-template-columns: 64px 1fr auto;
    gap: 12px;
    align-items: center;
    padding: 12px 14px;
    min-height: 64px;
    background: var(--clr-surface-card);
    border: 1px solid var(--clr-border);
    border-left-width: 4px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: background 0.1s, box-shadow 0.1s;
    -webkit-tap-highlight-color: transparent;
}

.mobile-appt-card:active {
    background: var(--clr-border-subtle);
}

.mobile-appt-card.status-requested        { border-left-color: var(--clr-status-requested); }
.mobile-appt-card.status-confirmed        { border-left-color: var(--clr-status-confirmed); }
.mobile-appt-card.status-in-progress      { border-left-color: var(--clr-status-in-progress); }
.mobile-appt-card.status-completed-ni     { border-left-color: var(--clr-status-completed-ni); }
.mobile-appt-card.status-completed        { border-left-color: var(--clr-status-completed); }

.mobile-appt-time {
    font-size: 13px;
    font-weight: 700;
    color: var(--clr-text);
    line-height: 1.25;
    text-align: left;
}

.mobile-appt-time-sep {
    color: var(--clr-text-muted);
    margin: 0 1px;
}

.mobile-appt-main {
    min-width: 0;
}

.mobile-appt-name {
    font-size: 14px;
    font-weight: 600;
    color: var(--clr-text);
    line-height: 1.2;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.mobile-appt-procs {
    margin-top: 2px;
    font-size: 12px;
    color: var(--clr-text-secondary);
    line-height: 1.3;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.mobile-appt-status-pill {
    flex-shrink: 0;
    font-size: 10.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--clr-text-muted);
    padding: 3px 8px;
    background: var(--clr-border-subtle);
    border-radius: 999px;
    white-space: nowrap;
}

/* ─── Mobile drawer (sidebar as off-canvas on ≤768px) ─────────────────────── */
/* Drawer toggle lives in the topbar; it's hidden on desktop and only
   appears on small viewports where the sidebar has become a drawer. */
.topbar-drawer-toggle {
    display: none;
    align-items: center;
    justify-content: flex-start;
    padding: 0;
    border: none;
    background: transparent;
    cursor: pointer;
    flex-shrink: 0;
}

.topbar-drawer-toggle-icon {
    display: block;
    height: 24px;
    width: auto;
    flex-shrink: 0;
}

.mobile-drawer-backdrop {
    display: none;
}

@media (max-width: 768px) {
    /* Hamburger becomes visible. */
    .topbar-drawer-toggle {
        display: inline-flex;
    }

    /* Search input on the topbar overflows badly on a phone; hide it for
       now. Re-introduce as a route/page-level mobile search in a later PR. */
    .topbar-search {
        display: none;
    }

    /* Topbar row was overflowing 360px viewports because the user widget
       (avatar + name + role + caret) plus the clinic pill pushed past the
       right edge. Shrink the row's chrome, hide everything that has a
       sensible alternative elsewhere, and keep just the avatar as the
       tap target for the user-menu. Left padding matches sidebar-brand's
       padding-left so the topbar logo and the drawer brand-icon sit at
       the same x on screen. */
    .topbar {
        gap: 8px;
        padding: 0 12px 0 10px;
    }

    /* Mirror the sidebar-brand's gap so the topbar logo sits in the same
       vertical-and-horizontal grid as the drawer brand row. */
    .topbar-left {
        gap: 10px;
    }

    .topbar-user-info,
    .topbar-user-caret {
        display: none;
    }

    .clinic-pill {
        display: none;
    }

    /* Mobile rule: no line separators above panels. The card header's
       border-bottom was visually noisy on a phone; the title above the
       body is enough to separate them. */
    .card-header {
        border-bottom: none;
        padding-bottom: 4px;
    }

    /* Card-level descriptive subtitles ("Pacijenti koji čekaju slobodan
       termin" etc.) eat vertical space without adding information on a
       phone. Hide on mobile only — desktop keeps them. */
    .card-subtitle {
        display: none;
    }

    /* Tighter buttons across the board on mobile so primary actions and
       chip-style controls don't dominate the column. */
    .btn {
        padding: 6px 12px;
        font-size: 12.5px;
    }

    .btn-sm {
        padding: 4px 9px;
        font-size: 11.5px;
    }

    /* Tighter page title on mobile so it shares the row with the
       primary action buttons without crowding them. The vertical box
       also shrinks to match the smaller mobile button height (.btn at
       6/12 padding ≈ 28px tall). */
    .page-title,
    .page-header-main {
        min-height: 28px;
    }
    .page-title {
        font-size: 18px;
    }

    /* Sidebar leaves the flex flow and becomes a fixed off-canvas drawer.
       Default state: translated off-screen to the left. When the html
       attribute data-mobile-drawer="open" is set (via firmbiteMobileDrawer.open),
       it slides in. Collapsed mode is a desktop concept — the mobile
       drawer is always full-width with visible text. */
    .sidebar {
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        z-index: 1000;
        transform: translateX(-100%);
        transition: transform 0.2s ease;
        width: var(--sidebar-width);
        min-width: var(--sidebar-width);
        box-shadow: 4px 0 16px rgba(15, 27, 45, 0.2);
    }

    html[data-sidebar="collapsed"] .sidebar {
        width: var(--sidebar-width);
        min-width: var(--sidebar-width);
    }

    html[data-sidebar="collapsed"] .sidebar-brand-name,
    html[data-sidebar="collapsed"] .sidebar-toggle,
    html[data-sidebar="collapsed"] .sidebar-link span,
    html[data-sidebar="collapsed"] .nav-group-label {
        visibility: visible;
    }

    html[data-sidebar="collapsed"] .sidebar-footer {
        display: block;
    }

    html[data-mobile-drawer="open"] .sidebar {
        transform: translateX(0);
    }

    /* While the drawer is closed the app-body shouldn't reserve any width
       for the sidebar (it's now position: fixed). Width is implicitly the
       full viewport because .sidebar no longer participates in flex sizing. */

    /* Backdrop only paints while the drawer is open. Lives behind the
       sidebar so the drawer itself is interactive. */
    html[data-mobile-drawer="open"] .mobile-drawer-backdrop {
        display: block;
        position: fixed;
        inset: 0;
        background: rgba(15, 27, 45, 0.45);
        z-index: 999;
    }

    /* Lock body scroll while the drawer is open so the page underneath
       doesn't scroll under the user's thumb. */
    html[data-mobile-drawer="open"] body {
        overflow: hidden;
    }
}

/* ─── UI style overlays (per-user, scoped via data-ui-style on <html>) ─────
   Each overlay re-declares the design tokens AND the shell shapes that
   distinguish a direction — sidebar treatment, active-nav idiom, card chrome,
   button shapes, form-input radii, calendar event radii, page-header rhythm.
   Selectors are scoped by html[data-ui-style="dX"] so they win over the
   base d4 rules by specificity (no !important).

   D4 is the application default; its rules live in the base CSS above. The
   d4 overlay block exists only as a marker — pick d4 to reset cleanly. */

/* ─────────── Direction 2 — Airy: floating rounded sidebar ───────────
   Light borderless shell. Sidebar + topbar are floating cards (rounded,
   inset) — the float/inset itself lives in the min-width:769px block at the
   end so the off-canvas mobile drawer keeps the base layout. Everything here
   is cosmetic (palette, chip shapes, type) and safe at every width. */
html[data-ui-style="d2"] {
    --clr-surface:        #F4F5F7;
    --clr-surface-card:   #FFFFFF;
    --clr-sidebar-bg:     #F9FAFB;
    --clr-text:           #0A0B0F;
    --clr-text-secondary: #5C6068;
    --clr-text-muted:     #A8ACB4;
    --hairline:           #E6E8EC;
    --hairline-strong:    #C9CDD3;
    --clr-border-subtle:  #E6E8EC;
    --clr-border:         #C9CDD3;
    --radius:             10px;
    --radius-sm:          6px;
    --radius-lg:          14px;
}
html[data-ui-style="d2"] .sidebar { border-right: 0; }
html[data-ui-style="d2"] .sidebar-brand { border-bottom: 0; padding: 18px 20px 14px 16px; }
html[data-ui-style="d2"] .nav-group-label { font-size: 10.5px; letter-spacing: 0.08em; padding: 20px 22px 8px; }
html[data-ui-style="d2"] .sidebar-link { border-radius: 8px; margin: 1px 12px; padding: 9px 10px; gap: 12px; font-size: 13.5px; font-weight: 500; }
html[data-ui-style="d2"] .sidebar-link:hover { background: rgba(0, 0, 0, 0.04); }
html[data-ui-style="d2"] .sidebar-link.active { background: var(--clr-surface-card); color: var(--clr-text); font-weight: 600; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05); }
html[data-ui-style="d2"] .sidebar-link.active::before { display: none; }
html[data-ui-style="d2"] .sidebar-link.active svg { color: var(--accent); opacity: 1; }
html[data-ui-style="d2"] .sidebar-footer { border-top: 0; padding: 16px 20px; }
html[data-ui-style="d2"] .topbar { background: var(--clr-surface-card); border-bottom: 0; }
html[data-ui-style="d2"] .clinic-pill { display: inline-flex; align-items: center; gap: 8px; background: var(--clr-surface); color: var(--clr-text); padding: 5px 12px; border-radius: 999px; font-size: 12px; font-weight: 600; text-transform: none; letter-spacing: 0; }
html[data-ui-style="d2"] .clinic-pill::before { position: static; transform: none; }
html[data-ui-style="d2"] .topbar-search { background: var(--clr-surface); border: 0; border-radius: 999px; padding: 8px 14px; }
html[data-ui-style="d2"] .topbar-search:focus-within { border-color: transparent; }
html[data-ui-style="d2"] .topbar-kbd { background: var(--clr-surface-card); border: 0; border-radius: 4px; }
html[data-ui-style="d2"] .topbar-icon-btn { width: 34px; height: 34px; border-radius: 999px; }
html[data-ui-style="d2"] .topbar-icon-btn:hover { background: var(--clr-surface); }
html[data-ui-style="d2"] .topbar-user { background: var(--clr-surface); border-radius: 999px; padding: 4px 12px 4px 4px; }
html[data-ui-style="d2"] .topbar-user-avatar { width: 28px; height: 28px; }
html[data-ui-style="d2"] .page-header { border-bottom: 0; padding-block: 0; }
html[data-ui-style="d2"] .page-title { font-weight: 700; letter-spacing: -0.025em; }
html[data-ui-style="d2"] .card { border-radius: 14px; }
html[data-ui-style="d2"] .card-header { border-bottom: 1px solid var(--hairline); }
html[data-ui-style="d2"] .card-title { text-transform: none; letter-spacing: 0; font-size: 13.5px; font-weight: 600; }
html[data-ui-style="d2"] .btn { border-radius: 999px; text-transform: none; letter-spacing: 0; font-weight: 600; font-size: 13px; }
html[data-ui-style="d2"] .form-input,
html[data-ui-style="d2"] .form-select,
html[data-ui-style="d2"] .form-textarea { border-radius: 10px; }
html[data-ui-style="d2"] .calendar-event,
html[data-ui-style="d2"] .calendar-block { border-radius: 8px; }

/* ─────────── Direction 2a — Airy · Topla (warm cream) ───────────
   The d2 airy shell on a warm off-white palette. Chips pick up the cream
   sidebar tone rather than the page grey. Floating/inset in the desktop block. */
html[data-ui-style="d2a"] {
    --clr-surface:        #F4F1EA;
    --clr-surface-card:   #FFFEFB;
    --clr-sidebar-bg:     #EFEBE0;
    --hairline:           #E4DFD1;
    --hairline-strong:    #C8C0A8;
    --clr-border-subtle:  #E4DFD1;
    --clr-border:         #C8C0A8;
    --clr-text:           #1D1A14;
    --clr-text-secondary: #5B554A;
    --clr-text-muted:     #A6A095;
    --radius:             10px;
    --radius-sm:          6px;
    --radius-lg:          14px;
}
html[data-ui-style="d2a"] .sidebar { border-right: 0; }
html[data-ui-style="d2a"] .sidebar-brand { border-bottom: 0; padding: 18px 20px 14px 16px; }
html[data-ui-style="d2a"] .nav-group-label { font-size: 10.5px; letter-spacing: 0.08em; padding: 20px 22px 8px; }
html[data-ui-style="d2a"] .sidebar-link { border-radius: 8px; margin: 1px 12px; padding: 9px 10px; gap: 12px; font-size: 13.5px; font-weight: 500; }
html[data-ui-style="d2a"] .sidebar-link:hover { background: rgba(0, 0, 0, 0.04); }
html[data-ui-style="d2a"] .sidebar-link.active { background: var(--clr-surface-card); color: var(--clr-text); font-weight: 600; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04); }
html[data-ui-style="d2a"] .sidebar-link.active::before { display: none; }
html[data-ui-style="d2a"] .sidebar-link.active svg { color: var(--accent); opacity: 1; }
html[data-ui-style="d2a"] .sidebar-footer { border-top: 0; padding: 16px 20px; }
html[data-ui-style="d2a"] .topbar { background: var(--clr-surface-card); border-bottom: 0; }
html[data-ui-style="d2a"] .clinic-pill { display: inline-flex; align-items: center; gap: 8px; background: var(--clr-sidebar-bg); color: var(--clr-text); padding: 5px 12px; border-radius: 999px; font-size: 12px; font-weight: 600; text-transform: none; letter-spacing: 0; }
html[data-ui-style="d2a"] .clinic-pill::before { position: static; transform: none; }
html[data-ui-style="d2a"] .topbar-search { background: var(--clr-sidebar-bg); border: 0; border-radius: 999px; padding: 8px 14px; }
html[data-ui-style="d2a"] .topbar-search:focus-within { border-color: transparent; }
html[data-ui-style="d2a"] .topbar-kbd { background: var(--clr-surface-card); border: 0; border-radius: 4px; }
html[data-ui-style="d2a"] .topbar-icon-btn { width: 34px; height: 34px; border-radius: 999px; }
html[data-ui-style="d2a"] .topbar-icon-btn:hover { background: var(--clr-sidebar-bg); }
html[data-ui-style="d2a"] .topbar-user { background: var(--clr-sidebar-bg); border-radius: 999px; padding: 4px 12px 4px 4px; }
html[data-ui-style="d2a"] .topbar-user-avatar { width: 28px; height: 28px; }
html[data-ui-style="d2a"] .page-header { border-bottom: 0; padding-block: 0; }
html[data-ui-style="d2a"] .page-title { font-weight: 700; letter-spacing: -0.025em; }
html[data-ui-style="d2a"] .card { border-radius: 14px; }
html[data-ui-style="d2a"] .card-title { text-transform: none; letter-spacing: 0; font-size: 13.5px; font-weight: 600; }
html[data-ui-style="d2a"] .btn { border-radius: 999px; text-transform: none; letter-spacing: 0; font-weight: 600; font-size: 13px; }
html[data-ui-style="d2a"] .form-input,
html[data-ui-style="d2a"] .form-select,
html[data-ui-style="d2a"] .form-textarea { border-radius: 10px; }
html[data-ui-style="d2a"] .calendar-event,
html[data-ui-style="d2a"] .calendar-block { border-radius: 8px; }

/* ─────────── Direction 2b — Airy · Frosted (bloom + glass) ───────────
   Translucent frosted panels over a soft colour bloom. Glass surfaces come
   from the rgba surface tokens + backdrop-filter; chips are their own lighter
   glass. Float/inset is in the desktop block. */
html[data-ui-style="d2b"] {
    --clr-surface:        #EEF1F5;
    --clr-surface-card:   rgba(255, 255, 255, 0.78);
    --clr-sidebar-bg:     rgba(255, 255, 255, 0.55);
    --clr-text:           #0E1015;
    --clr-text-secondary: #5A5F69;
    --clr-text-muted:     #A2A7B1;
    --hairline:           rgba(0, 0, 0, 0.06);
    --hairline-strong:    rgba(0, 0, 0, 0.14);
    --clr-border-subtle:  rgba(0, 0, 0, 0.06);
    --clr-border:         rgba(0, 0, 0, 0.14);
    --radius:             12px;
    --radius-sm:          8px;
    --radius-lg:          16px;
}
html[data-ui-style="d2b"] body {
    background:
        radial-gradient(80% 60% at 80% 0%, rgba(120, 175, 220, 0.35), transparent 65%),
        radial-gradient(60% 60% at 0% 100%, rgba(220, 200, 255, 0.32), transparent 70%),
        #EEF1F5;
    background-attachment: fixed;
}
html[data-ui-style="d2b"] .sidebar {
    border-right: 0;
    backdrop-filter: blur(18px);
    -webkit-backdrop-filter: blur(18px);
}
html[data-ui-style="d2b"] .sidebar-brand { border-bottom: 0; padding: 18px 20px 14px 16px; }
html[data-ui-style="d2b"] .nav-group-label { font-size: 10.5px; letter-spacing: 0.08em; padding: 20px 22px 8px; }
html[data-ui-style="d2b"] .sidebar-link { border-radius: 8px; margin: 1px 12px; padding: 9px 10px; gap: 12px; font-size: 13.5px; font-weight: 500; }
html[data-ui-style="d2b"] .sidebar-link:hover { background: rgba(255, 255, 255, 0.5); }
html[data-ui-style="d2b"] .sidebar-link.active { background: rgba(255, 255, 255, 0.85); color: var(--clr-text); font-weight: 600; box-shadow: 0 1px 3px rgba(15, 30, 60, 0.06); }
html[data-ui-style="d2b"] .sidebar-link.active::before { display: none; }
html[data-ui-style="d2b"] .sidebar-link.active svg { color: var(--accent); opacity: 1; }
html[data-ui-style="d2b"] .sidebar-footer { border-top: 0; padding: 16px 20px; }
html[data-ui-style="d2b"] .topbar {
    background: rgba(255, 255, 255, 0.5);
    border-bottom: 0;
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
}
html[data-ui-style="d2b"] .clinic-pill { display: inline-flex; align-items: center; gap: 8px; background: rgba(255, 255, 255, 0.6); color: var(--clr-text); padding: 5px 12px; border-radius: 999px; font-size: 12px; font-weight: 600; text-transform: none; letter-spacing: 0; }
html[data-ui-style="d2b"] .clinic-pill::before { position: static; transform: none; }
html[data-ui-style="d2b"] .topbar-search { background: rgba(255, 255, 255, 0.6); border: 0; border-radius: 999px; padding: 8px 14px; }
html[data-ui-style="d2b"] .topbar-search:focus-within { border-color: transparent; }
html[data-ui-style="d2b"] .topbar-kbd { background: rgba(255, 255, 255, 0.9); border: 0; border-radius: 4px; }
html[data-ui-style="d2b"] .topbar-icon-btn { width: 34px; height: 34px; border-radius: 999px; }
html[data-ui-style="d2b"] .topbar-icon-btn:hover { background: rgba(255, 255, 255, 0.5); }
html[data-ui-style="d2b"] .topbar-user { background: rgba(255, 255, 255, 0.6); border-radius: 999px; padding: 4px 12px 4px 4px; }
html[data-ui-style="d2b"] .topbar-user-avatar { width: 28px; height: 28px; }
html[data-ui-style="d2b"] .page-header { border-bottom: 0; padding-block: 0; }
html[data-ui-style="d2b"] .page-title { font-weight: 700; letter-spacing: -0.025em; }
html[data-ui-style="d2b"] .card {
    border-radius: 14px;
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
}
html[data-ui-style="d2b"] .card-title { text-transform: none; letter-spacing: 0; font-size: 13.5px; font-weight: 600; }
html[data-ui-style="d2b"] .btn { border-radius: 999px; text-transform: none; letter-spacing: 0; font-weight: 600; font-size: 13px; box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12); }
html[data-ui-style="d2b"] .form-input,
html[data-ui-style="d2b"] .form-select,
html[data-ui-style="d2b"] .form-textarea { border-radius: 10px; }
html[data-ui-style="d2b"] .calendar-event,
html[data-ui-style="d2b"] .calendar-block { border-radius: 8px; }

/* ─────────── Direction 2d — Airy · Hairline (pure white minimal) ───────────
   Pure white, hairlines only at major divisions, no float. Nav active is an
   accent-tint pill (matches direction-2d preview — not the d4 accent bar).
   Chips are hairline-outlined rather than filled. */
html[data-ui-style="d2d"] {
    --clr-surface:        #FFFFFF;
    --clr-surface-card:   #FFFFFF;
    --clr-sidebar-bg:     #FFFFFF;
    --clr-text:           #0A0B0F;
    --clr-text-secondary: #5A5F69;
    --clr-text-muted:     #A2A7B1;
    --hairline:           #ECEEF1;
    --hairline-strong:    #D6DAE0;
    --clr-border-subtle:  #ECEEF1;
    --clr-border:         #D6DAE0;
    --radius:             8px;
    --radius-sm:          6px;
    --radius-lg:          10px;
}
html[data-ui-style="d2d"] .sidebar-brand { margin-bottom: 12px; padding-left: 16px; }
html[data-ui-style="d2d"] .nav-group-label { font-size: 10.5px; letter-spacing: 0.08em; padding: 20px 22px 8px; }
html[data-ui-style="d2d"] .sidebar-link { border-radius: 8px; margin: 1px 12px; padding: 9px 10px; gap: 12px; font-size: 13.5px; font-weight: 500; }
html[data-ui-style="d2d"] .sidebar-link:hover { background: rgba(0, 0, 0, 0.03); }
html[data-ui-style="d2d"] .sidebar-link.active { background: color-mix(in srgb, var(--accent) 8%, white); color: var(--accent); font-weight: 600; }
html[data-ui-style="d2d"] .sidebar-link.active::before { display: none; }
html[data-ui-style="d2d"] .sidebar-link.active svg { color: var(--accent); opacity: 1; }
html[data-ui-style="d2d"] .clinic-pill { display: inline-flex; align-items: center; gap: 8px; background: color-mix(in srgb, var(--accent) 8%, white); color: var(--clr-text); padding: 5px 12px; border-radius: 999px; font-size: 12px; font-weight: 600; text-transform: none; letter-spacing: 0; }
html[data-ui-style="d2d"] .clinic-pill::before { position: static; transform: none; }
html[data-ui-style="d2d"] .topbar-search { background: transparent; border: 1px solid var(--hairline); border-radius: 999px; padding: 7px 14px; }
html[data-ui-style="d2d"] .topbar-search:focus-within { border-color: var(--hairline-strong); }
html[data-ui-style="d2d"] .topbar-kbd { background: var(--clr-surface-card); border-radius: 4px; }
html[data-ui-style="d2d"] .topbar-icon-btn { width: 34px; height: 34px; border-radius: 999px; }
html[data-ui-style="d2d"] .topbar-icon-btn:hover { background: color-mix(in srgb, var(--accent) 8%, white); }
html[data-ui-style="d2d"] .topbar-user { border: 1px solid var(--hairline); border-radius: 999px; padding: 4px 12px 4px 4px; }
html[data-ui-style="d2d"] .topbar-user-avatar { width: 28px; height: 28px; }
html[data-ui-style="d2d"] .page-title { font-weight: 700; letter-spacing: -0.02em; }
html[data-ui-style="d2d"] .card { border-radius: 8px; }
html[data-ui-style="d2d"] .card-title { text-transform: none; letter-spacing: 0; font-size: 13.5px; font-weight: 600; }
html[data-ui-style="d2d"] .btn { border-radius: 999px; text-transform: none; letter-spacing: 0; font-weight: 600; font-size: 13px; }
html[data-ui-style="d2d"] .form-input,
html[data-ui-style="d2d"] .form-select,
html[data-ui-style="d2d"] .form-textarea { border-radius: 8px; }

/* ─────────── Direction 2e — Airy · Cards (grey bg, floating white cards) ───────────
   Grey canvas; every surface (sidebar, topbar, page header, panels) is a
   floating white card with a soft shadow. Nav active is an accent-tint pill.
   Float/inset is in the desktop block. */
html[data-ui-style="d2e"] {
    --clr-surface:        #ECEEF2;
    --clr-surface-card:   #FFFFFF;
    --clr-sidebar-bg:     #FFFFFF;
    --clr-text:           #0A0B0F;
    --clr-text-secondary: #5A5F69;
    --clr-text-muted:     #A2A7B1;
    --hairline:           transparent;
    --hairline-strong:    #C8CBD2;
    --clr-border-subtle:  transparent;
    --clr-border:         #C8CBD2;
    --shadow-sm:          0 1px 2px rgba(15, 23, 42, 0.06);
    --shadow:             0 6px 20px rgba(20, 30, 55, 0.05), 0 1px 2px rgba(20, 30, 55, 0.03);
    --shadow-md:          0 8px 24px rgba(15, 23, 42, 0.10);
    --radius:             12px;
    --radius-sm:          8px;
    --radius-lg:          16px;
}
html[data-ui-style="d2e"] .sidebar { border-right: 0; box-shadow: var(--shadow); }
html[data-ui-style="d2e"] .sidebar-brand { border-bottom: 0; padding: 18px 20px 14px 16px; }
html[data-ui-style="d2e"] .nav-group-label { font-size: 10.5px; letter-spacing: 0.08em; padding: 20px 22px 8px; }
html[data-ui-style="d2e"] .sidebar-link { border-radius: 8px; margin: 1px 12px; padding: 9px 10px; gap: 12px; font-size: 13.5px; font-weight: 500; }
html[data-ui-style="d2e"] .sidebar-link:hover { background: var(--clr-surface); }
html[data-ui-style="d2e"] .sidebar-link.active { background: color-mix(in srgb, var(--accent) 9%, white); color: var(--accent); font-weight: 600; }
html[data-ui-style="d2e"] .sidebar-link.active::before { display: none; }
html[data-ui-style="d2e"] .sidebar-link.active svg { color: var(--accent); opacity: 1; }
html[data-ui-style="d2e"] .sidebar-footer { border-top: 0; padding: 16px 20px; }
html[data-ui-style="d2e"] .topbar { background: var(--clr-surface-card); box-shadow: var(--shadow); border-bottom: 0; }
html[data-ui-style="d2e"] .clinic-pill { display: inline-flex; align-items: center; gap: 8px; background: var(--clr-surface); color: var(--clr-text); padding: 5px 12px; border-radius: 999px; font-size: 12px; font-weight: 600; text-transform: none; letter-spacing: 0; }
html[data-ui-style="d2e"] .clinic-pill::before { position: static; transform: none; }
html[data-ui-style="d2e"] .topbar-search { background: var(--clr-surface); border: 0; border-radius: 999px; padding: 8px 14px; }
html[data-ui-style="d2e"] .topbar-search:focus-within { border-color: transparent; }
html[data-ui-style="d2e"] .topbar-kbd { background: var(--clr-surface-card); border: 0; border-radius: 4px; }
html[data-ui-style="d2e"] .topbar-icon-btn { width: 34px; height: 34px; border-radius: 999px; }
html[data-ui-style="d2e"] .topbar-icon-btn:hover { background: var(--clr-surface); }
html[data-ui-style="d2e"] .topbar-user { background: var(--clr-surface); border-radius: 999px; padding: 4px 12px 4px 4px; }
html[data-ui-style="d2e"] .topbar-user-avatar { width: 28px; height: 28px; }
html[data-ui-style="d2e"] .page-header { background: var(--clr-surface-card); border-radius: 16px; box-shadow: var(--shadow); border-bottom: 0; padding: 20px 24px; margin-bottom: 16px; }
html[data-ui-style="d2e"] .page-title { font-weight: 700; letter-spacing: -0.02em; }
html[data-ui-style="d2e"] .card { border-radius: 16px; border-color: transparent; box-shadow: var(--shadow); }
html[data-ui-style="d2e"] .card-header { border-bottom: 1px solid #F1F3F6; }
html[data-ui-style="d2e"] .card-title { text-transform: none; letter-spacing: 0; font-size: 13.5px; font-weight: 600; }
html[data-ui-style="d2e"] .btn { border-radius: 999px; text-transform: none; letter-spacing: 0; font-weight: 600; font-size: 12.5px; }
html[data-ui-style="d2e"] .form-input,
html[data-ui-style="d2e"] .form-select,
html[data-ui-style="d2e"] .form-textarea { border-radius: 10px; }
html[data-ui-style="d2e"] .calendar-event,
html[data-ui-style="d2e"] .calendar-block { border-radius: 8px; }

/* ─────────── Direction 3 — Soft & rounded (dark sidebar) ───────────
   Dark gradient sidebar, generous radii, soft shadows. Topbar is a floating
   rounded card with filled rounded chips; buttons are soft 14px rounds with a
   tinted shadow. Sidebar stays full-height (works as the mobile drawer too);
   only the topbar float + main padding are deferred to the desktop block. */
html[data-ui-style="d3"] {
    --clr-surface:        #F1F4F8;
    --clr-surface-card:   #FFFFFF;
    --clr-sidebar-bg:     #1A1C22;
    --clr-text:           #1A1B22;
    --clr-text-secondary: #5E626B;
    --clr-text-muted:     #98A0AC;
    --hairline:           #E2E6EC;
    --hairline-strong:    #C9CFD8;
    --clr-border-subtle:  #E2E6EC;
    --clr-border:         #C9CFD8;
    --radius:             12px;
    --radius-sm:          8px;
    --radius-lg:          16px;
}
/* Dark sidebar with white text. Brand PNGs flip to white via filter so the
   masked-recolour CSS in the base block doesn't have to be touched. */
html[data-ui-style="d3"] .sidebar {
    background: linear-gradient(180deg, #16181D 0%, #1F2128 100%);
    color: #BFC4CE;
    border-right: 0;
}
html[data-ui-style="d3"] .sidebar-brand { border-bottom: 1px solid rgba(255,255,255,0.05); padding-left: 20px; }
html[data-ui-style="d3"] .sidebar-brand:hover { background: rgba(255,255,255,0.04); }
html[data-ui-style="d3"] .sidebar-brand-icon,
html[data-ui-style="d3"] .sidebar-brand-name { filter: invert(1) brightness(1.1); }
html[data-ui-style="d3"] .sidebar-toggle { color: #BFC4CE; }
html[data-ui-style="d3"] .sidebar-toggle:hover { color: #fff; background: rgba(255,255,255,0.06); }
html[data-ui-style="d3"] .sidebar-nav { padding: 12px 0; }
html[data-ui-style="d3"] .sidebar-link {
    color: #BFC4CE;
    border-radius: 12px;
    margin: 1px 12px;
    padding: 10px 14px;
    gap: 12px;
    font-size: 13.5px;
}
html[data-ui-style="d3"] .sidebar-link svg { opacity: 0.65; color: #BFC4CE; }
html[data-ui-style="d3"] .sidebar-link:hover {
    background: rgba(255,255,255,0.06);
    color: #fff;
}
html[data-ui-style="d3"] .sidebar-link:hover svg { color: #fff; opacity: 1; }
html[data-ui-style="d3"] .sidebar-link.active {
    background: var(--accent);
    color: #fff;
    font-weight: 600;
}
html[data-ui-style="d3"] .sidebar-link.active::before { display: none; }
html[data-ui-style="d3"] .sidebar-link.active svg { color: #fff; opacity: 1; }
html[data-ui-style="d3"] .sidebar-footer {
    border-top: 1px solid rgba(255,255,255,0.05);
    color: #707682;
}
html[data-ui-style="d3"] .sidebar-footer-clinic { color: #BFC4CE; }
html[data-ui-style="d3"] .sidebar-footer-version { color: #707682; }
html[data-ui-style="d3"] .topbar { background: var(--clr-surface-card); border-bottom: 0; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.03); }
html[data-ui-style="d3"] .clinic-pill { display: inline-flex; align-items: center; gap: 8px; background: var(--clr-surface); color: var(--clr-text); padding: 6px 14px; border-radius: 999px; font-size: 12.5px; font-weight: 600; text-transform: none; letter-spacing: 0; }
html[data-ui-style="d3"] .clinic-pill::before { position: static; transform: none; }
html[data-ui-style="d3"] .topbar-search { background: var(--clr-surface); border: 0; border-radius: 999px; padding: 9px 16px; }
html[data-ui-style="d3"] .topbar-search:focus-within { border-color: transparent; }
html[data-ui-style="d3"] .topbar-kbd { background: var(--clr-surface-card); border: 0; border-radius: 999px; }
html[data-ui-style="d3"] .topbar-icon-btn { width: 36px; height: 36px; border-radius: 12px; background: var(--clr-surface); }
html[data-ui-style="d3"] .topbar-user { background: var(--clr-surface); border-radius: 999px; padding: 4px 14px 4px 4px; }
html[data-ui-style="d3"] .topbar-user-avatar { width: 30px; height: 30px; }
html[data-ui-style="d3"] .page-title { font-weight: 700; letter-spacing: -0.02em; }
html[data-ui-style="d3"] .card { border-radius: 16px; }
html[data-ui-style="d3"] .card-title { text-transform: none; letter-spacing: 0; font-size: 13.5px; font-weight: 600; }
html[data-ui-style="d3"] .btn { border-radius: 14px; text-transform: none; letter-spacing: 0; font-weight: 600; font-size: 13px; box-shadow: 0 2px 6px color-mix(in srgb, var(--accent) 25%, transparent); }
html[data-ui-style="d3"] .form-input,
html[data-ui-style="d3"] .form-select,
html[data-ui-style="d3"] .form-textarea { border-radius: 10px; }
html[data-ui-style="d3"] .calendar-event,
html[data-ui-style="d3"] .calendar-block { border-radius: 8px; }

/* ─────────── Floating-shell layout (desktop only) ──────────────────────────
   The airy directions render the sidebar and topbar as cards inset from the
   viewport with a gutter between them. Restricted to ≥769px so the ≤768px
   off-canvas drawer (position:fixed sidebar) and the compact mobile topbar
   keep the base layout untouched. Page-title sizing and pill-button padding
   live here too because the ≤768px base rules deliberately clamp them down. */
@media (min-width: 769px) {
    /* Floating rounded sidebar — d2 / d2a / d2b / d2e */
    html[data-ui-style="d2"]  .sidebar,
    html[data-ui-style="d2a"] .sidebar,
    html[data-ui-style="d2b"] .sidebar,
    html[data-ui-style="d2e"] .sidebar {
        border-radius: 18px;
        margin: 16px 0 16px 16px;
        height: calc(100% - 32px);
    }

    /* Floating topbar card — d2 / d2a / d2b / d2e (14px) */
    html[data-ui-style="d2"]  .topbar,
    html[data-ui-style="d2a"] .topbar,
    html[data-ui-style="d2b"] .topbar,
    html[data-ui-style="d2e"] .topbar {
        border-radius: 14px;
        height: auto;
        padding: 10px 18px;
        margin: 16px 16px 0;
    }
    html[data-ui-style="d2"]  .main-content,
    html[data-ui-style="d2a"] .main-content,
    html[data-ui-style="d2b"] .main-content,
    html[data-ui-style="d2e"] .main-content {
        padding: 16px;
    }

    /* d3 floats the topbar (16px round) over the full-height dark sidebar. */
    html[data-ui-style="d3"] .topbar {
        border-radius: 16px;
        height: auto;
        padding: 10px 18px;
        margin: 16px 20px 0;
    }
    html[data-ui-style="d3"] .main-content { padding: 16px 20px 24px; }

    /* Editorial title scale (base ≤768px clamps to 18px). */
    html[data-ui-style="d2"]  .page-title,
    html[data-ui-style="d2a"] .page-title,
    html[data-ui-style="d2b"] .page-title { font-size: 28px; }
    html[data-ui-style="d2d"] .page-title,
    html[data-ui-style="d3"]  .page-title { font-size: 26px; }
    html[data-ui-style="d2e"] .page-title { font-size: 24px; }

    /* Pill-button padding per preview (base ≤768px clamps to 6/12). */
    html[data-ui-style="d2"]  .btn,
    html[data-ui-style="d2a"] .btn,
    html[data-ui-style="d2b"] .btn,
    html[data-ui-style="d2d"] .btn { padding: 9px 18px; }
    html[data-ui-style="d2e"] .btn { padding: 8px 18px; }
    html[data-ui-style="d3"]  .btn { padding: 11px 20px; }
}

/* ─────────── Direction 4 — Sharp & editorial (default; no overrides) ───── */
html[data-ui-style="d4"] { /* intentionally empty */ }

/* ─────────── Time-grid surface overrides (Calendar / any provider strip) ──
   The preview HTMLs render the time grid as a "provider-strip table": one
   row per dentist with hours running across the top. The styling language —
   tinted appointment chips with dark text, an accent rail, per-direction
   radii and column-header typography — is what each direction expects on
   ANY time grid in the app. We apply it to FirmBite's existing
   .calendar-* DOM (which is a vertical week grid, not the horizontal
   provider strip the previews show), trading layout fidelity for the
   strong visual signal: the events now read distinctly per direction
   rather than just changing color. */

/* All non-d4 styles: rounded events with tinted backgrounds, dark text,
   colored rail at the left edge. Status colour comes from --ev-color
   declared on the .status-X classes above. */

/* d2 / d2a / d2b / d2d / d2e shared event treatment */
html[data-ui-style="d2"] .calendar-event,
html[data-ui-style="d2a"] .calendar-event,
html[data-ui-style="d2b"] .calendar-event,
html[data-ui-style="d2d"] .calendar-event,
html[data-ui-style="d2e"] .calendar-event {
    background: color-mix(in srgb, var(--ev-color, var(--clr-status-confirmed)) 10%, white);
    color: var(--clr-text);
    border-left: 0;
    padding: 3px 6px 3px 13px;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
}
html[data-ui-style="d2"]  .calendar-event { border-radius: 10px; }
html[data-ui-style="d2a"] .calendar-event { border-radius: 10px; }
html[data-ui-style="d2b"] .calendar-event { border-radius: 10px; }
html[data-ui-style="d2d"] .calendar-event { border-radius: 8px; box-shadow: none; }
html[data-ui-style="d2e"] .calendar-event { border-radius: 10px; box-shadow: var(--shadow-sm); }

/* Colored rail accent — a 3-px pill anchored inside the event's left edge,
   replacing the rgba(0,0,0,0.18) hairline that the d4 default carries. */
html[data-ui-style="d2"] .calendar-event::before,
html[data-ui-style="d2a"] .calendar-event::before,
html[data-ui-style="d2b"] .calendar-event::before,
html[data-ui-style="d2d"] .calendar-event::before,
html[data-ui-style="d2e"] .calendar-event::before {
    content: '';
    position: absolute;
    top: 4px;
    bottom: 4px;
    left: 4px;
    width: 3px;
    border-radius: 2px;
    background: var(--ev-color, var(--clr-status-confirmed));
}
/* Restore dark text colours for nested event labels (the d4 defaults assume
   white text on solid bg; tinted bg needs near-black labels). */
html[data-ui-style="d2"] .calendar-event-time,
html[data-ui-style="d2a"] .calendar-event-time,
html[data-ui-style="d2b"] .calendar-event-time,
html[data-ui-style="d2d"] .calendar-event-time,
html[data-ui-style="d2e"] .calendar-event-time { color: var(--clr-text-secondary); opacity: 1; }
html[data-ui-style="d2"] .calendar-event-name,
html[data-ui-style="d2a"] .calendar-event-name,
html[data-ui-style="d2b"] .calendar-event-name,
html[data-ui-style="d2d"] .calendar-event-name,
html[data-ui-style="d2e"] .calendar-event-name { color: var(--clr-text); }
html[data-ui-style="d2"] .calendar-event-sub,
html[data-ui-style="d2a"] .calendar-event-sub,
html[data-ui-style="d2b"] .calendar-event-sub,
html[data-ui-style="d2d"] .calendar-event-sub,
html[data-ui-style="d2e"] .calendar-event-sub { color: var(--clr-text-muted); opacity: 1; }

/* d3 — slightly stronger tint (12%), generous radius, no shadow */
html[data-ui-style="d3"] .calendar-event {
    background: color-mix(in srgb, var(--ev-color, var(--clr-status-confirmed)) 12%, white);
    color: var(--clr-text);
    border-left: 0;
    border-radius: 14px;
    padding: 3px 6px 3px 14px;
    box-shadow: none;
}
html[data-ui-style="d3"] .calendar-event::before {
    content: '';
    position: absolute;
    top: 4px;
    bottom: 4px;
    left: 5px;
    width: 3px;
    border-radius: 2px;
    background: var(--ev-color, var(--clr-status-confirmed));
}
html[data-ui-style="d3"] .calendar-event-time { color: var(--clr-text-secondary); opacity: 1; }
html[data-ui-style="d3"] .calendar-event-name { color: var(--clr-text); }
html[data-ui-style="d3"] .calendar-event-sub  { color: var(--clr-text-muted); opacity: 1; }

/* d4 — editorial: white surface, hairline-near-black left border, status as
   a colored dot indicator, dark text. Matches direction-4 preview's .event
   block. (Previously d4 also rendered solid-colour with white text; bring
   it into line with its own preview now that we have the option.) */
html[data-ui-style="d4"] .calendar-event {
    background: var(--clr-surface-card);
    color: var(--clr-text);
    border-left: 1px solid var(--clr-text);
    border-radius: 0;
    padding: 3px 6px;
    box-shadow: none;
}
html[data-ui-style="d4"] .calendar-event::before {
    content: '';
    position: absolute;
    top: 5px;
    left: 4px;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--ev-color, var(--clr-status-confirmed));
}
html[data-ui-style="d4"] .calendar-event-time { color: var(--clr-text-muted); opacity: 1; padding-left: 9px; }
html[data-ui-style="d4"] .calendar-event-name { color: var(--clr-text); }
html[data-ui-style="d4"] .calendar-event-sub  { color: var(--clr-text-muted); opacity: 1; }

/* Blocked-time chips follow the same per-direction radius and lose the
   dark-rgba left rail so they sit in the new tinted aesthetic. */
html[data-ui-style="d2"]  .calendar-block,
html[data-ui-style="d2a"] .calendar-block,
html[data-ui-style="d2b"] .calendar-block { border-radius: 10px; border-left: 0; }
html[data-ui-style="d2d"] .calendar-block { border-radius: 8px;  border-left: 0; box-shadow: none; }
html[data-ui-style="d2e"] .calendar-block { border-radius: 10px; border-left: 0; box-shadow: var(--shadow-sm); }
html[data-ui-style="d3"]  .calendar-block { border-radius: 14px; border-left: 0; }
html[data-ui-style="d4"]  .calendar-block { border-radius: 0;    border-left: 1px solid var(--clr-text); }

/* Column-header typography per direction. The previews diverge most on this
   row — letter-spacing/weight/case. Match each preview's idiom. */
html[data-ui-style="d2"]  .calendar-col-header-main,
html[data-ui-style="d2a"] .calendar-col-header-main,
html[data-ui-style="d2b"] .calendar-col-header-main,
html[data-ui-style="d2e"] .calendar-col-header-main { font-weight: 600; font-size: 12px; letter-spacing: 0; text-transform: none; }
html[data-ui-style="d2d"] .calendar-col-header-main { font-weight: 700; font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; }
html[data-ui-style="d3"]  .calendar-col-header-main { font-weight: 700; font-size: 12.5px; letter-spacing: 0; text-transform: none; }
html[data-ui-style="d4"]  .calendar-col-header-main { font-weight: 700; font-size: 10.5px; letter-spacing: 0.12em; text-transform: uppercase; }

/* Hour-label typography per direction. d4 keeps the monospace + uppercase
   editorial idiom; everyone else moves to Inter for the airy look. */
html[data-ui-style="d2"]  .calendar-hour-label,
html[data-ui-style="d2a"] .calendar-hour-label,
html[data-ui-style="d2b"] .calendar-hour-label,
html[data-ui-style="d2d"] .calendar-hour-label,
html[data-ui-style="d2e"] .calendar-hour-label,
html[data-ui-style="d3"]  .calendar-hour-label {
    font-family: 'Inter', system-ui, sans-serif;
    font-size: 11.5px;
    font-weight: 600;
}

/* Column-header background, time-axis border, cell dividers per direction —
   pulled forward from the previews' .grid-card / .grid-time-header rules. */
html[data-ui-style="d2"]  .calendar-col-header,
html[data-ui-style="d2a"] .calendar-col-header,
html[data-ui-style="d2b"] .calendar-col-header {
    background: var(--clr-surface);
    border-right: 0;
    border-bottom: 1px solid var(--hairline);
}
html[data-ui-style="d2"]  .calendar-time-axis,
html[data-ui-style="d2a"] .calendar-time-axis,
html[data-ui-style="d2b"] .calendar-time-axis,
html[data-ui-style="d2e"] .calendar-time-axis,
html[data-ui-style="d3"]  .calendar-time-axis { border-right: 0; }
html[data-ui-style="d2"]  .calendar-time-axis .calendar-corner,
html[data-ui-style="d2a"] .calendar-time-axis .calendar-corner,
html[data-ui-style="d2b"] .calendar-time-axis .calendar-corner {
    background: var(--clr-surface);
    border-bottom: 1px solid var(--hairline);
}
html[data-ui-style="d2"]  .calendar-cell,
html[data-ui-style="d2a"] .calendar-cell,
html[data-ui-style="d2b"] .calendar-cell { border-right: 0; }

html[data-ui-style="d2d"] .calendar-col-header {
    background: var(--clr-surface-card);
    border-bottom: 1px solid var(--hairline);
}

html[data-ui-style="d2e"] .calendar-col-header {
    background: var(--clr-surface-card);
    border-right: 0;
    border-bottom: 1px solid #F1F3F6;
}
html[data-ui-style="d2e"] .calendar-time-axis .calendar-corner {
    background: var(--clr-surface-card);
    border-bottom: 1px solid #F1F3F6;
}
html[data-ui-style="d2e"] .calendar-cell {
    border-right: 0;
    border-bottom: 1px dashed #EFF1F4;
}

html[data-ui-style="d3"] .calendar-layout { background: var(--clr-surface-card); }
html[data-ui-style="d3"] .calendar-col-header {
    background: var(--clr-surface-card);
    border-right: 0;
    border-bottom: 1px solid var(--hairline);
}
html[data-ui-style="d3"] .calendar-time-axis .calendar-corner {
    background: var(--clr-surface-card);
    border-bottom: 1px solid var(--hairline);
}
html[data-ui-style="d3"] .calendar-cell {
    border-right: 0;
    border-bottom: 1px solid var(--hairline);
}
html[data-ui-style="d3"] .calendar-grid > .calendar-cell:nth-of-type(2n) {
    border-bottom-style: solid;
    border-bottom-color: var(--hairline);
}

html[data-ui-style="d2"]  .calendar-grid > .calendar-cell:nth-of-type(2n),
html[data-ui-style="d2a"] .calendar-grid > .calendar-cell:nth-of-type(2n),
html[data-ui-style="d2b"] .calendar-grid > .calendar-cell:nth-of-type(2n) {
    border-bottom-style: solid;
    border-bottom-color: var(--hairline);
}

/* Card containing the calendar gets overflow:hidden where the card has a
   non-zero border-radius, so the grid's square inner corners clip cleanly. */
html[data-ui-style="d2"]  .card,
html[data-ui-style="d2a"] .card,
html[data-ui-style="d2b"] .card,
html[data-ui-style="d2e"] .card,
html[data-ui-style="d3"]  .card { overflow: hidden; }

/* Data tables — same family of changes: per-direction header typography,
   row dividers, and hover treatment. Matches the .grid-time-header /
   .provider-row idiom from the previews. */
html[data-ui-style="d2"]  .data-table th,
html[data-ui-style="d2a"] .data-table th,
html[data-ui-style="d2b"] .data-table th,
html[data-ui-style="d2e"] .data-table th { font-weight: 600; letter-spacing: 0; text-transform: none; color: var(--clr-text-muted); }
html[data-ui-style="d2d"] .data-table th { font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--clr-text-muted); }
html[data-ui-style="d3"]  .data-table th { font-weight: 700; letter-spacing: 0; text-transform: none; color: var(--clr-text-muted); }

/* ─────────── .grid-card — the wrapper around any time-grid table ──────────
   Mirrors the .grid-card rule from each preview HTML. We use it on the card
   that wraps both Calendar views (week and daily). The card classes already
   handle border-radius generally; .grid-card amplifies it where the preview
   wants a more pronounced container.

   Specificity: html[data-ui-style="dX"] .card.grid-card → (0,3,1), beats
   the (0,2,1) base .card overlay so this wins over the smaller per-direction
   card radius. */

/* d2 / d2a — airy with surface bg, 18-px radius, clipped */
html[data-ui-style="d2"]  .card.grid-card,
html[data-ui-style="d2a"] .card.grid-card {
    background: var(--clr-surface-card);
    border-radius: 18px;
    overflow: hidden;
}

/* d2b — same shape, no explicit bg (lets the frosted .card backdrop-filter
   continue to show through the bloom gradient) */
html[data-ui-style="d2b"] .card.grid-card {
    border-radius: 18px;
    overflow: hidden;
}

/* d2d — preview is intentionally empty (.grid-card { }) so the card just
   wears the hairline minimal d2d card styling. Restore the explicit border
   so the calendar isn't visually floating in d2d (which doesn't suit the
   "hairline hybrid" intent). */
html[data-ui-style="d2d"] .card.grid-card {
    border: 1px solid var(--hairline);
    border-radius: 6px;
}

/* d2e — floating: padding adjusted per preview (18px 8px 12px). The shadow
   already comes from the per-direction .card rule. */
html[data-ui-style="d2e"] .card.grid-card {
    border-radius: 14px;
    overflow: hidden;
}

/* d3 — soft & rounded: 18-px radius + a soft drop shadow (0,1,3) for the
   "card floats above the page" feel the d3 preview gives the .grid-card */
html[data-ui-style="d3"] .card.grid-card {
    background: var(--clr-surface-card);
    border-radius: 18px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.03);
    overflow: hidden;
}

/* d4 — editorial: border-top hairline only, square corners. Per
   direction-4 preview's literal .grid-card { border-top: 1px solid var(--hairline); } */
html[data-ui-style="d4"] .card.grid-card {
    border: 0;
    border-top: 1px solid var(--hairline);
    border-radius: 0;
    background: transparent;
    box-shadow: none;
}

/* ─────────── Daily-view (.dt-*) per-direction overlays ──────────────────────
   The horizontal daily timeline (CalendarDailyView) carries its own .dt-*
   classes, so the shell/week-grid overlays don't reach it. These rules give it
   the same per-direction event language the design-preview HTML uses for its
   provider strip: status-tinted rounded chips with a coloured left rail (airy /
   soft directions) vs. white editorial chips with a status dot + label (d4).
   Status comes from --ev-color (set on .dt-event.status-*); the staff colour
   keeps its own provider-cell stripe + "Boja osoblja" toggle. Grid dividers
   need no per-rule work — they read from the per-direction hairline tokens. */

/* Airy + soft: status-tinted chip, no border, coloured left rail, dark text. */
html[data-ui-style="d2"]  .dt-event,
html[data-ui-style="d2a"] .dt-event,
html[data-ui-style="d2b"] .dt-event,
html[data-ui-style="d2d"] .dt-event,
html[data-ui-style="d2e"] .dt-event,
html[data-ui-style="d3"]  .dt-event {
    background: color-mix(in srgb, var(--ev-color, var(--clr-status-confirmed)) 10%, white);
    border: 0;
    border-radius: 10px;
    padding: 6px 10px 6px 16px;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
}
html[data-ui-style="d2d"] .dt-event { border-radius: 8px; box-shadow: none; }
html[data-ui-style="d2e"] .dt-event { box-shadow: var(--shadow-sm); }
html[data-ui-style="d3"]  .dt-event {
    border-radius: 14px;
    background: color-mix(in srgb, var(--ev-color, var(--clr-status-confirmed)) 12%, white);
    box-shadow: none;
    padding-left: 17px;
}
html[data-ui-style="d2"]  .dt-event::before,
html[data-ui-style="d2a"] .dt-event::before,
html[data-ui-style="d2b"] .dt-event::before,
html[data-ui-style="d2d"] .dt-event::before,
html[data-ui-style="d2e"] .dt-event::before,
html[data-ui-style="d3"]  .dt-event::before {
    content: '';
    position: absolute;
    top: 8px;
    bottom: 8px;
    left: 6px;
    width: 3px;
    border-radius: 2px;
    background: var(--ev-color, var(--clr-status-confirmed));
}

/* d4 editorial: white chip, hairline-near-black left border, status dot + label. */
html[data-ui-style="d4"] .dt-event {
    background: var(--clr-surface-card);
    border: 0;
    border-left: 1px solid var(--clr-text);
    border-radius: 0;
    box-shadow: none;
    padding: 8px 12px;
}
html[data-ui-style="d4"] .dt-event-status {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--clr-text-secondary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
html[data-ui-style="d4"] .dt-event-status::before {
    content: '';
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--ev-color, var(--clr-status-confirmed));
    flex-shrink: 0;
}
html[data-ui-style="d4"] .dt-event-name { font-size: 14px; }

/* Borderless provider column for the airy / soft directions — the lightened
   hairline tokens soften the remaining grid lines automatically. */
html[data-ui-style="d2"]  .dt-provider-cell,
html[data-ui-style="d2a"] .dt-provider-cell,
html[data-ui-style="d2b"] .dt-provider-cell,
html[data-ui-style="d2e"] .dt-provider-cell,
html[data-ui-style="d3"]  .dt-provider-cell { border-right: 0; }

html[data-ui-style="d2"]  .dt-header-row > .dt-provider-cell,
html[data-ui-style="d2"]  .dt-header-row > .dt-hours,
html[data-ui-style="d2a"] .dt-header-row > .dt-provider-cell,
html[data-ui-style="d2a"] .dt-header-row > .dt-hours,
html[data-ui-style="d2b"] .dt-header-row > .dt-provider-cell,
html[data-ui-style="d2b"] .dt-header-row > .dt-hours,
html[data-ui-style="d2e"] .dt-header-row > .dt-provider-cell,
html[data-ui-style="d2e"] .dt-header-row > .dt-hours,
html[data-ui-style="d3"]  .dt-header-row > .dt-provider-cell,
html[data-ui-style="d3"]  .dt-header-row > .dt-hours { border-bottom: 1px solid var(--hairline); }

/* Column-header typography per direction (mirrors the week grid idiom). */
html[data-ui-style="d2"]  .dt-provider-head,
html[data-ui-style="d2a"] .dt-provider-head,
html[data-ui-style="d2b"] .dt-provider-head,
html[data-ui-style="d2e"] .dt-provider-head { font-weight: 600; letter-spacing: 0.04em; }
html[data-ui-style="d4"]  .dt-provider-head { font-weight: 700; letter-spacing: 0.12em; }

/* Day-pill shape per direction (base is a filled pill that suits the airy set). */
html[data-ui-style="d4"]  .day-pill { border-radius: 2px; }
html[data-ui-style="d4"]  .day-pill.is-selected,
html[data-ui-style="d4"]  .day-pill.is-selected:hover {
    background: transparent;
    color: var(--accent);
    border-color: var(--hairline-strong);
    box-shadow: inset 0 -2px 0 var(--accent);
}
html[data-ui-style="d2d"] .day-pill { border-radius: 8px; }
html[data-ui-style="d3"]  .day-pill { background: transparent; border-color: transparent; }
html[data-ui-style="d3"]  .day-pill:hover { background: var(--clr-surface); }

