/* ==========================================================================
   FitSystem — Components
   --------------------------------------------------------------------------
   Each block ports one widget from the Flutter app. The mobile source is cited
   so the two implementations stay traceable when either side changes.

   Requires fitsystem.css (tokens) to be loaded first.
   ========================================================================== */


/* ==========================================================================
   App shell — the phone frame (routing/app_router.dart _HomeShell)
   --------------------------------------------------------------------------
   A single centred column, full viewport height, that reproduces the mobile
   app's proportions at every width: app bar on top, a scrolling body, a fixed
   bottom tab bar. On desktop the column carries hairline "device" edges so it
   reads as a phone held in the middle of the screen.
   ========================================================================== */
:root {
    --fs-app-width: 460px;
    --fs-appbar-h: 56px;
    --fs-bottomnav-h: 64px;
    --fs-sidenav-w: 232px;
    --fs-sidenav-w-collapsed: 68px;
    --fs-content-narrow: 520px;   /* the desktop "mobile column" width for logging pages */
}

/* Collapsed rail: swap the sidebar width token so both the grid column and the
   FAB offset (which key off --fs-sidenav-w) adapt together. */
html.nav-collapsed { --fs-sidenav-w: var(--fs-sidenav-w-collapsed); }

.fs-app {
    width: 100%;
    max-width: var(--fs-app-width);
    margin-inline: auto;
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
    position: relative;
    background-color: var(--fs-bg);
}

/* Device edges once the viewport is wider than the column */
@media (min-width: 480px) {
    .fs-app {
        border-inline: 1px solid var(--fs-border);
    }
}

/* The scrolling content region. Bottom padding clears the tab bar + a FAB.
   `container-type: inline-size` makes this a query container named `app`, so
   content styling can respond to the *column* width (~460px) rather than the
   browser viewport. This is what keeps the phone layout intact on desktop,
   where the viewport is wide but the column is narrow — see the `@container
   app` blocks in fitsystem-workouts.css. */
.fs-app-body {
    flex: 1 1 auto;
    padding: 0.875rem 0.875rem calc(var(--fs-bottomnav-h) + 1.5rem);
    container: app / inline-size;
}

.fs-app-body > .container,
.fs-app-body > .container-fluid {
    padding-inline: 0;
    max-width: 100%;
}

/* Bootstrap's responsive grid keys off the viewport, which no longer matches
   the column. Inside the phone frame everything is narrow, so responsive
   columns always stack — exactly the mobile single-column behaviour. Base
   `.col` / `.col-6` (intentional at every width) are left alone.

   Scoped to `:not(.fs-app--wide)` so the wide desktop shell gets Bootstrap's
   real responsive grid back (it still stacks below 768px on a phone, which is
   the mobile behaviour we want there anyway). */
.fs-app:not(.fs-app--wide) [class*="col-sm-"],
.fs-app:not(.fs-app--wide) [class*="col-md-"],
.fs-app:not(.fs-app--wide) [class*="col-lg-"],
.fs-app:not(.fs-app--wide) [class*="col-xl-"] {
    flex: 0 0 100% !important;
    max-width: 100% !important;
}

/* Viewport display-toggles (`d-none d-md-block` etc.) also mis-fire in the
   narrow column: the app is always "mobile", so show the mobile side and hide
   the desktop side regardless of viewport. Wide pages opt out (see above). */
.fs-app:not(.fs-app--wide) .d-none.d-sm-block,
.fs-app:not(.fs-app--wide) .d-none.d-md-block,
.fs-app:not(.fs-app--wide) .d-none.d-lg-block,
.fs-app:not(.fs-app--wide) .d-none.d-sm-flex,
.fs-app:not(.fs-app--wide) .d-none.d-md-flex,
.fs-app:not(.fs-app--wide) .d-none.d-lg-flex { display: none !important; }

.fs-app:not(.fs-app--wide) .d-sm-none,
.fs-app:not(.fs-app--wide) .d-md-none,
.fs-app:not(.fs-app--wide) .d-lg-none { display: revert !important; }

/* Auth pages (login/register) have no bottom nav — reclaim that space. */
.fs-app--plain .fs-app-body {
    padding-bottom: 1.5rem;
    display: flex;
    flex-direction: column;
    justify-content: center;
}


/* ==========================================================================
   App bar — appBarTheme (app_theme.dart:103-114)
   --------------------------------------------------------------------------
   Per-page header: optional back arrow · title · actions. Sticky, flush on
   the page background, hairline underneath. No persistent logo.
   ========================================================================== */
.fs-appbar {
    position: sticky;
    top: 0;
    z-index: 1030;
    display: flex;
    align-items: center;
    gap: 0.25rem;
    min-height: var(--fs-appbar-h);
    padding: 0.5rem 0.5rem 0.5rem 0.375rem;
    background-color: var(--fs-bg);
    border-bottom: 1px solid var(--fs-border);
}

.fs-appbar-back {
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    background: transparent;
    color: var(--fs-text);
    border-radius: var(--fs-radius-pill);
    font-size: 1.05rem;
    cursor: pointer;
    transition: background-color var(--fs-transition);
}

.fs-appbar-back:hover { background-color: var(--fs-hover-overlay); color: var(--fs-text); }

.fs-appbar-title {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 1.2rem;
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--fs-text);
    padding-inline: 0.375rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* No back arrow ⇒ align the title with the body's content padding. */
.fs-appbar--root .fs-appbar-title { padding-left: 0.5rem; }

/* Right-side actions (bell, options menu). Reset list semantics. */
.fs-appbar-actions {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 0.125rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.fs-appbar-actions > li { list-style: none; }

/* Icon action button — bell, options ⋮ */
.fs-appbar-actions .nav-link,
.fs-appbar-action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0;
    color: var(--fs-text-secondary) !important;
    border-radius: var(--fs-radius-pill);
    font-size: 1.05rem;
    background: transparent;
    border: none;
    cursor: pointer;
    transition: color var(--fs-transition), background-color var(--fs-transition);
}

.fs-appbar-actions .nav-link:hover,
.fs-appbar-action:hover {
    color: var(--fs-text) !important;
    background-color: var(--fs-hover-overlay);
}

/* Logo, shown only on the unauthenticated (plain) shell */
.fs-appbar-brand { display: inline-flex; align-items: center; padding: 0.25rem 0.5rem; }
.fs-appbar-brand img { height: 30px; }
.fs-logo { display: none; }
html[data-theme="dark"] .fs-logo--dark { display: block; }
html[data-theme="light"] .fs-logo--light { display: block; }

.theme-toggle {
    cursor: pointer;
    display: inline-flex !important;
    align-items: center;
    gap: 0.375rem;
    color: var(--fs-text-secondary) !important;
    transition: color var(--fs-transition);
}

.theme-toggle:hover { color: var(--fs-text) !important; }
.theme-toggle .theme-toggle-light { display: none; }
html[data-theme="dark"] .theme-toggle .theme-toggle-dark { display: none; }
html[data-theme="dark"] .theme-toggle .theme-toggle-light { display: inline; }


/* ==========================================================================
   Bottom tab bar — NavigationBar (app_theme.dart:182-200)
   --------------------------------------------------------------------------
   Three destinations pinned to the bottom of the phone column. The active tab
   gets an accent-tinted pill behind its icon plus accent label — the mobile
   NavigationBar indicator.
   ========================================================================== */
.fs-bottom-nav {
    position: sticky;
    bottom: 0;
    z-index: 1030;
    display: flex;
    align-items: stretch;
    height: var(--fs-bottomnav-h);
    padding-bottom: env(safe-area-inset-bottom);
    background-color: var(--fs-surface);
    border-top: 1px solid var(--fs-border);
}

.fs-bottom-nav-item {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    padding-top: 6px;
    color: var(--fs-text-secondary);
    text-decoration: none;
    font-size: 0.6875rem;
    font-weight: 500;
    transition: color var(--fs-transition);
}

.fs-bottom-nav-item:hover { color: var(--fs-text); }

.fs-bottom-nav-item .fs-bottom-nav-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 30px;
    border-radius: var(--fs-radius-pill);
    font-size: 1.05rem;
    transition: background-color var(--fs-transition);
}

.fs-bottom-nav-item.is-active { color: var(--fs-accent); font-weight: 600; }
.fs-bottom-nav-item.is-active .fs-bottom-nav-icon {
    background-color: var(--fs-accent-tint);
    color: var(--fs-accent);
}


/* ==========================================================================
   Desktop app shell + left sidebar
   --------------------------------------------------------------------------
   Navigation is device-driven: at >=900px every authenticated page gets the
   left sidebar and loses the bottom tab bar; below that it's the phone column
   with the bottom bar. Content width is page-driven: logging/tracking pages
   keep the mobile centred column, while admin pages (ViewData["Shell"]="wide"
   -> `.fs-app--wide`) get a true wide Bootstrap layout for heavy data entry.
   `.fs-app--plain` (login/register, unauthenticated) is deliberately excluded.
   ========================================================================== */
.fs-sidenav { display: none; }        /* hidden on phone (default) */

@media (min-width: 900px) {
    /* The desktop shell — applies to every authenticated page */
    .fs-app:not(.fs-app--plain) {
        max-width: none;              /* was 460px — fill the viewport */
        margin-inline: 0;
        display: grid;
        grid-template-columns: var(--fs-sidenav-w) minmax(0, 1fr);
        grid-template-rows: auto 1fr;   /* app bar = content height, body fills */
        align-content: start;
        grid-template-areas:
            "sidenav appbar"
            "sidenav body";
        border-inline: none;          /* drop the phone "device edges" */
    }

    .fs-app:not(.fs-app--plain) .fs-appbar     { grid-area: appbar; }
    .fs-app:not(.fs-app--plain) .fs-app-body   { grid-area: body; }
    .fs-app:not(.fs-app--plain) .fs-bottom-nav { display: none; }   /* never on desktop */
    .fs-section-menu { display: none; }   /* phone-only: the nested sidebar covers these links on desktop */

    .fs-app:not(.fs-app--plain) .fs-sidenav {
        grid-area: sidenav;
        display: flex;
        flex-direction: column;
        position: sticky;
        top: 0;
        height: 100dvh;
        padding: 1rem 0.75rem;
        background-color: var(--fs-surface);
        border-right: 1px solid var(--fs-border);
        overflow-y: auto;
    }

    /* Content width by page type */
    .fs-app-body { padding: 1.5rem 2rem 2rem; }

    /* Logging/tracking: keep the mobile centred column.
       NB: `.fs-app-body` is a container-type:inline-size query container, so it
       must be given a *definite* width — `max-width` + auto margins leaves it
       with no resolvable inline size and containment collapses it. `min()` keeps
       it definite while still shrinking on narrower main areas. */
    .fs-app:not(.fs-app--wide) .fs-app-body {
        width: min(100%, calc(var(--fs-content-narrow) + 4rem));   /* content + h-padding */
        margin-inline: auto;
    }
    /* Admin: true wide Bootstrap, capped for sanity on ultrawide */
    .fs-app--wide .fs-app-body {
        width: min(100%, 1320px);
        margin-inline: auto;
    }

    /* Collapsed rail — icons only. The width token is already swapped on
       html.nav-collapsed; here we hide the labels and centre the icons. */
    html.nav-collapsed .fs-sidenav-label,
    html.nav-collapsed .fs-sidenav-brand-logo,
    html.nav-collapsed .fs-sidenav .theme-toggle-text { display: none; }

    html.nav-collapsed .fs-sidenav { padding-inline: 0.5rem; }
    html.nav-collapsed .fs-sidenav-brand { justify-content: center; padding-inline: 0; }
    html.nav-collapsed .fs-sidenav-item,
    html.nav-collapsed .fs-sidenav .theme-toggle {
        justify-content: center;
        gap: 0;
        padding-inline: 0;
    }
    html.nav-collapsed .fs-sidenav-footer form { display: flex; justify-content: center; }

    /* Collapsed rail has no room for accordions: drop the group headers and
       show every child as a flat, centred icon regardless of open state. */
    html.nav-collapsed .fs-sidenav-group-header { display: none; }
    html.nav-collapsed .fs-sidenav-group-items { display: flex !important; }
    html.nav-collapsed .fs-sidenav-subitem { padding-left: 0; }
}

.fs-sidenav-brand {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    height: var(--fs-appbar-h);
    padding: 0 0.25rem 0.75rem 0.5rem;
    margin-bottom: 0.5rem;
    border-bottom: 1px solid var(--fs-border);
}
.fs-sidenav-brand .fs-logo { height: 26px; width: auto; }
.fs-sidenav-brand-logo { display: inline-flex; align-items: center; }

.fs-sidenav-collapse-btn {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border: 0;
    background: transparent;
    border-radius: var(--fs-radius-sm);
    color: var(--fs-text-secondary);
    cursor: pointer;
    transition: color var(--fs-transition), background-color var(--fs-transition);
}
.fs-sidenav-collapse-btn:hover {
    color: var(--fs-text);
    background-color: var(--fs-hover-overlay);
}
/* The chevron flips to point the other way once collapsed. */
html.nav-collapsed .fs-sidenav-collapse-btn i { transform: rotate(180deg); }

.fs-sidenav-nav {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.fs-sidenav-item {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    width: 100%;
    padding: 0.5rem 0.625rem;
    border: 0;
    background: transparent;
    border-radius: var(--fs-radius-sm);
    color: var(--fs-text-secondary);
    font-size: 0.9375rem;
    font-weight: 500;
    text-decoration: none;
    text-align: left;
    cursor: pointer;
    transition: color var(--fs-transition), background-color var(--fs-transition);
}
.fs-sidenav-item:hover {
    color: var(--fs-text);
    background-color: var(--fs-hover-overlay);
}

.fs-sidenav-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.5rem;
    font-size: 1rem;
    flex-shrink: 0;
}

.fs-sidenav-label { white-space: nowrap; overflow: hidden; }

.fs-sidenav-item.is-active {
    color: var(--fs-accent);
    font-weight: 600;
    background-color: var(--fs-accent-tint);
}

/* Collapsible groups (Meals, Macros, Manage). The header is a plain
   fs-sidenav-item that toggles the group; children live in -group-items,
   hidden until the group carries .is-open. */
.fs-sidenav-chevron {
    margin-left: auto;
    font-size: 0.75rem;
    flex-shrink: 0;
    transition: transform var(--fs-transition);
}
.fs-sidenav-group.is-open > .fs-sidenav-group-header .fs-sidenav-chevron {
    transform: rotate(90deg);
}
.fs-sidenav-group-items {
    display: none;
    flex-direction: column;
    gap: 2px;
    margin-top: 2px;
}
.fs-sidenav-group.is-open > .fs-sidenav-group-items { display: flex; }
.fs-sidenav-subitem { padding-left: 2rem; }
.fs-sidenav-subitem .fs-sidenav-icon { font-size: 0.9rem; }

.fs-sidenav-divider {
    border: 0;
    border-top: 1px solid var(--fs-border-soft);
    margin: 0.5rem 0.25rem;
}
html.nav-collapsed .fs-sidenav-divider { margin-inline: 0.25rem; }

.fs-sidenav-footer {
    margin-top: auto;
    padding-top: 0.75rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    border-top: 1px solid var(--fs-border);
}
.fs-sidenav-footer form { margin: 0; }
.fs-sidenav-footer .theme-toggle { width: 100%; justify-content: flex-start; }
.fs-sidenav-logout { color: var(--fs-danger); }
.fs-sidenav-logout:hover {
    color: var(--fs-danger);
    background-color: var(--fs-danger-tint);
}


/* ==========================================================================
   Card — AppCard (shared/widgets/app_card.dart)
   --------------------------------------------------------------------------
   Surface fill, 1px hairline border, 16px radius, elevation 0. No shadow,
   no dark header bar.
   ========================================================================== */
.card,
.fs-card {
    background-color: var(--fs-surface);
    border: 1px solid var(--fs-border);
    border-radius: var(--fs-radius-card);
    box-shadow: none;
    margin-bottom: 0.75rem;
    overflow: hidden;
}

.card-body {
    padding: 1rem;
    color: var(--fs-text);
}

@media (min-width: 576px) {
    .card-body { padding: 1.25rem; }
}

/* A tappable card — the InkWell variant of AppCard */
.fs-card--tappable,
a.fs-card {
    display: block;
    color: inherit;
    cursor: pointer;
    transition: background-color var(--fs-transition), border-color var(--fs-transition);
}

.fs-card--tappable:hover,
a.fs-card:hover {
    background-color: var(--fs-elevated);
    border-color: var(--fs-input-border);
    color: inherit;
}

/* The accent stripe stays as a way to mark the page's primary card, but as a
   left rule rather than a top bar — quieter, and survives the rounded corner. */
.card-accent {
    border-left: 3px solid var(--fs-accent);
}


/* ==========================================================================
   Section header — SectionHeader (shared/widgets/section_header.dart)
   --------------------------------------------------------------------------
   Uppercase, 700 weight, 0.8px tracking, secondary colour. This is what
   replaces the near-black .card-header slab from the old workouts.css.
   ========================================================================== */
.card-header,
.fs-section-label {
    background: transparent;
    border-bottom: 1px solid var(--fs-border);
    color: var(--fs-text-secondary);
    font-size: 0.6875rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.8px;
    padding: 0.75rem 1rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.card-header h1, .card-header h2, .card-header h3,
.card-header h4, .card-header h5, .card-header h6 {
    color: var(--fs-text-secondary);
    font-size: 0.6875rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.8px;
    margin: 0;
}

.card-header i {
    color: var(--fs-accent);
    font-size: 0.8125rem;
}

/* Standalone label above a group of cards, outside any card */
.fs-section-label {
    border-bottom: none;
    padding: 1.25rem 0.25rem 0.5rem;
}

/* Buttons inside a header row shouldn't inherit the uppercase label styling */
.card-header .btn,
.fs-section-label .btn {
    text-transform: none;
    letter-spacing: normal;
    font-size: 0.8125rem;
}

.card-header .btn-outline-light {
    color: var(--fs-text-secondary) !important;
    border: 1px solid var(--fs-border) !important;
    background: transparent !important;
}

.card-header .btn-outline-light:hover,
.card-header .btn-outline-light:focus {
    color: var(--fs-text) !important;
    background: var(--fs-hover-overlay) !important;
    border-color: var(--fs-input-border) !important;
}


/* ==========================================================================
   Tile — the mobile ListTile row (profile_screen.dart:86-101)
   --------------------------------------------------------------------------
   40px rounded-12 leading icon on an accent tint, title, subtitle, chevron.
   Applied to .list-group-item-action so existing roster/menu lists inherit it.
   ========================================================================== */
.list-group {
    border-radius: var(--fs-radius-card);
}

.list-group-item {
    background-color: var(--fs-surface);
    border-color: var(--fs-border);
    color: var(--fs-text);
    padding: 0.875rem 1rem;
}

.list-group-flush > .list-group-item {
    border-inline: none;
}

.list-group-item-action,
.fs-tile {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    color: var(--fs-text);
    text-decoration: none;
    transition: background-color var(--fs-transition);
}

.list-group-item-action:hover,
.list-group-item-action:focus,
.fs-tile:hover,
.fs-tile:focus {
    background-color: var(--fs-hover-overlay);
    color: var(--fs-text);
}

/* Leading icon square */
.fs-tile-icon {
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--fs-radius-input);
    background-color: var(--fs-accent-tint);
    color: var(--fs-accent);
    font-size: 0.9375rem;
    overflow: hidden;
}

.fs-tile-icon img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Neutral variant for avatars without a brand association */
.fs-tile-icon--neutral {
    background-color: var(--fs-elevated);
    color: var(--fs-text-secondary);
}

/* The tile parts are markup-agnostic — they're often <span>s inside an <a>,
   so display has to be stated rather than inherited from a block element. */
.fs-tile-body {
    display: block;
    flex: 1;
    min-width: 0;
}

.fs-tile-title {
    display: block;
    font-size: 0.9375rem;
    font-weight: 600;
    color: var(--fs-text);
    line-height: 1.3;
    overflow: hidden;
    text-overflow: ellipsis;
}

.fs-tile-subtitle {
    display: block;
    font-size: 0.8125rem;
    color: var(--fs-text-secondary);
    line-height: 1.35;
    margin-top: 1px;
}

.fs-tile-trailing {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    color: var(--fs-text-muted);
    font-size: 0.8125rem;
}


/* ==========================================================================
   Stat tile — StatTile (shared/widgets/stat_tile.dart)
   --------------------------------------------------------------------------
   Big 700-weight value over a small uppercase label.
   ========================================================================== */
.fs-stat-row {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    gap: 0.75rem;
    align-items: start;
}

.fs-stat {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.fs-stat--center {
    align-items: center;
    text-align: center;
}

.fs-stat-value {
    font-size: 1.375rem;
    font-weight: 700;
    line-height: 1.1;
    color: var(--fs-text);
    letter-spacing: -0.02em;
}

.fs-stat-value.is-accent { color: var(--fs-accent); }

.fs-stat-label {
    font-size: 0.6875rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--fs-text-secondary);
}

/* A card that is nothing but a stat — used on the dashboards */
.fs-stat-card {
    background-color: var(--fs-surface);
    border: 1px solid var(--fs-border);
    border-radius: var(--fs-radius-card);
    padding: 0.875rem 1rem;
    display: flex;
    flex-direction: column;
    gap: 2px;
    align-items: center;
    text-align: center;
}

.fs-stat-card i {
    color: var(--fs-accent);
    font-size: 1rem;
    margin-bottom: 0.25rem;
}


/* ==========================================================================
   Pill chip — PillChip (shared/widgets/pill_chip.dart)
   --------------------------------------------------------------------------
   Fully rounded, tinted fill at ~14% of the hue, 600-weight small label.
   Bootstrap's .badge is remapped onto it so existing badges convert for free.
   ========================================================================== */
.badge,
.fs-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.25rem 0.625rem;
    border-radius: var(--fs-radius-pill);
    font-size: 0.6875rem;
    font-weight: 600;
    line-height: 1.4;
    letter-spacing: 0;
    background-color: var(--fs-elevated);
    color: var(--fs-text-secondary);
}

.badge i,
.fs-chip i { font-size: 0.6875rem; }

/* Tinted variants. Bootstrap's .bg-* utilities land here because the badge
   markup across the app already uses them. */
.badge.bg-primary,
.fs-chip--accent {
    background-color: var(--fs-accent-tint) !important;
    color: var(--fs-accent) !important;
}

.badge.bg-success,
.fs-chip--success {
    background-color: var(--fs-success-tint) !important;
    color: var(--fs-success) !important;
}

/* Solid accent fill (e.g. an "Active" state that needs stronger emphasis than
   the tinted variants). Pairs the accent background with on-accent text so it
   stays readable in both themes — a plain .badge would keep the grey base text. */
.badge.bg-accent-solid {
    background-color: var(--fs-accent) !important;
    color: var(--fs-on-accent) !important;
}

.badge.bg-warning,
.badge.bg-warning.text-dark,
.fs-chip--warning {
    background-color: var(--fs-warning-tint) !important;
    color: var(--fs-warning) !important;
}

.badge.bg-danger,
.fs-chip--danger {
    background-color: var(--fs-danger-tint) !important;
    color: var(--fs-danger) !important;
}

.badge.bg-info,
.fs-chip--info {
    background-color: var(--fs-info-tint) !important;
    color: var(--fs-info) !important;
}

.badge.bg-secondary,
.badge.bg-light,
.badge.bg-dark,
.fs-badge-muted {
    background-color: var(--fs-elevated) !important;
    color: var(--fs-text) !important;
    border: 1px solid var(--fs-border);
}


/* ==========================================================================
   Live workout reaction bubbles — ephemeral pop-ups from friends "cheering
   on" an in-progress workout (see Workouts/Edit.cshtml + WorkoutReactionHub).
   Fixed host, top-centered, bubbles float up and fade like a toast but
   friendlier — closer to Apple Fitness / Peloton high-fives.
   ========================================================================== */
.fs-reaction-host {
    position: fixed;
    top: 12px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 1080;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    pointer-events: none;
    max-width: calc(100vw - 24px);
}

.fs-reaction-bubble {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    background-color: var(--fs-surface);
    border: 1px solid var(--fs-border);
    border-radius: var(--fs-radius-pill);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
    padding: 0.5rem 1rem;
    animation: fs-reaction-in 0.3s ease-out;
    transition: opacity 0.4s ease, transform 0.4s ease;
}

.fs-reaction-bubble--out {
    opacity: 0;
    transform: translateY(-8px);
}

.fs-reaction-emoji {
    font-size: 1.375rem;
    line-height: 1;
}

.fs-reaction-text {
    font-size: 0.875rem;
    color: var(--fs-text);
    white-space: nowrap;
}

@keyframes fs-reaction-in {
    from {
        opacity: 0;
        transform: translateY(-12px) scale(0.9);
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}


/* ==========================================================================
   Buttons — filledButtonTheme / outlinedButtonTheme / textButtonTheme
   (app_theme.dart:149-176)
   ========================================================================== */
.btn {
    --bs-btn-box-shadow: none;
    border-radius: var(--fs-radius-btn);
    font-weight: 600;
    font-size: 0.875rem;
    letter-spacing: 0;
    padding: 0.5rem 1rem;
    border-width: 1px;
    transition: background-color var(--fs-transition), border-color var(--fs-transition), color var(--fs-transition);
}

.btn:focus-visible {
    box-shadow: 0 0 0 3px var(--fs-accent-tint);
}

/* Filled */
.btn-primary,
.btn-workout-primary {
    background-color: var(--fs-accent);
    border-color: var(--fs-accent);
    color: var(--fs-on-accent);
}

.btn-primary:hover,
.btn-primary:focus,
.btn-primary:active,
.btn-workout-primary:hover,
.btn-workout-primary:focus {
    background-color: var(--fs-accent-hover);
    border-color: var(--fs-accent-hover);
    color: var(--fs-on-accent);
}

.btn-primary:disabled,
.btn-primary.disabled {
    background-color: var(--fs-accent);
    border-color: var(--fs-accent);
    color: var(--fs-on-accent);
    opacity: 0.45;
}

.btn-success {
    background-color: var(--fs-success);
    border-color: var(--fs-success);
    color: #fff;
}

.btn-success:hover,
.btn-success:focus {
    background-color: #12833B;
    border-color: #12833B;
    color: #fff;
}

.btn-danger {
    background-color: var(--fs-danger);
    border-color: var(--fs-danger);
    color: #fff;
}

.btn-danger:hover,
.btn-danger:focus {
    background-color: #B91C1C;
    border-color: #B91C1C;
    color: #fff;
}

/* Outlined — transparent fill, hairline border, primary text */
.btn-outline-secondary,
.btn-secondary,
.btn-workout-secondary,
.btn-workout-outline,
.btn-outline-light,
.btn-light {
    background-color: transparent;
    border: 1px solid var(--fs-border);
    color: var(--fs-text);
}

.btn-outline-secondary:hover,
.btn-outline-secondary:focus,
.btn-secondary:hover,
.btn-secondary:focus,
.btn-workout-secondary:hover,
.btn-workout-outline:hover,
.btn-outline-light:hover,
.btn-light:hover {
    background-color: var(--fs-hover-overlay);
    border-color: var(--fs-input-border);
    color: var(--fs-text);
}

/* Outlined, accent — for the secondary call to action */
.btn-outline-primary {
    background-color: transparent;
    border: 1px solid var(--fs-accent);
    color: var(--fs-accent);
}

.btn-outline-primary:hover,
.btn-outline-primary:focus {
    background-color: var(--fs-accent-tint);
    border-color: var(--fs-accent);
    color: var(--fs-accent);
}

.btn-outline-danger {
    background-color: transparent;
    border: 1px solid var(--fs-danger);
    color: var(--fs-danger);
}

.btn-outline-danger:hover,
.btn-outline-danger:focus {
    background-color: var(--fs-danger-tint);
    border-color: var(--fs-danger);
    color: var(--fs-danger);
}

/* Text button */
.btn-link {
    color: var(--fs-accent);
    font-weight: 600;
    text-decoration: none;
    padding: 0.375rem 0.5rem;
}

.btn-link:hover { color: var(--fs-accent-hover); }

/* Sizes */
.btn-sm {
    font-size: 0.8125rem;
    padding: 0.375rem 0.75rem;
    border-radius: var(--fs-radius-sm);
}

.btn-lg {
    font-size: 0.9375rem;
    padding: 0.75rem 1.25rem;
}

/* Block button — FilledButton's minimumSize: Size.fromHeight(50) */
.fs-btn-block,
.btn.w-100:not(.btn-sm) {
    min-height: 50px;
    font-size: 0.9375rem;
}

/* Icon-only square button */
.btn-icon {
    width: 36px;
    height: 36px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--fs-radius-sm);
}

.btn-group > .btn:first-child { border-start-start-radius: var(--fs-radius-btn); border-end-start-radius: var(--fs-radius-btn); }
.btn-group > .btn:last-child  { border-start-end-radius: var(--fs-radius-btn);   border-end-end-radius: var(--fs-radius-btn); }

/* Analytics buttons — deliberately the neutral secondary treatment (no blue).
   The --fs-analytics token itself is kept for chart accents (.text-analytics). */
.btn-analytics,
.btn-outline-analytics {
    background-color: transparent;
    border: 1px solid var(--fs-border);
    color: var(--fs-text);
}

.btn-analytics:hover,
.btn-analytics:focus,
.btn-outline-analytics:hover,
.btn-outline-analytics:focus {
    background-color: var(--fs-hover-overlay);
    border-color: var(--fs-input-border);
    color: var(--fs-text);
}

.text-analytics { color: var(--fs-analytics) !important; }


/* ==========================================================================
   Floating action button — FloatingActionButton.extended
   (diary_screen.dart:105-109)
   --------------------------------------------------------------------------
   The "＋ Add food" / "＋ Start workout" pill. Anchored to the bottom-right of
   the phone column, floating just above the tab bar.
   ========================================================================== */
.fs-fab {
    position: fixed;
    right: max(1rem, calc(50vw - var(--fs-app-width) / 2 + 1rem));
    bottom: calc(var(--fs-bottomnav-h) + 1rem + env(safe-area-inset-bottom));
    z-index: 1035;

    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.875rem 1.25rem;
    border: none;
    border-radius: var(--fs-radius-pill);

    background-color: var(--fs-accent);
    color: var(--fs-on-accent);
    font-size: 0.9375rem;
    font-weight: 600;
    line-height: 1;
    text-decoration: none;

    /* The one place elevation is warranted — it floats over content. */
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.28);
    transition: background-color var(--fs-transition), transform var(--fs-transition);
}

.fs-fab:hover,
.fs-fab:focus {
    background-color: var(--fs-accent-hover);
    color: var(--fs-on-accent);
    transform: translateY(-1px);
}

.fs-fab i { font-size: 0.875rem; }

/* On desktop there's no bottom nav and the logging column is centred in the
   main area (right of the sidebar); anchor the FAB to that column's edge. */
@media (min-width: 900px) {
    .fs-app:not(.fs-app--plain) .fs-fab {
        right: max(1.5rem, calc((100vw - var(--fs-sidenav-w) - var(--fs-content-narrow)) / 2 + 1rem));
        bottom: 1.5rem;
    }
}


/* ==========================================================================
   Forms — inputDecorationTheme (app_theme.dart:129-148)
   --------------------------------------------------------------------------
   filled: true on the elevated surface, 12px radius, 2px accent focus border.
   ========================================================================== */
.form-label {
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--fs-text-secondary);
    margin-bottom: 0.375rem;
}

.form-control,
.form-select,
textarea.form-control {
    background-color: var(--fs-elevated);
    border: 1px solid var(--fs-input-border);
    border-radius: var(--fs-radius-input);
    color: var(--fs-text);
    padding: 0.75rem 0.875rem;
    font-size: 0.9375rem;
    box-shadow: none;
}

.form-control:focus,
.form-select:focus {
    background-color: var(--fs-elevated);
    border-color: var(--fs-accent);
    border-width: 2px;
    padding: calc(0.75rem - 1px) calc(0.875rem - 1px);
    color: var(--fs-text);
    box-shadow: none;
    outline: none;
}

.form-control::placeholder { color: var(--fs-text-muted); }

.form-control:disabled,
.form-control[readonly],
.form-select:disabled {
    background-color: var(--fs-recessed);
    color: var(--fs-text-secondary);
    border-color: var(--fs-border);
}

.form-select {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23A8A8A4' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");
}

html[data-theme="light"] .form-select {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23737373' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");
}

/* Floating labels need their own metrics — Bootstrap positions the label
   against a fixed input height, so the padding override above has to be
   restated here rather than inherited. */
.form-floating > .form-control,
.form-floating > .form-select {
    height: 3.5rem;
    min-height: 3.5rem;
    padding: 1rem 0.875rem 0.375rem;
    line-height: 1.25;
}

.form-floating > .form-control:focus,
.form-floating > .form-select:focus {
    padding: calc(1rem - 1px) calc(0.875rem - 1px) calc(0.375rem - 1px);
}

.form-floating > label {
    padding: 1rem 0.875rem;
    color: var(--fs-text-muted);
    border: none;
}

.form-floating > .form-control:focus ~ label,
.form-floating > .form-control:not(:placeholder-shown) ~ label,
.form-floating > .form-select ~ label {
    color: var(--fs-text-secondary);
    transform: scale(0.8) translateY(-0.5rem) translateX(0.15rem);
    opacity: 1;
}

.form-floating > .form-control:focus ~ label::after,
.form-floating > .form-control:not(:placeholder-shown) ~ label::after,
.form-floating > .form-select ~ label::after {
    background: transparent;
}

.form-control-sm,
.form-select-sm {
    padding: 0.5rem 0.625rem;
    font-size: 0.8125rem;
    border-radius: var(--fs-radius-sm);
}

/* Prevent iOS zoom-on-focus */
@media (max-width: 767.98px) {
    .form-control,
    .form-select,
    textarea.form-control { font-size: 16px; }
}

.input-group > .form-control,
.input-group > .form-select { border-radius: var(--fs-radius-input); }

.input-group > :not(:first-child):not(.dropdown-menu) {
    border-start-start-radius: 0;
    border-end-start-radius: 0;
}

.input-group > :not(:last-child) {
    border-start-end-radius: 0;
    border-end-end-radius: 0;
}

.input-group-text {
    background-color: var(--fs-recessed);
    border: 1px solid var(--fs-input-border);
    border-radius: var(--fs-radius-input);
    color: var(--fs-text-secondary);
    font-size: 0.875rem;
}

/* Checks, radios & switches */
.form-check-input {
    background-color: var(--fs-elevated);
    border: 1px solid var(--fs-input-border);
}

.form-check-input:checked {
    background-color: var(--fs-accent);
    border-color: var(--fs-accent);
}

.form-check-input:focus {
    border-color: var(--fs-accent);
    box-shadow: 0 0 0 3px var(--fs-accent-tint);
}

.form-check-label { color: var(--fs-text); }

/* The "choice card" pattern used across the macro calculators: a whole
   bordered row that acts as one large tap target. */
.activity-levels .form-check,
.form-check.fs-choice {
    background-color: var(--fs-surface);
    border: 1px solid var(--fs-border);
    border-radius: var(--fs-radius-input);
    padding: 0.875rem 0.875rem 0.875rem 2.5rem;
    margin-bottom: 0.5rem;
    transition: background-color var(--fs-transition), border-color var(--fs-transition);
}

.activity-levels .form-check:hover,
.form-check.fs-choice:hover {
    background-color: var(--fs-elevated);
    border-color: var(--fs-input-border);
}

.activity-levels .form-check:has(.form-check-input:checked),
.form-check.fs-choice:has(.form-check-input:checked) {
    background-color: var(--fs-accent-subtle);
    border-color: var(--fs-accent);
}

.form-check-label small { color: var(--fs-text-secondary); }

/* Range slider */
.form-range::-webkit-slider-runnable-track { background-color: var(--fs-border); height: 6px; border-radius: var(--fs-radius-pill); }
.form-range::-moz-range-track { background-color: var(--fs-border); height: 6px; border-radius: var(--fs-radius-pill); }
.form-range::-webkit-slider-thumb { background-color: var(--fs-accent); }
.form-range::-moz-range-thumb { background-color: var(--fs-accent); }

/* Validation */
.is-invalid,
.form-control.is-invalid,
.form-select.is-invalid {
    border-color: var(--fs-danger) !important;
    background-color: var(--fs-danger-tint) !important;
}

.invalid-feedback,
.text-danger,
.field-validation-error { color: var(--fs-danger) !important; }

.activity-levels.is-invalid {
    border: 1px solid var(--fs-danger);
    border-radius: var(--fs-radius-input);
    padding: 0.5rem;
    background: transparent !important;
}


/* ==========================================================================
   Dropdown — PopupMenuButton (diary_screen.dart:116-140)
   --------------------------------------------------------------------------
   The labelled options menu that replaced rows of bare icons on mobile.
   ========================================================================== */
.dropdown-menu {
    background-color: var(--fs-surface);
    border: 1px solid var(--fs-border);
    border-radius: var(--fs-radius-input);
    box-shadow: none;
    padding: 0.375rem;
    min-width: 15rem;
}

.dropdown-item {
    border-radius: var(--fs-radius-sm);
    color: var(--fs-text);
    font-size: 0.875rem;
    padding: 0.5rem 0.625rem;
}

.dropdown-item:hover,
.dropdown-item:focus {
    background-color: var(--fs-hover-overlay);
    color: var(--fs-text);
}

.dropdown-item.active,
.dropdown-item:active {
    background-color: var(--fs-accent-tint);
    color: var(--fs-accent);
}

.dropdown-item i {
    color: var(--fs-accent);
    width: 1.125rem;
    margin-right: 0.625rem;
    text-align: center;
}

.dropdown-header {
    color: var(--fs-text-muted) !important;
    font-size: 0.625rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.8px;
    padding: 0.625rem 0.625rem 0.25rem;
}

.dropdown-toggle::after { opacity: 0.5; }


/* ==========================================================================
   Accordion — card treatment with an accent tint when open
   ========================================================================== */
.accordion-item {
    background-color: var(--fs-surface);
    border: 1px solid var(--fs-border);
    border-radius: var(--fs-radius-card) !important;
    margin-bottom: 0.625rem;
    overflow: hidden;
    box-shadow: none;
}

.accordion-button {
    background-color: transparent;
    color: var(--fs-text);
    font-weight: 600;
    font-size: 0.9375rem;
    padding: 0.875rem 1rem;
    border: none;
    box-shadow: none;
}

.accordion-button:not(.collapsed) {
    background-color: var(--fs-accent-subtle);
    color: var(--fs-text);
    border-bottom: 1px solid var(--fs-border);
    box-shadow: none;
}

.accordion-button.collapsed {
    background-color: transparent;
    color: var(--fs-text);
}

.accordion-button:focus {
    box-shadow: none;
    border-color: transparent;
}

.accordion-button::after {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23A8A8A4'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
    filter: none;
}

html[data-theme="light"] .accordion-button::after {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23737373'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
}

.accordion-button:not(.collapsed)::after {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%237FB56B'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
}

html[data-theme="light"] .accordion-button:not(.collapsed)::after {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%234F7942'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
}

.accordion-body {
    background-color: var(--fs-surface);
    padding: 1rem;
}

.accordion-collapse { transition: height 0.2s ease !important; }


/* ==========================================================================
   Modal — dialogTheme (app_theme.dart:219-226)
   --------------------------------------------------------------------------
   Surface, 16px radius, hairline border. No dark header bar.
   ========================================================================== */
.modal-content {
    background-color: var(--fs-surface);
    border: 1px solid var(--fs-border);
    border-radius: var(--fs-radius-card);
    box-shadow: none;
}

.modal-header {
    background: transparent;
    border-bottom: 1px solid var(--fs-border);
    padding: 1rem 1.25rem;
}

.modal-header .modal-title {
    color: var(--fs-text);
    font-size: 1rem;
    font-weight: 700;
}

.modal-header .btn-close {
    filter: none;
    opacity: 0.6;
}

html[data-theme="dark"] .modal-header .btn-close,
html[data-theme="dark"] .btn-close {
    filter: invert(1) grayscale(1) brightness(1.6);
}

.modal-body {
    background: transparent;
    color: var(--fs-text);
    padding: 1.25rem;
}

.modal-footer {
    background: transparent;
    border-top: 1px solid var(--fs-border);
    padding: 0.875rem 1.25rem;
}

.modal-backdrop.show { opacity: 0.6; }

/* Bottom-sheet feel on phones — bottomSheetTheme (app_theme.dart:227-233) */
@media (max-width: 575.98px) {
    .modal-dialog:not(.modal-dialog-centered) {
        margin: 0;
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        max-width: 100%;
    }

    .modal-dialog:not(.modal-dialog-centered) .modal-content {
        border-radius: 20px 20px 0 0;
        border-bottom: none;
    }
}


/* ==========================================================================
   Progress / macro bars — MacroBar (shared/widgets/macro_bar.dart)
   ========================================================================== */
.progress,
.progress-stacked {
    background-color: var(--fs-border);
    border-radius: var(--fs-radius-pill);
    height: 8px;
    overflow: hidden;
}

.progress-bar {
    background-color: var(--fs-accent);
    border-radius: var(--fs-radius-pill);
}

.progress-bar.bg-protein, .macro-protein { background-color: var(--fs-protein) !important; }
.progress-bar.bg-carbs,   .macro-carbs   { background-color: var(--fs-carbs) !important; }
.progress-bar.bg-fat,     .macro-fat     { background-color: var(--fs-fat) !important; }

.text-protein { color: var(--fs-protein) !important; }
.text-carbs   { color: var(--fs-carbs) !important; }
.text-fat     { color: var(--fs-fat) !important; }


/* ==========================================================================
   Tables — hairline rules, no stripes, quiet uppercase head
   ========================================================================== */
.table {
    --bs-table-bg: transparent;
    color: var(--fs-text);
    margin-bottom: 0;
}

.table > thead > tr > th,
.workout-table th {
    background: transparent;
    color: var(--fs-text-secondary);
    font-size: 0.6875rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.8px;
    padding: 0.75rem 0.875rem;
    border-bottom: 1px solid var(--fs-border);
    white-space: nowrap;
}

.table > tbody > tr > td {
    padding: 0.75rem 0.875rem;
    vertical-align: middle;
    border-bottom: 1px solid var(--fs-border-soft);
    background: transparent;
    color: var(--fs-text);
}

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

.table-hover > tbody > tr:hover > * {
    background-color: var(--fs-hover-overlay);
    color: var(--fs-text);
}

.table-striped > tbody > tr:nth-of-type(odd) > * {
    background-color: transparent;
    color: var(--fs-text);
}

.table-responsive {
    border-radius: var(--fs-radius-card);
    overflow-x: auto;
}

/* DataTables (dataTables.bootstrap5) */
.dataTables_wrapper { color: var(--fs-text); }

.dataTables_wrapper .dataTables_info,
.dataTables_wrapper .dataTables_length,
.dataTables_wrapper .dataTables_filter,
.dataTables_wrapper .dataTables_processing {
    color: var(--fs-text-secondary);
    font-size: 0.8125rem;
}

.dataTables_wrapper .dataTables_filter input,
.dataTables_wrapper .dataTables_length select {
    background-color: var(--fs-elevated);
    border: 1px solid var(--fs-input-border);
    border-radius: var(--fs-radius-sm);
    color: var(--fs-text);
    padding: 0.375rem 0.625rem;
}

table.dataTable { background: transparent; color: var(--fs-text); }
table.dataTable tbody td { color: var(--fs-text); border-color: var(--fs-border-soft); }

table.dataTable.stripe tbody tr.odd > *,
table.dataTable.display tbody tr.odd > * { box-shadow: none; }

.dataTables_wrapper .dataTables_paginate .paginate_button {
    color: var(--fs-text-secondary) !important;
    border: none !important;
    border-radius: var(--fs-radius-sm) !important;
    background: transparent !important;
}

.dataTables_wrapper .dataTables_paginate .paginate_button:hover {
    background: var(--fs-hover-overlay) !important;
    color: var(--fs-text) !important;
}

.dataTables_wrapper .dataTables_paginate .paginate_button.current {
    background: var(--fs-accent-tint) !important;
    color: var(--fs-accent) !important;
}

.page-link {
    background-color: transparent;
    border-color: var(--fs-border);
    color: var(--fs-text-secondary);
}

.page-item.active .page-link {
    background-color: var(--fs-accent);
    border-color: var(--fs-accent);
    color: var(--fs-on-accent);
}


/* ==========================================================================
   Alerts — tinted, borderless, matching the chip logic
   ========================================================================== */
.alert {
    border: 1px solid transparent;
    border-radius: var(--fs-radius-input);
    padding: 0.875rem 1rem;
    font-size: 0.875rem;
}

.alert-success { background-color: var(--fs-success-tint); border-color: var(--fs-success-tint); color: var(--fs-success); }
.alert-danger  { background-color: var(--fs-danger-tint);  border-color: var(--fs-danger-tint);  color: var(--fs-danger); }
.alert-warning { background-color: var(--fs-warning-tint); border-color: var(--fs-warning-tint); color: var(--fs-warning); }
.alert-info,
.alert-primary { background-color: var(--fs-accent-subtle); border-color: var(--fs-accent-tint); color: var(--fs-text); }
.alert-secondary,
.alert-light   { background-color: var(--fs-recessed); border-color: var(--fs-border); color: var(--fs-text-secondary); }


/* ==========================================================================
   Empty state — EmptyView (shared/widgets/state_views.dart)
   ========================================================================== */
.empty-state,
.fs-empty {
    text-align: center;
    padding: 2.5rem 1.5rem;
    color: var(--fs-text-secondary);
    background: transparent;
    border: 1px dashed var(--fs-border);
    border-radius: var(--fs-radius-card);
}

.empty-state i,
.fs-empty i {
    font-size: 2rem;
    color: var(--fs-text-muted);
    margin-bottom: 0.75rem;
    display: block;
}

.empty-state h5,
.fs-empty h5 {
    color: var(--fs-text);
    font-size: 0.9375rem;
    font-weight: 600;
    margin-bottom: 0.25rem;
}

.empty-state p,
.fs-empty p {
    margin-bottom: 0;
    font-size: 0.875rem;
    color: var(--fs-text-secondary);
}


/* ==========================================================================
   Gradient header — GradientHeader (shared/widgets/gradient_header.dart)
   --------------------------------------------------------------------------
   The single sanctioned gradient in the system: a subtle accent wash fading
   into the page background, used only on hero bands.
   ========================================================================== */
.fs-gradient-header {
    background: linear-gradient(to bottom, var(--fs-accent-tint), transparent);
    padding: 1.25rem 1rem 1.5rem;
    margin: -0.875rem -0.875rem 0.75rem;
    text-align: center;
}

.fs-gradient-header .fs-avatar {
    width: 76px;
    height: 76px;
    border-radius: 50%;
    border: 2px solid var(--fs-accent);
    padding: 3px;
    margin: 0 auto 0.75rem;
    display: flex;
    align-items: center;
    justify-content: center;
}

.fs-gradient-header .fs-avatar > * {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    object-fit: cover;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: var(--fs-accent-tint);
    color: var(--fs-accent);
    font-size: 1.75rem;
}


/* ==========================================================================
   Toasts — snackBarTheme (app_theme.dart:234-241)
   ========================================================================== */
#toast-container > div {
    background-color: var(--fs-elevated) !important;
    color: var(--fs-text) !important;
    border: 1px solid var(--fs-border);
    border-radius: var(--fs-radius-btn) !important;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.28) !important;
    opacity: 1 !important;
    font-size: 0.875rem;
    padding: 0.875rem 1rem 0.875rem 3rem;
}

#toast-container > .toast-success { border-left: 3px solid var(--fs-success); }
#toast-container > .toast-error   { border-left: 3px solid var(--fs-danger); }
#toast-container > .toast-warning { border-left: 3px solid var(--fs-warning); }
#toast-container > .toast-info    { border-left: 3px solid var(--fs-accent); }

.toast-title { font-weight: 600; }


/* ==========================================================================
   Footer
   ========================================================================== */
footer {
    background-color: var(--fs-bg);
    border-top: 1px solid var(--fs-border);
    color: var(--fs-text-muted);
    font-size: 0.8125rem;
    padding: 1rem;
}

footer a { color: var(--fs-text-secondary); }
footer a:hover { color: var(--fs-text); }

@media (max-width: 767.98px) {
    footer {
        flex-direction: column;
        gap: 0.5rem;
        text-align: center;
    }
}


/* ==========================================================================
   Notification bell
   ========================================================================== */
.notification-badge,
#notificationCount {
    background-color: var(--fs-danger) !important;
    color: #fff !important;
    font-size: 0.625rem;
    font-weight: 700;
    border-radius: var(--fs-radius-pill);
}

.notification-item {
    border-bottom: 1px solid var(--fs-border-soft);
    padding: 0.75rem;
    color: var(--fs-text);
}

.notification-item:hover { background-color: var(--fs-hover-overlay); }
.notification-item.unread { background-color: var(--fs-accent-subtle); }


/* ==========================================================================
   Misc utilities used by existing markup
   ========================================================================== */
.rounded-circle.bg-secondary {
    background-color: var(--fs-elevated) !important;
    color: var(--fs-text-secondary) !important;
}

.rounded-circle.bg-secondary i { color: var(--fs-text-secondary) !important; }

.shadow,
.shadow-sm,
.shadow-lg { box-shadow: none !important; }

.fs-divider {
    height: 1px;
    background-color: var(--fs-border);
    border: none;
    margin: 1rem 0;
}

.fs-muted-note {
    font-size: 0.8125rem;
    color: var(--fs-text-secondary);
    line-height: 1.45;
}

/* Flatpickr — brand accent in both themes (loaded per-page on the Diary) */
.flatpickr-calendar {
    background: var(--fs-surface);
    border: 1px solid var(--fs-border);
    border-radius: var(--fs-radius-input);
    box-shadow: none;
    color: var(--fs-text);
}

.flatpickr-months .flatpickr-month,
.flatpickr-current-month,
.flatpickr-weekdays,
span.flatpickr-weekday {
    background: transparent;
    color: var(--fs-text-secondary);
    fill: var(--fs-text-secondary);
}

.flatpickr-day {
    color: var(--fs-text);
    border-radius: var(--fs-radius-sm);
}

.flatpickr-day:hover { background: var(--fs-hover-overlay); border-color: transparent; }

.flatpickr-day.selected,
.flatpickr-day.selected:hover,
.flatpickr-day.selected:focus {
    background: var(--fs-accent);
    border-color: var(--fs-accent);
    color: var(--fs-on-accent);
}

.flatpickr-day.today { border-color: var(--fs-accent); }

.flatpickr-day.prevMonthDay,
.flatpickr-day.nextMonthDay,
.flatpickr-day.flatpickr-disabled { color: var(--fs-text-muted); }


/* ==========================================================================
   Macro planner — targets form + weekly plan
   --------------------------------------------------------------------------
   These classes (Pages/Shared/_MacroPlanner.cshtml) lost their styling when the
   old theme was removed, so the day rows fell back to unstyled inline-block and
   wrapped onto three lines. Everything below is token-driven so the planner is
   legible in both themes.
   ========================================================================== */

/* Proteins / Carbs / Fats — three across, stacking on narrow screens. */
.macro-input-group {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1rem;
    margin-bottom: 1rem;
}

@media (max-width: 575.98px) {
    .macro-input-group { grid-template-columns: minmax(0, 1fr); gap: 0.75rem; }
}

.macro-input-group .form-group label,
#macro-targets .form-group > label {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-bottom: 0.35rem;
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--fs-text-secondary);
}

/* Column headings above the seven day rows. */
.weekly-plan-header {
    padding: 0 0.75rem;
    font-size: 0.6875rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--fs-text-muted);
}

.weekly-plan-header i { margin-right: 0.25rem; }

.day-label {
    font-weight: 600;
    color: var(--fs-text);
}

.macro-value {
    font-variant-numeric: tabular-nums;
    color: var(--fs-text-secondary);
}

/* The per-day control cluster: − · slider · + · kcal · lock, all on one line.
   min-width:0 on the range lets it absorb the leftover space instead of
   forcing the row to wrap. */
.slider-controls {
    display: flex;
    align-items: center;
    flex-wrap: nowrap;
    gap: 0.5rem;
}

.slider-controls .form-range {
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
    padding: 0;
}

.slider-btn {
    flex: 0 0 auto;
    width: 26px;
    height: 26px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    font-size: 0.7rem;
    line-height: 1;
    background-color: transparent;
    border: 1px solid var(--fs-border);
    border-radius: var(--fs-radius-pill);
    color: var(--fs-text-secondary);
    cursor: pointer;
    transition: background-color var(--fs-transition), color var(--fs-transition);
}

.slider-btn:hover {
    background-color: var(--fs-hover-overlay);
    color: var(--fs-text);
}

.calorie-badge {
    flex: 0 0 auto;
    min-width: 3.75rem;
    justify-content: center;
    font-variant-numeric: tabular-nums;
    background-color: var(--fs-accent-tint) !important;
    color: var(--fs-accent) !important;
}

.lock-icon {
    flex: 0 0 auto;
    width: 22px;
    text-align: center;
    font-size: 0.8rem;
    color: var(--fs-text-muted);
    cursor: pointer;
    transition: color var(--fs-transition);
}

.lock-icon:hover { color: var(--fs-text); }
.lock-icon.fa-lock { color: var(--fs-accent); }

/* Day rows read as a quiet list, not as boxed cards. */
#weekly-display .list-group-item {
    background-color: transparent;
    border: 0;
    border-bottom: 1px solid var(--fs-border-soft);
    padding-left: 0.75rem;
    padding-right: 0.75rem;
}

#weekly-display .list-group-item:last-child { border-bottom: 0; }

/* Narrow screens: the five-column grid is too tight, so give each day its own
   two-line block — name + macros, then the full-width slider cluster. */
@media (max-width: 767.98px) {
    .weekly-plan-header { display: none; }

    #weekly-display .list-group-item > .row > [class*="col-"] {
        flex: 0 0 auto;
        width: auto;
    }

    #weekly-display .list-group-item > .row {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: 0.35rem 0.75rem;
    }

    #weekly-display .list-group-item > .row > .col-2:first-child {
        flex: 1 0 100%;
    }

    #weekly-display .list-group-item > .row > .col-4 {
        flex: 1 0 100%;
        margin-top: 0.35rem;
    }

    /* Label the bare numbers now that the header row is hidden. */
    .macro-value[data-label]::before {
        content: attr(data-label) " ";
        color: var(--fs-text-muted);
        font-size: 0.6875rem;
    }
}

/* ==========================================================================
   Shared month calendar (_MonthCalendar partial + month-calendar.js)
   Hand-built on-brand month grid with per-day dots. Popover variant is used by
   the diary date picker; inline variant by the schedule view.
   ========================================================================== */
.fs-cal { text-align: center; }

.fs-cal--pop {
    position: absolute; top: calc(100% + 8px); left: 50%; transform: translateX(-50%);
    z-index: 1050; width: 300px; max-width: 92vw;
    background: var(--fs-surface); border: 1px solid var(--fs-border);
    border-radius: var(--fs-radius-card, 16px); box-shadow: 0 8px 28px rgba(0, 0, 0, 0.28);
    padding: 12px; display: none;
}
.fs-cal--pop.open { display: block; }

.fs-cal--inline {
    background: var(--fs-surface); border: 1px solid var(--fs-border);
    border-radius: var(--fs-radius-card, 16px); padding: 12px;
}

.fs-cal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.fs-cal-title { font-weight: 700; color: var(--fs-text); font-size: 0.95rem; }
.fs-cal-nav {
    background: none; border: none; color: var(--fs-text-secondary);
    padding: 4px 10px; border-radius: var(--fs-radius-sm, 8px); cursor: pointer; font-size: 0.85rem;
}
.fs-cal-nav:hover { background: var(--fs-recessed); color: var(--fs-text); }
.fs-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.fs-cal-dow {
    font-size: 0.62rem; font-weight: 600; color: var(--fs-text-muted);
    text-transform: uppercase; padding-bottom: 4px;
}
.fs-cal-cell {
    aspect-ratio: 1; border: none; background: none; border-radius: var(--fs-radius-sm, 8px);
    cursor: pointer; display: flex; flex-direction: column; align-items: center;
    justify-content: center; gap: 1px; color: var(--fs-text); font-size: 0.85rem; padding: 0;
}
.fs-cal-cell.empty { cursor: default; }
.fs-cal-cell:hover:not(.empty):not(:disabled) { background: var(--fs-recessed); }
.fs-cal-cell.future, .fs-cal-cell:disabled { color: var(--fs-text-muted); opacity: 0.45; cursor: default; }
.fs-cal-cell.today:not(.selected) { box-shadow: inset 0 0 0 1.5px var(--fs-accent); }
.fs-cal-cell.selected { background: var(--fs-accent); color: var(--fs-on-accent); font-weight: 700; }
.fs-cal-dots { display: flex; gap: 3px; height: 5px; align-items: center; justify-content: center; }
.fs-cal-dot { width: 5px; height: 5px; border-radius: 50%; display: inline-block; }
.fs-cal-cell.selected .fs-cal-dot { background: var(--fs-on-accent); }
.fs-cal-legend {
    display: flex; gap: 16px; justify-content: center; margin-top: 10px;
    font-size: 0.66rem; color: var(--fs-text-muted); flex-wrap: wrap;
}
.fs-cal-legend span { display: inline-flex; align-items: center; gap: 5px; }

/* Dot colours (diary) */
.fs-cal-dot--food { background: var(--fs-accent); }
.fs-cal-dot--weight { background: var(--fs-info, #0EA5E9); }
/* Dot colours (schedule) */
.fs-cal-dot--planned { background: var(--fs-info, #0EA5E9); }
.fs-cal-dot--completed { background: var(--fs-accent); }
.fs-cal-dot--skipped { background: var(--fs-text-muted); }
.fs-cal-dot--completed-unscheduled { background: var(--fs-accent); opacity: 0.55; }
