/* =============================================================
   Painokumppani — Editorial Nordic design system
   Vaalea ("Aamu") oletuksena, tumma ("Yö") .dark-luokalla.
   ============================================================= */

:root {
    /* Pinnat & musteet */
    --bg:        #F1ECE0;
    --surface:   #FAF6EC;
    --raised:    #FFFFFF;
    --ink:       #13201A;
    --ink-soft:  #5C6660;
    --ink-faint: #8B928D;
    --line:      #DDD6C6;
    --line-soft: #E8E2D4;
    --line-strong: #C9C2B6;

    /* Brändi */
    --juniper:      #2F5043;
    --juniper-soft: #DDE8E0;
    --saffron:      #B96F3B;
    --saffron-soft: #F1DDCB;

    /* Semanttiset — laajennettu paletti */
    --danger:       #9B3838;
    --danger-soft:  #F3DEDE;
    --success:      #3F6B4E;
    --success-soft: #DDE8E0;
    --warning:      #B58A2E;
    --warning-soft: #F3E8CE;
    --info:         #4A6B87;
    --info-soft:    #DBE4EC;

    /* Aliakset selkeyttäväksi käytäntönä */
    --accent:       var(--saffron);
    --primary:      var(--juniper);

    --gradient-hero: radial-gradient(120% 80% at 70% 0%, #E2EAE2 0%, transparent 60%);

    /* Border-radius-asteikko */
    --radius-xs:   6px;
    --radius-sm:   10px;
    --radius-md:   16px;
    --radius-lg:   22px;
    --radius-card: var(--radius-lg);
    --radius-pill: 999px;

    /* Varjot */
    --shadow-sm:     0 1px 2px rgba(19, 32, 26, 0.05);
    --shadow-card:   0 1px 1px rgba(19, 32, 26, 0.03), 0 8px 24px -8px rgba(19, 32, 26, 0.06);
    --shadow-lifted: 0 1px 1px rgba(19, 32, 26, 0.04), 0 16px 40px -12px rgba(19, 32, 26, 0.12);
    --shadow-btn:    0 10px 24px -8px rgba(19, 32, 26, 0.28);
    --shadow-focus:  0 0 0 3px rgba(47, 80, 67, 0.22);

    /* Typografia-asteikko */
    --text-2xs:  0.75rem;
    --text-xs:   0.85rem;
    --text-sm:   0.95rem;
    --text-md:   1rem;
    --text-lg:   1.15rem;
    --text-xl:   1.4rem;
    --text-2xl:  1.9rem;
    --text-3xl:  2.4rem;
    --text-hero: clamp(2.5rem, 8vw, 5rem);
    --leading-tight: 1.2;
    --leading-body:  1.55;
    --leading-loose: 1.7;

    /* Spacing-asteikko (4/8-pohjainen) */
    --space-2xs: 0.25rem;   /*  4px */
    --space-xs:  0.5rem;    /*  8px */
    --space-sm:  0.75rem;   /* 12px */
    --space-md:  1rem;      /* 16px */
    --space-lg:  1.5rem;    /* 24px */
    --space-xl:  2rem;      /* 32px */
    --space-2xl: 3rem;      /* 48px */
    --space-3xl: 4rem;      /* 64px */

    --ease-out: cubic-bezier(0.2, 0.7, 0.25, 1);
}

.dark {
    --bg:        #0E1411;
    --surface:   #161D19;
    --raised:    #1C231F;
    --ink:       #ECE5D4;
    --ink-soft:  #97A09A;
    --ink-faint: #5F6864;
    --line:      #242C27;
    --line-soft: #1B221E;
    --line-strong: #313A34;
    --juniper:   #8DBDA1;
    --juniper-soft: #1A2922;
    --saffron:   #D08855;
    --saffron-soft: #2A1F16;
    --danger:      #D87A7A;
    --danger-soft: #2E1A1A;
    --success:      #8DBDA1;
    --success-soft: #1A2922;
    --warning:      #D9B36A;
    --warning-soft: #2A2314;
    --info:         #8FADC7;
    --info-soft:    #1B242C;
    --gradient-hero: radial-gradient(120% 80% at 70% 0%, #1A2922 0%, transparent 60%);
    --shadow-sm:     0 1px 2px rgba(0, 0, 0, 0.35);
    --shadow-card:   0 1px 1px rgba(0, 0, 0, 0.5), 0 12px 32px -8px rgba(0, 0, 0, 0.4);
    --shadow-lifted: 0 1px 1px rgba(0, 0, 0, 0.5), 0 18px 48px -12px rgba(0, 0, 0, 0.5);
    --shadow-btn:    0 10px 24px -8px rgba(141, 189, 161, 0.4);
    --shadow-focus:  0 0 0 3px rgba(141, 189, 161, 0.25);
}

* { box-sizing: border-box; }

html, body {
    background: var(--bg);
    color: var(--ink);
}

body {
    margin: 0;
    font-family: 'Instrument Sans', system-ui, -apple-system, sans-serif;
    font-feature-settings: 'ss01';
    font-size: 15px;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    min-height: 100vh;
}

/* Paperi-grain — hienovarainen tekstuuri pinnoille */
body::before {
    content: '';
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 1;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.95' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0.6 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
    opacity: 0.05;
    mix-blend-mode: multiply;
}
.dark body::before { opacity: 0.12; mix-blend-mode: screen; }

::selection { background: var(--saffron-soft); color: var(--saffron); }
.dark ::selection { background: var(--juniper); color: var(--bg); }

:focus-visible {
    outline: 2px solid var(--juniper);
    outline-offset: 3px;
    border-radius: 6px;
}

/* =============================================================
   Typografia
   ============================================================= */

.font-display, h1, h2, h3, .hero-headline, .display {
    font-family: 'Fraunces', Georgia, serif;
    font-variation-settings: 'opsz' 144, 'SOFT' 50;
    letter-spacing: -0.025em;
}

.font-mono, .mono { font-family: 'JetBrains Mono', ui-monospace, monospace; }

.italic-display {
    font-style: italic;
    font-variation-settings: 'opsz' 144, 'SOFT' 80;
    color: var(--juniper);
}

h1 { font-size: 2.4rem; font-weight: 500; margin: 0 0 0.4rem; line-height: 1.05; letter-spacing: -0.025em; }
h2 { font-size: 1.4rem; font-weight: 500; margin: 0 0 0.6rem; line-height: 1.2; letter-spacing: -0.02em; }
h3 { font-size: 1.1rem; font-weight: 600; margin: 0 0 0.4rem; line-height: 1.3; letter-spacing: -0.015em; }

@media (min-width: 768px) {
    h1 { font-size: 3.2rem; }
    h2 { font-size: 1.6rem; }
}

.subtitle {
    color: var(--ink-soft);
    margin: 0 0 1.6rem;
    font-size: 1rem;
}

.label {
    font-size: 0.7rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--ink-faint);
    font-weight: 500;
}

.hint {
    color: var(--ink-soft);
    font-size: 0.9rem;
    line-height: 1.45;
    margin: 0.4rem 0;
    /* Nollataan .form-grid labelin uppercase/letter-spacing/lihavointi-
       perimä, jotta <span class="hint"> labelin sisällä näyttää tavalliselta
       leipätekstiltä eikä ISOLTA HARVENNETULTA otsikolta. */
    text-transform: none;
    letter-spacing: 0;
    font-weight: 400;
}

.success { color: var(--juniper); font-weight: 500; }

/* =============================================================
   Layout: side rail + main + bottom nav
   ============================================================= */

.app-shell {
    min-height: 100vh;
    position: relative;
    z-index: 2;
}

.side-rail { display: none; }

.main-col {
    padding: 1.4rem 1.25rem 7rem;
    max-width: 1180px;
    margin: 0 auto;
}

.topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 1.6rem;
    gap: 1rem;
}

.topbar-brand {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    color: var(--ink);
    text-decoration: none;
}
.topbar-mark {
    width: 36px; height: 36px;
    border-radius: 50%;
    background: var(--ink);
    color: var(--bg);
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Fraunces', serif;
    font-variation-settings: 'opsz' 144, 'SOFT' 100;
    font-size: 1.25rem;
    font-weight: 500;
}
.topbar-title {
    font-family: 'Fraunces', serif;
    font-size: 1.1rem;
    font-weight: 500;
    letter-spacing: -0.025em;
    line-height: 1;
}
.topbar-date {
    font-size: 0.65rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ink-faint);
    margin-top: 0.2rem;
}

.icon-btn {
    width: 40px; height: 40px;
    border-radius: 50%;
    border: 1px solid var(--line);
    background: transparent;
    color: var(--ink);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: background 0.18s var(--ease-out), border-color 0.18s var(--ease-out);
}
.icon-btn:hover { background: var(--juniper-soft); border-color: transparent; }
.icon-btn svg { width: 18px; height: 18px; }

.topbar-actions {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
}
.topbar-logout-form { margin: 0; }

.rail-logout {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    margin: 0;
}
.rail-user {
    font-size: 0.78rem;
    color: var(--ink-soft);
    padding: 0 0.2rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.bottom-nav {
    position: fixed;
    inset: auto 0 0 0;
    z-index: 50;
    padding: 0.5rem 0.75rem max(0.75rem, env(safe-area-inset-bottom));
    background: linear-gradient(to top, var(--bg) 70%, transparent);
    pointer-events: none;
}
.bottom-nav-inner {
    background: var(--raised);
    border: 1px solid var(--line);
    border-radius: 22px;
    box-shadow: var(--shadow-lifted);
    display: flex;
    align-items: center;
    justify-content: space-around;
    padding: 0.35rem;
    pointer-events: auto;
}
.bottom-nav a {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    padding: 0.45rem 0.25rem;
    font-size: 0.6rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    font-weight: 500;
    color: var(--ink-soft);
    border-radius: 12px;
    text-decoration: none;
    transition: background 0.2s, color 0.2s;
}
.bottom-nav a svg { width: 20px; height: 20px; stroke-width: 1.6; }
.bottom-nav a.active {
    color: var(--ink);
    background: var(--juniper-soft);
}
.bottom-nav a.active svg { color: var(--juniper); }

@media (min-width: 768px) {
    .app-shell {
        display: grid;
        grid-template-columns: 260px minmax(0, 1fr);
    }
    .side-rail {
        display: flex;
        flex-direction: column;
        gap: 2rem;
        padding: 2.4rem 1.8rem;
        border-right: 1px solid var(--line);
        position: sticky;
        top: 0;
        height: 100vh;
        z-index: 5;
    }
    .side-rail .brand-row {
        display: flex;
        align-items: center;
        gap: 0.85rem;
        color: var(--ink);
        text-decoration: none;
    }
    .side-rail-mark {
        width: 42px; height: 42px;
        border-radius: 50%;
        background: var(--ink);
        color: var(--bg);
        display: flex;
        align-items: center;
        justify-content: center;
        font-family: 'Fraunces', serif;
        font-variation-settings: 'opsz' 144, 'SOFT' 100;
        font-size: 1.5rem;
    }
    .side-rail-title {
        font-family: 'Fraunces', serif;
        font-weight: 500;
        font-size: 1.3rem;
        letter-spacing: -0.025em;
        display: block;
        line-height: 1;
    }
    .side-rail-tag {
        display: block;
        font-size: 0.65rem;
        letter-spacing: 0.14em;
        text-transform: uppercase;
        color: var(--ink-faint);
        margin-top: 0.3rem;
    }
    .side-rail nav {
        display: flex;
        flex-direction: column;
        gap: 0.15rem;
        margin-top: 0.5rem;
    }
    .side-rail nav a {
        font-size: 0.98rem;
        padding: 0.55rem 0.85rem;
        border-radius: 12px;
        color: var(--ink-soft);
        text-decoration: none;
        position: relative;
        transition: color 0.2s, background 0.2s;
    }
    .side-rail nav a:hover {
        color: var(--ink);
        background: var(--line-soft);
    }
    .side-rail nav a.active {
        color: var(--ink);
        background: var(--juniper-soft);
    }
    .side-rail nav a.active::before {
        content: '';
        position: absolute;
        left: -8px;
        top: 50%;
        transform: translateY(-50%);
        width: 3px;
        height: 60%;
        border-radius: 999px;
        background: var(--juniper);
    }
    .side-rail .rail-foot {
        margin-top: auto;
        display: flex;
        flex-direction: column;
        gap: 0.8rem;
    }
    .side-rail .coach-pill {
        display: flex;
        align-items: center;
        gap: 0.7rem;
        padding: 0.8rem;
        border-radius: 14px;
        background: var(--surface);
        border: 1px solid var(--line);
    }
    .theme-toggle {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 0.55rem 0.85rem;
        font-size: 0.85rem;
        border-radius: 12px;
        border: 1px solid var(--line);
        background: transparent;
        color: var(--ink);
        cursor: pointer;
        font-family: inherit;
    }
    .theme-toggle .label-text { color: var(--ink-soft); }
    .theme-toggle .value { font-weight: 500; }

    .main-col {
        padding: 2.4rem 3rem 3rem;
    }
    .topbar { margin-bottom: 2.4rem; }
    .topbar-mobile-brand { display: none; }
    .topbar-desktop-date { display: block; }
    .bottom-nav { display: none; }
}

@media (min-width: 1024px) {
    .main-col { padding-left: 5rem; padding-right: 5rem; }
}

.topbar-mobile-brand { display: flex; }
.topbar-desktop-date { display: none; }

/* =============================================================
   Hero & pullquote
   ============================================================= */

.hero {
    position: relative;
    padding: 1.5rem 0.5rem;
    margin-bottom: 2.4rem;
    background-image: var(--gradient-hero);
    border-radius: 26px;
}
.hero-eyebrow {
    font-size: 0.7rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--ink-faint);
    font-weight: 500;
    margin-bottom: 0.8rem;
    display: block;
}
.hero-headline {
    font-family: 'Fraunces', serif;
    font-variation-settings: 'opsz' 144, 'SOFT' 30;
    font-size: clamp(2.5rem, 8vw, 5rem);
    font-weight: 500;
    line-height: 0.95;
    letter-spacing: -0.035em;
    margin: 0;
}
/* Kapeammat sivut (auth/profile/onboarding): pienempi clamp jotta otsikko
   mahtuu kapeampaan layoutiin yhden tai kahden rivin sisään. Sama font,
   sama font-weight, sama letter-spacing kuin pää-.hero-headlinella. */
.hero-headline.hero-headline-compact {
    font-size: clamp(2.2rem, 6vw, 3.4rem);
}
.hero-chip-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem 1.4rem;
    align-items: baseline;
    margin-top: 1.5rem;
}

@media (min-width: 768px) {
    .hero { padding: 2rem 2rem 2rem 0.5rem; }
}

.pullquote {
    position: relative;
    padding: 0 0 0 1.8rem;
    margin-bottom: 3rem;
}
.pullquote::before {
    content: '“';
    position: absolute;
    left: -0.4rem;
    top: -2.6rem;
    font-family: 'Fraunces', serif;
    font-variation-settings: 'opsz' 144, 'SOFT' 100;
    font-size: 6rem;
    line-height: 1;
    color: var(--juniper);
    opacity: 0.2;
    pointer-events: none;
}
.pullquote .label { color: var(--juniper); }
.pullquote-text {
    font-family: 'Fraunces', serif;
    font-variation-settings: 'opsz' 144, 'SOFT' 40;
    font-size: clamp(1.4rem, 4vw, 2.4rem);
    line-height: 1.15;
    letter-spacing: -0.025em;
    margin: 0.6rem 0 0;
    max-width: 36ch;
    font-weight: 500;
}
.pullquote-text em {
    font-style: italic;
    color: var(--juniper);
    font-variation-settings: 'opsz' 144, 'SOFT' 80;
}

/* =============================================================
   Dashboard: kompakti trio (seuraava ateria / paino / treeni)
   ============================================================= */

.dash-promise {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.6rem;
    margin: 0 0 1.6rem;
    padding: 0.55rem 0.9rem;
    background: var(--juniper-soft);
    border-radius: 12px;
    font-family: 'Fraunces', serif;
    font-variation-settings: 'opsz' 80, 'SOFT' 60;
    font-size: 1rem;
    line-height: 1.3;
    color: var(--juniper);
}
.dash-promise .label { color: var(--juniper); }

/* Yksinkertainen 3-sarakkeinen korttirivi (käytössä admin-dashboardissa). */
.dash-trio {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.6rem;
}
@media (min-width: 768px) {
    .dash-trio { grid-template-columns: repeat(3, 1fr); gap: 1.1rem; }
}

/* Dashboardin päälohko: Next meal, Painosi, Ravinto + Painotrendi + Päiväpulssi
   samassa flex-kontainerissa, jotta CSS `order` voi lomittaa ne eri tavoin
   mobiilissa ja desktopilla.
   Mobiili (yksi sarake): Next meal → Painotrendi → Päiväpulssi → Painosi →
   Ravinto (trendit heti Next Mealin alle).
   Desktop: kolme yhtä leveää korttia ylärivillä (trio) + trendit täysleveinä
   niiden alla — DOM-järjestyksessä. */
.dash-main {
    display: flex;
    flex-direction: column;
    gap: 1.6rem;
}
.dash-main > .dash-card-meal      { order: 1; }
.dash-main > #painotrendi         { order: 2; }
.dash-main > .dash-pulse          { order: 3; }
.dash-main > .dash-weight-card    { order: 4; }
.dash-main > .dash-nutrition-card { order: 5; }

@media (min-width: 768px) {
    .dash-main {
        flex-direction: row;
        flex-wrap: wrap;
        gap: 1.1rem;
    }
    /* Trio: kolme yhtä leveää saraketta ylärivillä. */
    .dash-main > .dash-card-meal,
    .dash-main > .dash-weight-card,
    .dash-main > .dash-nutrition-card {
        flex: 1 1 0;
        min-width: 0;
    }
    /* Trendit täysleveinä omilla riveillään trion alla. */
    .dash-main > #painotrendi,
    .dash-main > .dash-pulse {
        flex: 1 1 100%;
    }
    /* Desktop-järjestys = DOM-järjestys (ateria, paino, ravinto, trendit). */
    .dash-main > .dash-card-meal      { order: 1; }
    .dash-main > .dash-weight-card    { order: 2; }
    .dash-main > .dash-nutrition-card { order: 3; }
    .dash-main > #painotrendi         { order: 4; }
    .dash-main > .dash-pulse          { order: 5; }
}

.dash-card {
    padding: 0.95rem 1.1rem;
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
}
.dash-card .label { display: block; }
.dash-card-main {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.6rem;
    flex-wrap: wrap;
}
.dash-figure {
    font-family: 'Fraunces', serif;
    font-variation-settings: 'opsz' 144, 'SOFT' 30;
    font-size: 1.7rem;
    font-weight: 500;
    letter-spacing: -0.025em;
    line-height: 1;
    color: var(--ink);
}
.dash-figure small {
    font-family: 'Fraunces', serif;
    font-size: 0.85rem;
    color: var(--ink-soft);
    font-weight: 400;
}
.dash-figure-name { font-size: 1.35rem; }
.dash-figure-icon { font-size: 1.3rem; }
.dash-card-sub {
    font-size: 0.85rem;
    color: var(--ink-soft);
    line-height: 1.3;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.15rem;
    text-align: right;
}

/* Painosi-laatikon lisätieto: päivän muistutus, putki, tavoiteaika-arvio.
   Yhdistetty rivipino jotta välistys pysyy tiiviinä eikä laatikko venyisi. */
.dash-weight-meta {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    font-size: 0.82rem;
    line-height: 1.35;
    color: var(--ink-soft);
    margin: 0;
}
.dash-weight-meta p { margin: 0; }
.dash-weighin-group {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    margin-top: 0.2rem;
}
.dash-weight-nudge {
    color: var(--saffron, var(--ink));
    font-weight: 500;
    font-size: 0.82rem;
    line-height: 1.3;
    letter-spacing: 0.02em;
    margin: 0;
}
.dash-weight-streak { color: var(--juniper); }
.dash-weight-streak-warn { color: var(--ink-soft); font-weight: 400; }
.dash-weight-eta {
    color: var(--ink-faint, var(--ink-soft));
    font-size: 0.78rem;
    letter-spacing: 0.02em;
}
.dash-meal-products {
    font-family: 'Fraunces', serif;
    font-size: 0.95rem;
    line-height: 1.3;
    color: var(--ink);
    margin: 0;
}
.dash-card-link {
    font-size: 0.78rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--juniper);
    text-decoration: none;
    font-weight: 500;
    margin-top: 0.1rem;
}
.dash-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}
.dash-weighin {
    margin-top: 0;
    gap: 0.4rem;
}
.dash-weighin input {
    flex: 1;
    min-width: 0;
    padding: 0.5rem 0.7rem;
    font-size: 0.88rem;
}
.dash-weighin button {
    padding: 0.5rem 1rem;
    font-size: 0.85rem;
}

/* ----- Päiväpulssi (DailyCheckin) -----
   Oma kortti trion alla: otsikkorivi + (?)-painike ovat <details>n
   ulkopuolella, jotta sisäkkäisen <details>n click bubbling ei sotke
   lomakkeen tilaa. Summary näkyy aina pienenä rivinä; lomake avautuu
   klikkauksesta (auki oletuksena kun päivän pulssia ei vielä ole).
   1–5-asteikot renderöidään radio-napeilla, jotka piilotetaan
   visuaalisesti ja korvataan pyöreillä, mobiilissa hyvin osuvilla
   painikkeilla. */
.dash-checkin-header {
    /* .dash-checkin-legend-row tarjoaa flex-rivin label + (?) -parille;
       tämä luokka vain antaa pohjapehmusteen suhteessa statusriviin. */
    margin-bottom: 0.5rem;
}
.dash-checkin {
    position: relative;
}
.dash-checkin-summary {
    cursor: pointer;
    list-style: none;
    display: flex;
    align-items: center;
    padding: 0.15rem 1.6rem 0.15rem 0;
    -webkit-tap-highlight-color: transparent;
}
.dash-checkin-summary::-webkit-details-marker { display: none; }
.dash-checkin-summary::after {
    content: '▾';
    position: absolute;
    right: 0.2rem;
    top: 0.2rem;
    color: var(--ink-faint, var(--ink-soft));
    font-size: 0.8rem;
    transition: transform 0.15s ease;
}
.dash-checkin[open] .dash-checkin-summary::after { transform: rotate(180deg); }
.dash-checkin-status {
    font-size: 0.78rem;
    color: var(--ink-soft);
    line-height: 1.3;
}
.dash-checkin-form {
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
    margin-top: 0.6rem;
}
.dash-checkin-field {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}
.dash-checkin-legend {
    font-size: 0.78rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-soft);
    font-weight: 500;
}
/* Aamurituaalin paino-input yhdistetyssä lomakkeessa (punnitus + reflektio). */
.dash-morning-weight {
    width: 100%;
    padding: 0.55rem 0.75rem;
    font-size: 0.95rem;
    border: 1px solid var(--line);
    border-radius: 12px;
    background: var(--bg);
    color: var(--ink);
}
/* Väliotsikot "Miten eilinen meni?" / "Miten nukuit?" jakavat aamulomakkeen. */
.dash-checkin-subhead {
    margin: 0.6rem 0 0;
    font-family: 'Fraunces', serif;
    font-variation-settings: 'opsz' 80, 'SOFT' 60;
    font-size: 1rem;
    color: var(--ink);
}
/* Prosessitavoitteen toteumarviointi näyttää lupaustekstin nappiasteikon
   yläpuolella samalla juniper-sävyllä kuin dashin yläosan lupausrivi,
   jotta käyttäjä tunnistaa kontekstin yhdellä silmäyksellä. */
.dash-checkin-promise-text {
    margin: 0.05rem 0 0.15rem;
    padding: 0.4rem 0.7rem;
    background: var(--juniper-soft);
    border-radius: 10px;
    font-family: 'Fraunces', serif;
    font-variation-settings: 'opsz' 80, 'SOFT' 60;
    font-size: 0.92rem;
    line-height: 1.3;
    color: var(--juniper);
}
.dash-scale {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
}
.dash-scale-opt {
    flex: 1 1 0;
    min-width: 2.4rem;
    position: relative;
    cursor: pointer;
}
.dash-scale-opt input {
    position: absolute;
    opacity: 0;
    inset: 0;
    margin: 0;
    cursor: pointer;
}
.dash-scale-opt span {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 2.4rem;
    border: 1px solid var(--line);
    border-radius: 999px;
    font-variant-numeric: tabular-nums;
    font-size: 0.95rem;
    color: var(--ink-soft);
    background: var(--bg);
    transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
.dash-scale-opt input:checked + span {
    background: var(--juniper);
    color: var(--bg);
    border-color: var(--juniper);
    font-weight: 600;
}
.dash-scale-opt input:focus-visible + span {
    outline: 2px solid var(--juniper);
    outline-offset: 2px;
}
/* Uni-painikkeet ovat leveämpiä kuin numeroasteikot ("6–7 h" vs "3"),
   joten annetaan koko riville oma min-leveys jotta tekstit eivät katkea. */
.dash-scale-sleep .dash-scale-opt { min-width: 3.2rem; }
.dash-scale-sleep .dash-scale-opt span {
    font-size: 0.82rem;
    padding: 0 0.4rem;
}
.dash-checkin-save {
    align-self: flex-start;
    padding: 0.55rem 1.1rem;
    font-size: 0.88rem;
    margin-top: 0.2rem;
}

/* Profiilisivun checkbox + tone-radio-rivi. Käytetään samaa visuaalista
   kieltä kuin päiväpulssin nappiasteikko (.dash-scale-opt).
   Korkeampi spesifisyys (.form-grid .checkbox-label) on tarpeen jotta
   ohitamme .form-grid labelin column-suunnan ja uppercase-typografian —
   muuten checkbox pinottuisi tekstin päälle ja "Käytössä"-rivi olisi
   ISO HARVENNETTU. */
.form-grid .checkbox-label,
.checkbox-label {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 0.6rem;
    cursor: pointer;
    text-transform: none;
    letter-spacing: 0;
    font-weight: 400;
    font-size: 0.95rem;
    color: var(--ink);
}
.checkbox-label input[type="checkbox"] {
    width: 1.1rem;
    height: 1.1rem;
    accent-color: var(--juniper);
    cursor: pointer;
}
.form-field-label {
    display: block;
    font-size: 0.78rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-soft);
    font-weight: 500;
    margin-top: 0.8rem;
    margin-bottom: 0.4rem;
}
.tone-options {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}
.tone-opt {
    flex: 1 1 0;
    min-width: 6rem;
    position: relative;
    cursor: pointer;
}
.tone-opt input {
    position: absolute;
    opacity: 0;
    inset: 0;
    margin: 0;
    cursor: pointer;
}
.tone-opt span {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 2.6rem;
    border: 1px solid var(--line);
    border-radius: 999px;
    font-size: 0.9rem;
    font-weight: 400;
    letter-spacing: 0;
    text-transform: none;
    color: var(--ink-soft);
    background: var(--bg);
    transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
.tone-opt input:checked + span {
    background: var(--juniper);
    color: var(--bg);
    border-color: var(--juniper);
    font-weight: 600;
}
.tone-opt input:focus-visible + span {
    outline: 2px solid var(--juniper);
    outline-offset: 2px;
}

/* Päivän motivaatio — kevyt rivi, kursiivilla nostettu */
.dash-motivation {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.6rem;
    margin: 0 0 1.6rem;
    padding: 0.55rem 0.9rem;
    background: var(--saffron-soft, rgba(217, 162, 87, 0.10));
    border-radius: 12px;
    font-family: 'Fraunces', serif;
    font-variation-settings: 'opsz' 80, 'SOFT' 80;
    font-size: 1.02rem;
    line-height: 1.35;
    color: var(--ink);
}
.dash-motivation .label { color: var(--saffron, var(--ink-soft)); }
.dash-motivation-text { font-style: italic; letter-spacing: -0.01em; }

/* "Seuraava ateria" -kortin sisällä käytetään ravintosivun meal-card-tyyliä.
   dash-card-meal poistaa tuplapehmusteen niin että meal-card-head istuu suoraan. */
.dash-card-meal .meal-card-head { margin-bottom: 0.5rem; }
.dash-card-meal .meal-products { margin-bottom: 0.3rem; }
.dash-card-meal .meal-type {
    flex-wrap: wrap;
    margin-bottom: 0.25rem;
}
.dash-card-meal .meal-time { font-size: 1.05rem; }
.dash-card-meal .meal-products li { font-size: 0.98rem; }

/* Ryhmä-slotti-editorin jaetut tyylit: sekä ravintosivun päivälomake
   (day_meals.html) että dashboardin Next Meal -kortin inline-editori
   käyttävät samaa dm_group-makroa. Pidetään täällä yhtenä totuutena. */
.dm-group { margin-bottom: .6rem; }
.dm-group-label { display: block; font-size: .8rem; opacity: .7; margin-bottom: .2rem; }
.dm-group-row { display: grid; grid-template-columns: 1fr 5rem; gap: .4rem; align-items: center; }
/* min-width:0 sallii selectin kutistua sarakkeeseen — muuten pisin
   option-teksti venyttää sen yli kortin ja rikkoo layoutin. */
.dm-group-row select, .dm-group-row input { margin: 0; min-width: 0; }
.dm-group-row select { width: 100%; max-width: 100%; }
.dm-req { color: var(--saffron, #c8791a); font-weight: 700; }
.dm-hint { font-size: .78rem; opacity: .6; }

/* Next Meal -kortin inline-editorin toggle + lomake. */
.dash-meal-edit { margin-top: 0.4rem; }
.dash-meal-edit-summary {
    cursor: pointer;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--juniper);
    list-style: none;
}
.dash-meal-edit-summary::-webkit-details-marker { display: none; }
.dash-meal-edit-form { margin-top: 0.6rem; }

/* "Huomenna"-merkki Seuraava ateria -kortissa, kun kaikki tämän päivän
   ateriat ovat jo ohi ja kortti näyttää huomisen ensimmäisen aterian. */
.meal-tomorrow-badge {
    display: inline-block;
    margin-left: 0.4rem;
    padding: 0.05rem 0.5rem;
    border: 1px solid var(--line);
    border-radius: 999px;
    font-size: 0.7rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ink-soft);
    background: var(--bg);
    vertical-align: middle;
}

/* Painosi-laatikon yläpuolinen selite: "tämän päivän mittaus" / "punnittu N pv sitten" */
.weight-today-caption {
    display: block;
    font-size: 0.78rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-soft);
    font-weight: 400;
    margin-top: -0.15rem;
}

/* =============================================================
   Chips & labels
   ============================================================= */

.chip {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.28rem 0.7rem;
    font-size: 0.7rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    font-weight: 500;
    border-radius: var(--radius-pill);
    background: var(--juniper-soft);
    color: var(--juniper);
}
.chip-saffron { background: var(--saffron-soft); color: var(--saffron); }
.chip-ink { background: var(--ink); color: var(--bg); }

/* Ravinto-osion alanavigaatio (päivän ateriat · suunnitelmapohja ·
   ruokapaletti). Pilleririvi joka kääriytyy kapealla; aktiivinen korostettu. */
.subnav {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-bottom: 1.25rem;
}
.subnav-item {
    display: inline-flex;
    align-items: center;
    padding: 0.4rem 0.9rem;
    font-size: 0.9rem;
    font-weight: 500;
    color: var(--ink-soft);
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    text-decoration: none;
    transition: background 0.15s var(--ease-out), color 0.15s var(--ease-out);
}
.subnav-item:hover {
    background: var(--juniper-soft);
    color: var(--juniper);
}
.subnav-item.active {
    background: var(--juniper);
    border-color: transparent;
    color: #fff;
}
.chip .dot {
    width: 6px; height: 6px; border-radius: 50%; background: currentColor;
}

/* =============================================================
   Cards
   ============================================================= */

.grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.1rem;
}

@media (min-width: 1024px) {
    .grid-feature {
        grid-template-columns: 1.4fr 1fr;
    }
    .grid-sidebar {
        grid-template-columns: 1fr 360px;
    }
}

@media (min-width: 768px) {
    .grid-pair {
        grid-template-columns: 1fr 1fr;
    }
}

.card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-card);
    padding: 1.5rem;
    box-shadow: var(--shadow-card);
    position: relative;
    z-index: 2;
    margin-bottom: 0;
}
@media (min-width: 768px) {
    .card { padding: 2rem; }
}
.card-raised { background: var(--raised); }
.card-ink {
    background: var(--ink);
    color: var(--bg);
    border-color: transparent;
}
.card-ink .label { color: rgba(255, 255, 255, 0.55); }
.card-ink h2, .card-ink h3 { color: var(--bg); }

.card-saffron {
    background: linear-gradient(135deg, var(--saffron-soft), var(--surface));
}
.card-saffron .label { color: var(--saffron); }

.card-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1rem;
}

/* highlight card (process goal in old layout) → pullquote-feel */
.card.highlight {
    background: var(--juniper-soft);
    border-color: transparent;
}
.card.highlight .big {
    font-family: 'Fraunces', serif;
    font-size: 1.4rem;
    font-weight: 500;
    color: var(--juniper);
    letter-spacing: -0.02em;
    margin: 0.4rem 0;
}

/* =============================================================
   Buttons
   ============================================================= */

.btn-primary, .btn-secondary, .btn-ghost {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.78rem 1.25rem;
    border-radius: var(--radius-pill);
    border: 1px solid transparent;
    font-family: inherit;
    font-size: 0.92rem;
    font-weight: 500;
    letter-spacing: -0.01em;
    cursor: pointer;
    text-decoration: none;
    transition: transform 0.18s var(--ease-out), box-shadow 0.18s var(--ease-out),
                background 0.18s var(--ease-out), border-color 0.18s var(--ease-out);
}
.btn-primary {
    background: var(--ink);
    color: var(--bg);
}
.btn-primary:hover {
    transform: translateY(-1px);
    box-shadow: 0 10px 24px -8px rgba(19, 32, 26, 0.28);
}
.btn-primary:active { transform: translateY(0); }
.dark .btn-primary:hover { box-shadow: 0 10px 24px -8px rgba(141, 189, 161, 0.4); }

.btn-secondary {
    background: var(--juniper-soft);
    color: var(--juniper);
    border-color: transparent;
}
.btn-secondary:hover {
    background: var(--juniper);
    color: var(--bg);
}

.btn-ghost {
    background: transparent;
    color: var(--ink);
    border-color: var(--line);
}
.btn-ghost:hover {
    background: var(--juniper-soft);
    border-color: transparent;
}

.btn-small {
    padding: 0.45rem 0.85rem;
    font-size: 0.78rem;
}

.link-btn {
    background: none;
    border: none;
    color: var(--danger);
    cursor: pointer;
    font-size: 0.82rem;
    font-family: inherit;
    padding: 0.3rem 0.5rem;
    border-radius: 8px;
    transition: background 0.18s;
}
.link-btn:hover { background: rgba(155, 56, 56, 0.08); }

/* =============================================================
   Metrics, bars, rings
   ============================================================= */

.metric-row { display: flex; flex-direction: column; gap: 0.4rem; margin: 0.6rem 0 1rem; }
.metric-row.triplet {
    flex-direction: row;
    gap: 1rem;
    flex-wrap: wrap;
}
.metric { display: flex; flex-direction: column; flex: 1; min-width: 120px; }
.metric-label {
    font-size: 0.7rem;
    color: var(--ink-faint);
    text-transform: uppercase;
    letter-spacing: 0.12em;
    font-weight: 500;
}
.metric-value {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 1.4rem;
    font-weight: 500;
    line-height: 1.15;
    color: var(--ink);
    margin-top: 0.2rem;
}
.metric.small .metric-value { font-size: 1.05rem; }
.metric-value small { color: var(--ink-soft); font-weight: 400; font-size: 0.7em; }

.bigfig {
    font-family: 'Fraunces', serif;
    font-variation-settings: 'opsz' 144, 'SOFT' 30;
    font-size: clamp(2.8rem, 8vw, 3.6rem);
    font-weight: 500;
    letter-spacing: -0.035em;
    line-height: 1;
    color: var(--ink);
}
.bigfig small {
    font-family: 'Fraunces', serif;
    font-size: 1.2rem;
    color: var(--ink-soft);
    font-weight: 400;
    margin-left: 0.2rem;
}

.bar {
    height: 6px;
    background: var(--line-soft);
    border-radius: 999px;
    overflow: hidden;
    margin-top: 0.4rem;
}
.bar-fill {
    height: 100%;
    background: var(--juniper);
    border-radius: 999px;
    transition: width 0.6s var(--ease-out);
}
.bar-fill.saffron { background: var(--saffron); }
.bar-fill.ink { background: var(--ink); }

.macro-rings {
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 1rem 0 0.6rem;
}
.macro-rings svg { width: 170px; height: 170px; }
.macro-legend {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.5rem;
    text-align: center;
    margin-top: 0.4rem;
}
.macro-legend .swatch {
    display: block;
    width: 8px; height: 8px; border-radius: 50%;
    margin: 0 auto 0.3rem;
}
.macro-legend .name {
    font-size: 0.7rem;
    color: var(--ink-faint);
    letter-spacing: 0.1em;
    text-transform: uppercase;
}
.macro-legend .num {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.82rem;
    margin-top: 0.15rem;
}
.macro-legend .num span { color: var(--ink-faint); }

/* Wave (weight trend) SVG */
.wave-card svg {
    width: 100%;
    height: 160px;
}
.wave-fill-stop-1 { stop-color: var(--juniper); stop-opacity: 0.22; }
.wave-fill-stop-2 { stop-color: var(--juniper); stop-opacity: 0; }
.wave-x-labels {
    display: flex;
    justify-content: space-between;
    font-size: 0.65rem;
    color: var(--ink-faint);
    margin-top: 0.4rem;
}
.wave-ma { stroke: var(--saffron); }

/* Päiväpulssin trendikaavio — sama koko kuin painokäyrä, oma legenda. */
.pulse-chart svg {
    width: 100%;
    height: 160px;
}
.pulse-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem 1rem;
    margin-top: 0.5rem;
}
.pulse-legend-item {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.75rem;
    color: var(--ink-soft);
}
.pulse-legend-dot {
    width: 0.7rem;
    height: 0.7rem;
    border-radius: 50%;
    flex: 0 0 auto;
}
.wave-ma-caption {
    margin: 0.35rem 0 0;
    font-size: 0.7rem;
    color: var(--ink-faint);
    letter-spacing: 0.02em;
}

/* Painon mittarirystysten rivi (4 lukua aaltokäyrän yläpuolella) */
.weight-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    gap: 0.9rem 1.2rem;
    margin-top: 0.9rem;
    padding-top: 0.9rem;
    border-top: 1px solid var(--line-soft);
}
.weight-stat {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    min-width: 0;
}
.weight-stat-label {
    font-size: 0.7rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ink-soft);
    font-weight: 500;
}
.weight-stat-num {
    font-size: 1.15rem;
    color: var(--ink);
    line-height: 1.1;
    font-weight: 500;
}
.weight-stat-num small {
    font-size: 0.7rem;
    color: var(--ink-soft);
    font-weight: 400;
}
/* Pieni alaotsikko stat-numeron alla — käytetään viikkomuutoksessa
   näyttämään "edellinen → nykyinen" -arvo ja suuntaselite. */
.weight-stat-sub {
    font-size: 0.7rem;
    color: var(--ink-soft);
    letter-spacing: 0.04em;
    line-height: 1.3;
}
/* Värilliset variantit määritellään suba:n JÄLKEEN jotta combo
   esim. `weight-stat-sub weight-stat-loss` saa värin oikein. */
.weight-stat-loss { color: var(--juniper); }
.weight-stat-gain { color: var(--saffron); }
.weight-stat-flat { color: var(--ink-soft); }

/* Selitysrivi 5-laatikkoisen rivin alla: kertoo edellinen → nykyinen
   7 pv keskiarvon ja suunnan tavoitteeseen. Pidetty ruudukon ulkopuolella
   jotta laatikot itsessään pysyvät samankorkuisia. */
.weight-trend-context {
    margin: 0.7rem 0 0;
    font-size: 0.78rem;
    line-height: 1.4;
    color: var(--ink-soft);
    letter-spacing: 0.02em;
}

/* Painotrendin placeholder ennen ensimmäisiä mittauksia — kortti näkyy
   silti, jotta käyttäjä näkee tilan ja oppii että painoa seurataan. */
.weight-trend-empty {
    margin-top: 0.9rem;
    padding-top: 0.9rem;
    border-top: 1px solid var(--line-soft);
}
.weight-trend-empty-text {
    margin: 0 0 0.9rem;
    font-size: 0.92rem;
    line-height: 1.5;
    color: var(--ink-soft);
}
.weight-trend-empty-stats {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.9rem 1.2rem;
}

/* Edistymispalkki: lähtöpaino → tavoite */
.journey-bar {
    margin-top: 1.2rem;
    padding-top: 1rem;
    border-top: 1px solid var(--line-soft);
}
.journey-bar-track {
    position: relative;
    height: 6px;
    background: var(--line-soft);
    border-radius: var(--radius-pill);
    overflow: hidden;
}
.journey-bar-fill {
    height: 100%;
    background: linear-gradient(90deg, var(--juniper-soft) 0%, var(--juniper) 100%);
    border-radius: var(--radius-pill);
    transition: width 0.6s var(--ease-out);
}
.journey-bar-ends {
    display: flex;
    justify-content: space-between;
    margin-top: 0.4rem;
    font-size: 0.7rem;
    color: var(--ink-faint);
}

/* Välitavoitteet: 5 tähteä palkin PÄÄLLÄ (20/40/60/80/100 %).
   Saavutettu tähti muuttuu safraaninkeltaiseksi ja täyttyy. */
.journey-bar-graphic {
    position: relative;
}
.journey-milestones {
    position: absolute;
    inset: 0;
    margin: 0;
    padding: 0;
    list-style: none;
    pointer-events: none;
}
.journey-milestone {
    position: absolute;
    top: 50%;
    width: 16px;
    height: 16px;
    transform: translate(-50%, -50%);
    color: var(--line-strong, var(--ink-faint));
    transition: color 0.4s var(--ease-out), transform 0.4s var(--ease-out);
}
.journey-milestone svg {
    display: block;
    width: 100%;
    height: 100%;
}
.journey-milestone.reached {
    color: var(--saffron);
    transform: translate(-50%, -50%) scale(1.15);
}

/* =============================================================
   Forms
   ============================================================= */

.form-grid {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}
.form-grid label {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    font-size: 0.72rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ink-soft);
    font-weight: 500;
}
.row {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
}
.row label { flex: 1; min-width: 140px; }

input, select, textarea {
    font-family: inherit;
    font-size: 0.98rem;
    padding: 0.7rem 0.9rem;
    border: 1px solid var(--line);
    border-radius: 12px;
    background: var(--raised);
    color: var(--ink);
    text-transform: none;
    letter-spacing: 0;
    transition: border-color 0.18s, background 0.18s, box-shadow 0.18s;
}
.dark input, .dark select, .dark textarea {
    background: var(--surface);
}
input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--juniper);
    box-shadow: 0 0 0 3px var(--juniper-soft);
}
textarea { resize: vertical; min-height: 80px; }

.inline-form {
    display: flex;
    gap: 0.6rem;
    margin-top: 1rem;
    flex-wrap: wrap;
}
.inline-form input { flex: 1; min-width: 160px; }

.form-section-title {
    font-family: 'Fraunces', serif;
    font-size: 1.15rem;
    font-weight: 500;
    letter-spacing: -0.02em;
    color: var(--ink);
    margin: 0.6rem 0 0;
    padding-top: 1rem;
    border-top: 1px dashed var(--line);
}
.form-section-title:first-of-type { border-top: none; padding-top: 0; }

/* Profiilisivun kortti — yksi kortti per "Tallenna"-osio (who/goal/move…).
   Aiemmin sama inline-style toistui 7 kertaa templatessa. */
.profile-card {
    max-width: 720px;
    margin: 0 auto 1.2rem;
}
.profile-card .form-section-title { margin-top: 0; }

/* =============================================================
   Meal list & meal plan
   ============================================================= */

.meal-list {
    list-style: none;
    padding: 0;
    margin: 0;
}
.meal-list li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.95rem 0;
    border-bottom: 1px dashed var(--line);
    gap: 1rem;
}
.meal-list li:last-child { border-bottom: none; }
.meal-list .meal-type {
    font-size: 0.62rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--juniper);
    font-weight: 500;
}
.meal-list .meal-name {
    font-family: 'Fraunces', serif;
    font-size: 1.05rem;
    letter-spacing: -0.02em;
    line-height: 1.2;
    margin-top: 0.15rem;
    color: var(--ink);
}
.meal-list .meal-kcal {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.95rem;
    text-align: right;
}
.meal-list .meal-macros {
    font-size: 0.72rem;
    color: var(--ink-soft);
    text-align: right;
    margin-top: 0.15rem;
}

.meal-plan {
    background: var(--bg);
    border: 1px dashed var(--line);
    padding: 1rem 1.1rem;
    border-radius: 14px;
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.82rem;
    line-height: 1.5;
    white-space: pre-wrap;
    overflow-x: auto;
    color: var(--ink-soft);
    margin: 0.8rem 0 1rem;
}

/* Päivän kalorisumma kortin yläosassa */
.meal-total {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 1rem;
    padding: 0.65rem 0.9rem;
    margin-bottom: 1rem;
    border: 1px solid var(--line);
    border-radius: 0.6rem;
    background: var(--juniper-soft, rgba(0, 0, 0, 0.02));
}
.meal-total-label {
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-soft, inherit);
}
.meal-total-value {
    font-size: 1rem;
    font-weight: 600;
}

/* Päivän viisi ateriaa (kortit) */
.meal-cards {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
}
.meal-card {
    border: 1px solid var(--line);
    border-radius: 16px;
    padding: 1rem 1.1rem 1.1rem;
    background: var(--bg);
    scroll-margin-top: 90px;
    transition: border-color 0.2s ease, background-color 0.2s ease;
}
.meal-card-next {
    border-color: var(--juniper);
    background: var(--juniper-soft);
}
.meal-card-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.7rem;
}
.meal-card .meal-type {
    font-size: 0.62rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--juniper);
    font-weight: 600;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}
.meal-card .meal-next-tag {
    background: var(--juniper);
    color: var(--bg);
    font-size: 0.58rem;
    letter-spacing: 0.16em;
    padding: 0.15rem 0.45rem;
    border-radius: 999px;
}
.meal-card .meal-time {
    font-size: 1.25rem;
    font-weight: 500;
    color: var(--ink);
    margin-top: 0.15rem;
    letter-spacing: -0.01em;
}
.meal-card .meal-kcal {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.95rem;
    color: var(--ink);
    white-space: nowrap;
}
.meal-head-right {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.15rem;
}
/* Aterian makrot (proteiini/hiilari/rasva) pienenä rivinä tuotelistan alle. */
.meal-macros {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 0.9rem;
    margin-top: 0.5rem;
    padding-top: 0.5rem;
    border-top: 1px solid var(--line-soft);
    font-size: 0.8rem;
    color: var(--ink-soft);
    font-family: 'JetBrains Mono', monospace;
}
.meal-macro-label {
    color: var(--ink-faint);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-size: 0.72rem;
}
/* Aterian tavoitekalorit toteuman alla — himmeä pieni rivi vertailua varten. */
.meal-kcal-target {
    font-size: 0.72rem;
    color: var(--ink-soft);
    white-space: nowrap;
}
/* Toteuma yli tavoitteen: korosta saffranilla (ei virhe — käyttäjä voi valita
   tehdä isomman aterian, mutta näkee sen selvästi). */
.meal-kcal.meal-kcal-over { color: var(--saffron); }
.meal-products {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}
.meal-products li {
    font-family: 'Fraunces', serif;
    font-size: 1.05rem;
    line-height: 1.3;
    letter-spacing: -0.01em;
    color: var(--ink);
    padding-left: 0.9rem;
    position: relative;
}
.meal-products li::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0.65em;
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: var(--saffron);
}
.meal-product-kcal {
    color: var(--ink-soft);
    font-size: 0.82rem;
    margin-left: 0.25rem;
    white-space: nowrap;
}

/* Vaihtoehtokuplan tap-nappi näyttää täysin tavalliselta tekstiltä. */
.meal-product-tap {
    background: none;
    border: 0;
    padding: 0;
    margin: 0;
    font: inherit;
    color: inherit;
    text-align: left;
    cursor: pointer;
    line-height: inherit;
}
.meal-product-tap:focus-visible {
    outline: 2px solid var(--saffron);
    outline-offset: 2px;
    border-radius: 2px;
}
.meal-product-tap[aria-expanded="true"] {
    background: var(--saffron-soft);
}

.product-alts-bubble {
    position: absolute;
    left: 0.9rem;
    top: calc(100% + 0.35rem);
    z-index: 20;
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: 0.6rem;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.10);
    padding: 0.6rem 0.75rem;
    min-width: 12rem;
    max-width: min(22rem, calc(100vw - 2rem));
}
.product-alts-title {
    font-size: 0.68rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-soft);
    margin-bottom: 0.4rem;
}
.product-alts-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}
.product-alts-chip {
    background: var(--juniper-soft);
    color: var(--juniper);
    padding: 0.2rem 0.55rem;
    border-radius: var(--radius-pill);
    font-size: 0.72rem;
    line-height: 1.25;
    white-space: nowrap;
}
.product-alts-chip-grams {
    opacity: 0.85;
}
.product-alts-chip-cooked {
    font-size: 0.66rem;
    opacity: 0.7;
}
.product-alts-ask-label {
    font-size: 0.68rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-soft);
    margin: 0.55rem 0 0.3rem;
}
.product-alts-ask-form {
    display: flex;
    gap: 0.3rem;
    align-items: stretch;
}
.product-alts-ask-input {
    flex: 1 1 auto;
    min-width: 0;
    padding: 0.3rem 0.55rem;
    font: inherit;
    font-size: 0.85rem;
    border: 1px solid var(--line);
    border-radius: 0.4rem;
    background: var(--bg);
    color: var(--ink);
}
.product-alts-ask-input:focus-visible {
    outline: 2px solid var(--saffron);
    outline-offset: 1px;
    border-color: transparent;
}
.product-alts-ask-submit {
    padding: 0.3rem 0.7rem;
    font: inherit;
    font-size: 0.72rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    background: var(--ink);
    color: var(--bg);
    border: 0;
    border-radius: 0.4rem;
    cursor: pointer;
}
.product-alts-ask-submit:disabled { opacity: 0.5; cursor: default; }
.product-alts-result:empty { display: none; }
.product-alts-result { margin-top: 0.4rem; }
.product-alts-chip-unknown {
    background: var(--saffron-soft);
    color: var(--ink-soft);
    white-space: normal;
}
.week-day-products .product-alts-bubble {
    left: 0.7rem;
    top: calc(100% + 0.25rem);
}
.week-day-products .product-alts-chip {
    font-size: 0.66rem;
    padding: 0.15rem 0.45rem;
}
.week-day-products .product-alts-chip-cooked {
    font-size: 0.62rem;
}
.week-day-products .product-alts-ask-input,
.week-day-products .product-alts-ask-submit {
    font-size: 0.72rem;
}

.shopping-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
}
.shopping-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 1rem;
    padding: 0.55rem 0;
    border-bottom: 1px dotted var(--line);
}
.shopping-row:last-child { border-bottom: none; }
.shopping-name {
    font-family: 'Fraunces', serif;
    font-size: 1.05rem;
    color: var(--ink);
}
.shopping-amount {
    color: var(--ink-soft);
    font-size: 0.92rem;
    white-space: nowrap;
}

.week-days {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
}
.week-day {
    padding: 0.7rem 0.85rem;
    border-radius: 0.5rem;
    border: 1px solid var(--line);
    background: var(--bg);
}
.week-day-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.6rem;
}
.week-day-name {
    font-family: 'Fraunces', serif;
    font-size: 1rem;
    font-weight: 500;
    letter-spacing: -0.01em;
    color: var(--ink);
}
.week-day-kcal {
    font-size: 0.88rem;
    color: var(--ink-soft);
    white-space: nowrap;
}
.week-day-meals {
    list-style: none;
    padding: 0;
    margin: 0.5rem 0 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.week-day-meals > li {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}
.week-day-meal-head {
    display: grid;
    grid-template-columns: 1fr auto auto;
    gap: 0.5rem;
    font-size: 0.85rem;
    color: var(--ink-soft);
}
.week-day-meal-name {
    font-family: 'Fraunces', serif;
    color: var(--ink);
}
.week-day-meal-time { font-size: 0.78rem; opacity: 0.7; }
.week-day-meal-kcal { font-size: 0.78rem; }
.week-day-products {
    list-style: none;
    padding: 0;
    margin: 0.1rem 0 0.15rem 0.8rem;
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
}
.week-day-products li {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.6rem;
    font-size: 0.78rem;
    color: var(--ink-soft);
    line-height: 1.35;
    position: relative;
    padding-left: 0.7rem;
}
.week-day-products li::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0.55em;
    width: 3px;
    height: 3px;
    border-radius: 50%;
    background: var(--saffron);
    opacity: 0.6;
}
.week-day-product-kcal {
    font-size: 0.78rem;
    opacity: 0.8;
    white-space: nowrap;
}
.dotted-rule {
    background-image: radial-gradient(circle, var(--line) 1px, transparent 1px);
    background-size: 6px 6px;
    background-repeat: repeat-x;
    background-position: 0 50%;
    height: 6px;
    margin: 1.2rem 0;
}

/* =============================================================
   Meal plan review
   ============================================================= */

.meal-plan-review {
    border-top: 1px solid var(--line);
    padding-top: 1rem;
}
.review-sections {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}
.review-section {
    padding: 0;
}
.review-section-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.6rem;
}
.review-section-label {
    font-size: 0.82rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--ink);
}
.review-section-score {
    font-size: 0.82rem;
    color: var(--saffron);
    white-space: nowrap;
}
.review-bar {
    margin-top: 0.35rem;
    width: 100%;
    height: 4px;
    background: var(--line-soft);
    border-radius: 2px;
    overflow: hidden;
}
.review-bar-fill {
    display: block;
    height: 100%;
    background: var(--saffron);
    border-radius: 2px;
}
.review-section-text {
    margin: 0.4rem 0 0;
    font-size: 0.88rem;
    line-height: 1.45;
    color: var(--ink-soft);
}
.review-overall {
    margin-top: 1rem;
    padding: 0.7rem 0.85rem;
    background: var(--saffron-soft);
    border-radius: 6px;
}
.review-overall-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.6rem;
}
.review-overall-label {
    font-size: 0.82rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--ink);
}
.review-overall-score {
    font-size: 0.92rem;
    color: var(--saffron);
    font-weight: 600;
}
.review-overall-text {
    margin: 0.35rem 0 0;
    font-size: 0.88rem;
    line-height: 1.45;
    color: var(--ink);
}
.review-ideas {
    margin-top: 1rem;
}
.review-ideas-title {
    display: block;
    font-size: 0.82rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--ink);
    margin-bottom: 0.4rem;
}
.review-ideas-list {
    margin: 0;
    padding-left: 1.1rem;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    font-size: 0.88rem;
    line-height: 1.4;
    color: var(--ink-soft);
}
.review-raw {
    margin: 0;
    padding: 0.6rem 0.7rem;
    background: var(--line-soft);
    border-radius: 6px;
    font-size: 0.84rem;
    line-height: 1.4;
    white-space: pre-wrap;
    word-wrap: break-word;
}

/* =============================================================
   Weekly workout grid
   ============================================================= */

.week-strip {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 0.5rem;
}
.week-strip-day {
    text-align: center;
}
.week-strip-day .dayname {
    display: block;
    font-size: 0.62rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--ink-faint);
    margin-bottom: 0.4rem;
    font-weight: 500;
}
.week-strip-day.today .dayname { color: var(--juniper); font-weight: 600; }
.week-strip-day .cell {
    aspect-ratio: 1;
    border-radius: 16px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Fraunces', serif;
    font-size: 0.9rem;
    font-weight: 500;
    color: var(--ink-soft);
    background: var(--line-soft);
    overflow: hidden;
    padding: 4px;
    text-align: center;
    line-height: 1.05;
}
.week-strip-day.today .cell {
    background: var(--ink);
    color: var(--bg);
    border: 2px solid var(--juniper);
}
.week-strip-day.rest .cell {
    font-style: italic;
    font-variation-settings: 'opsz' 80, 'SOFT' 100;
    font-size: 0.7rem;
}

.week-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.7rem;
}
@media (min-width: 768px) {
    .week-grid { grid-template-columns: repeat(7, 1fr); }
}
.day-card {
    background: var(--surface);
    border: 1px solid var(--line);
    padding: 1rem;
    border-radius: 18px;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    min-height: 130px;
}
.day-card h3 {
    font-size: 0.62rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--ink-faint);
    font-weight: 500;
    margin: 0;
    font-family: 'Instrument Sans', sans-serif;
}
.day-card strong {
    font-family: 'Fraunces', serif;
    font-weight: 500;
    font-size: 1rem;
    letter-spacing: -0.02em;
    line-height: 1.15;
    color: var(--ink);
    display: block;
    margin-top: 0.2rem;
}
.day-card pre {
    margin: 0;
    font-family: 'Instrument Sans', sans-serif;
    font-size: 0.78rem;
    color: var(--ink-soft);
    white-space: pre-wrap;
    line-height: 1.4;
    margin-top: auto;
}
.day-card.today {
    background: var(--ink);
    color: var(--bg);
    border-color: transparent;
    box-shadow: 0 0 0 2px var(--juniper);
    position: relative;
}
.day-card.today h3 { color: rgba(255,255,255,0.6); }
.day-card.today strong { color: var(--bg); }
.day-card.today pre { color: rgba(255,255,255,0.75); }
.day-card.today::after {
    content: 'Tänään';
    position: absolute;
    top: 0.6rem;
    right: 0.6rem;
    font-size: 0.55rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    background: var(--juniper);
    color: var(--bg);
    padding: 0.15rem 0.45rem;
    border-radius: 999px;
    font-weight: 600;
}
.day-card em {
    font-family: 'Fraunces', serif;
    font-style: italic;
    font-variation-settings: 'opsz' 80, 'SOFT' 100;
    color: var(--ink-soft);
    font-size: 0.95rem;
}

/* Pinottu viikkonäkymä — päivät allekkain, tämänpäiväinen korostettuna */
.week-stack {
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
}
.week-stack .day-card {
    min-height: 0;
    padding: 1.1rem 1.2rem;
    scroll-margin-top: 1rem;
}
.week-stack .day-card h3 {
    font-size: 0.7rem;
}
.week-stack .day-card strong {
    font-size: 1.15rem;
    margin-top: 0.3rem;
}
.week-stack .day-card pre {
    font-size: 0.88rem;
    margin-top: 0.6rem;
}
.week-stack .day-card.today {
    box-shadow: 0 0 0 2px var(--juniper), 0 8px 24px -10px rgba(0,0,0,0.25);
}

/* Exercise list inside today card */
.exercise-list {
    background: var(--bg);
    border: 1px dashed var(--line);
    padding: 0.9rem 1rem;
    border-radius: 12px;
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.82rem;
    white-space: pre-wrap;
    color: var(--ink-soft);
    line-height: 1.55;
    margin: 0.6rem 0;
}

/* =============================================================
   Chat
   ============================================================= */

.chat-card {
    padding: 0;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    gap: 0;
}
.chat-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1.1rem 1.4rem;
    border-bottom: 1px solid var(--line);
}
.chat-header-left {
    display: flex;
    align-items: center;
    gap: 0.7rem;
}
.coach-avatar {
    width: 38px; height: 38px;
    border-radius: 50%;
    background: var(--juniper);
    color: var(--bg);
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Fraunces', serif;
    font-style: italic;
    font-variation-settings: 'opsz' 144, 'SOFT' 100;
    font-size: 1.15rem;
}
.coach-avatar-soft {
    background: var(--juniper-soft);
    color: var(--juniper);
    width: 32px; height: 32px;
    font-size: 1rem;
}
.live-dot {
    width: 8px; height: 8px;
    border-radius: 50%;
    background: var(--juniper);
    animation: softPulse 2.6s ease-in-out infinite;
}
.chat-status {
    font-size: 0.72rem;
    color: var(--ink-soft);
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-top: 0.1rem;
}

.chat-stream {
    max-height: 56vh;
    overflow-y: auto;
    padding: 1.6rem 1.2rem;
    display: flex;
    flex-direction: column;
    gap: 1.6rem;
    scroll-behavior: smooth;
}
.chat-stream::-webkit-scrollbar { width: 6px; }
.chat-stream::-webkit-scrollbar-thumb { background: var(--line); border-radius: 3px; }

.chat-row {
    display: flex;
    gap: 0.7rem;
    max-width: 92%;
}
.chat-row.user {
    align-self: flex-end;
    justify-content: flex-end;
}
.chat-row.assistant .chat-content {
    flex: 1;
}
.chat-row.assistant .chat-bubble {
    font-family: 'Fraunces', serif;
    font-variation-settings: 'opsz' 80, 'SOFT' 80;
    font-size: 1.05rem;
    line-height: 1.4;
    letter-spacing: -0.015em;
    color: var(--ink);
}
.chat-row.assistant .chat-bubble em {
    font-style: italic;
    color: var(--juniper);
}
.chat-row.user .chat-bubble {
    background: var(--ink);
    color: var(--bg);
    padding: 0.7rem 1rem;
    border-radius: 18px 18px 6px 18px;
    font-size: 0.95rem;
    line-height: 1.45;
}
.chat-bubble { white-space: pre-wrap; word-wrap: break-word; margin: 0; }
.chat-time {
    font-size: 0.62rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ink-faint);
    margin-top: 0.25rem;
    font-weight: 500;
}
.chat-row.user .chat-time { text-align: right; }

.chat-date-divider {
    text-align: center;
    font-size: 0.6rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--ink-faint);
    font-weight: 500;
}

.chat-form {
    display: flex;
    align-items: flex-end;
    gap: 0.5rem;
    padding: 0.75rem;
    background: var(--raised);
    border-top: 1px solid var(--line);
}
.chat-form textarea {
    flex: 1;
    border: 1px solid var(--line);
    border-radius: 16px;
    background: var(--bg);
    padding: 0.7rem 0.9rem;
    font-size: 0.95rem;
    max-height: 120px;
    min-height: 44px;
    text-transform: none;
    letter-spacing: 0;
}
.chat-form button { flex-shrink: 0; }

/* =============================================================
   Context strip (chat sivun alaosa)
   ============================================================= */

.context-strip {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.7rem;
    margin-top: 1.4rem;
}
@media (min-width: 768px) {
    .context-strip { grid-template-columns: repeat(4, 1fr); }
}
.context-tile {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 16px;
    padding: 0.95rem 1rem;
}
.context-tile .label {
    font-size: 0.6rem;
    margin-bottom: 0.35rem;
    display: block;
}
.context-tile .value {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.95rem;
    color: var(--ink);
}

/* =============================================================
   Flash messages
   ============================================================= */

.flash {
    padding: 0.85rem 1.1rem;
    border-radius: 14px;
    margin-bottom: 1rem;
    font-weight: 500;
    font-size: 0.95rem;
    border: 1px solid transparent;
}
.flash-success {
    background: var(--juniper-soft);
    color: var(--juniper);
    border-color: rgba(47, 80, 67, 0.2);
}
.flash-error {
    background: rgba(155, 56, 56, 0.08);
    color: var(--danger);
    border-color: rgba(155, 56, 56, 0.25);
}

/* Taustagenerointi-banneri ravinto-sivulla — saffron-sävyinen, kelluvalla
   spinnerillä joka pyörii niin kauan kuin jobi on käynnissä. */
.bg-job-banner {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.85rem 1.1rem;
    border-radius: 14px;
    background: var(--saffron-soft);
    color: var(--saffron);
    border: 1px solid rgba(185, 111, 59, 0.25);
    font-weight: 500;
    font-size: 0.95rem;
}
.bg-job-banner[hidden] { display: none; }
.bg-job-banner-spinner {
    display: inline-flex;
    color: var(--saffron);
    animation: bg-job-spin 1.4s linear infinite;
}
.bg-job-banner-spinner svg circle {
    stroke-dasharray: 60 40;
}
.bg-job-banner.is-done .bg-job-banner-spinner,
.bg-job-banner.is-error .bg-job-banner-spinner {
    animation: none;
}
.bg-job-banner-link {
    color: inherit;
    text-decoration: underline;
    cursor: pointer;
}
@keyframes bg-job-spin {
    to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
    .bg-job-banner-spinner { animation: none !important; }
}

/* "Suunnitelma kannattaisi päivittää" — pehmeämpi juniper-värinen kuin
   ajossa-oleva job-banneri, jotta ne erottuvat toisistaan visuaalisesti. */
.plan-stale-banner {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.85rem 1.1rem;
    border-radius: 14px;
    background: var(--juniper-soft);
    color: var(--juniper);
    border: 1px solid rgba(47, 80, 67, 0.22);
    font-size: 0.95rem;
}
.dark .plan-stale-banner {
    border-color: rgba(141, 189, 161, 0.28);
}
.plan-stale-banner-title {
    font-weight: 600;
    letter-spacing: -0.01em;
}
.plan-stale-banner-reasons {
    margin: 0;
    padding-left: 1.1rem;
    color: var(--ink);
    font-size: 0.9rem;
    line-height: 1.4;
}
.plan-stale-banner-actions {
    display: flex;
    justify-content: flex-end;
    margin-top: 0.2rem;
}

/* =============================================================
   Animations
   ============================================================= */

@keyframes rise {
    from { opacity: 0; transform: translateY(14px); }
    to   { opacity: 1; transform: translateY(0); }
}
.rise { animation: rise 0.7s var(--ease-out) both; }
.rise-1 { animation-delay: 0.04s; }
.rise-2 { animation-delay: 0.10s; }
.rise-3 { animation-delay: 0.18s; }
.rise-4 { animation-delay: 0.26s; }
.rise-5 { animation-delay: 0.34s; }
.rise-6 { animation-delay: 0.42s; }
.rise-7 { animation-delay: 0.50s; }
.rise-8 { animation-delay: 0.58s; }

@keyframes drawRing {
    from { stroke-dashoffset: var(--ring-circ); }
}

@keyframes softPulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(141, 189, 161, 0.45); }
    50%      { box-shadow: 0 0 0 8px rgba(141, 189, 161, 0); }
}

@media (prefers-reduced-motion: reduce) {
    .rise, .live-dot { animation: none !important; }
    .live-dot { box-shadow: none !important; }
    *, *::before, *::after { transition: none !important; }
}

/* =============================================================
   Utilities
   ============================================================= */

.flex-between {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
}
.text-soft { color: var(--ink-soft); }
.text-faint { color: var(--ink-faint); }
.text-juniper { color: var(--juniper); }
.text-saffron { color: var(--saffron); }
.text-center { text-align: center; }
.text-xs { font-size: 0.78rem; }
.text-sm { font-size: 0.85rem; }
.no-underline { text-decoration: none; }

/* Spacing-utilityt. Nimet noudattavat skaalaa
   3xs(0.2)→2xs(0.3)→xs(0.4)→sm(0.6)→md-tight(0.8)→md(1)→md-lg(1.5)→lg(1.6)→xl(2).
   Eri arvot (1.5 vs 1.6) säilytetään tietoisesti — ne ovat alkuperäisiä
   design-päätöksiä eikä niitä yhdistetä ilman erillistä keskustelua. */
.m-0 { margin: 0; }
.mt-3xs { margin-top: 0.2rem; }
.mt-2xs { margin-top: 0.3rem; }
.mt-xs  { margin-top: 0.4rem; }
.mt-sm  { margin-top: 0.6rem; }
.mt-md  { margin-top: 1rem; }
.mt-md-tight { margin-top: 0.8rem; }
.mt-lg  { margin-top: 1.6rem; }
.mt-neg-sm { margin-top: -0.4rem; }
.mb-md  { margin-bottom: 1.5rem; }
.mb-lg  { margin-bottom: 1.6rem; }
.mb-xl  { margin-bottom: 2rem; }

/* Form-grid-utilityt: lomakekenttä joka venyy mutta ei mene alle 200px:n
   leveiseksi. Käytetään profiili- ja onboarding-sivuilla parittain. */
.field-200 { flex: 1; min-width: 200px; }

/* Page-width-utilityt: hero- ja form-card -leveydet auth-sivuille (kapea
   460px) sekä onboarding/profiili-sivuille (medium 720px). Marginit ovat
   `auto`-keskityksiä yhdessä joko ylä-/alavälit-utilityilla tai itse luokassa.*/
.page-narrow { max-width: 460px; margin-left: auto; margin-right: auto; }
.page-medium { max-width: 720px; margin-left: auto; margin-right: auto; }

/* Auth/onboarding-sivujen brand-blocki — toistuu 3 kertaa identtisesti
   (login/register/onboarding). Sisältää logon (.topbar-mark-lg + .brand-wordmark
   + .label) sekä otsikon. .topbar-mark-lg laajentaa olemassa olevan
   .topbar-markin 44×44 px:iin Hero-käyttöä varten. */
.brand-header {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    margin-bottom: 2rem;
}
.brand-wordmark {
    font-family: 'Fraunces', serif;
    font-size: 1.3rem;
    font-weight: 500;
    letter-spacing: -0.025em;
    line-height: 1;
}
.topbar-mark-lg {
    width: 44px;
    height: 44px;
    font-size: 1.5rem;
}

/* Dashboard-tilastolaatan klikkaava linkki — 3 paikassa dashboardissa
   sama anchor-wrapperi tilastokorttien sisällä. */
.dash-stat-link {
    text-decoration: none;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

/* Auth/onboarding/profiili-sivujen "intro"-leipätekstin koko ja max-leveys.
   Tekstien tarkka käyttötarkoitus näkyy template-puolelta — täällä vain
   typografinen säätö, käytetään yhdessä .text-soft.mt-md -luokkien kanssa. */
.intro-text {
    max-width: 50ch;
    font-size: 1.02rem;
    line-height: 1.5;
}
/* Leveämpi intro-variantti listoille (nutrition_guidelines, shopping_list). */
.intro-text.intro-text-wide { max-width: 56ch; }

/* Fraunces-nosto leipätekstin sisällä: ravinto- ja dashboard-sivuilla
   käytetty 1.1–1.2rem korostuslause. Aiemmin sama tyyli toistui inline.
   Modifier .fraunces-note-lg nostaa 1.2rem käyttöön (dashin pulse-vastaus). */
.fraunces-note {
    font-family: 'Fraunces', serif;
    font-variation-settings: 'opsz' 80, 'SOFT' 80;
    font-size: 1.1rem;
    line-height: 1.4;
    letter-spacing: -0.02em;
    margin: 0.6rem 0 0.8rem;
}
.fraunces-note-lg { font-size: 1.2rem; }
.fraunces-note-pre { white-space: pre-wrap; }
.fraunces-note-mt-md { margin: 1rem 0 0; }

/* Coach pill (.coach-pill) -laatikon sisältöteksti: pieni otsikko + alateksti.
   Käytetään sekä side-railissa että dashboardin koko-leveydellä. */
.coach-pill-title { font-size: 0.92rem; font-weight: 500; }
.coach-pill-sub { font-size: 0.78rem; color: var(--ink-soft); }
.coach-pill-sub-dark {
    font-size: 0.7rem;
    color: rgba(255,255,255,0.55);
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

/* Mono-figure: JetBrains Mono -tyylinen luku exercise-sivun korttirivissä
   ja admin-näkymien yläkulmissa. Aiemmin inline 1.6rem / 1.4rem useassa
   paikassa — siirretty luokkaan jotta drift loppuu. */
.mono-figure {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 1.6rem;
    font-weight: 500;
    letter-spacing: -0.02em;
    line-height: 1.15;
}
.mono-figure-sm {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 1.4rem;
    font-weight: 500;
    letter-spacing: -0.02em;
    line-height: 1.15;
}

/* Admin-sivujen pienet apumerkinnät */
.admin-mono-code {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 1.25rem;
    margin: 0;
}
.admin-hint-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.8rem;
    font-size: 0.85rem;
}
.admin-hint-right { text-align: right; font-size: 0.85rem; }
.admin-email { font-size: 1.15rem; font-weight: 500; }
.admin-admin-tag { color: var(--saffron); font-weight: 500; }
.admin-figure-row {
    font-size: 1.4rem;
    font-weight: 500;
    margin-top: 0.15rem;
}
.admin-meta { font-size: 0.8rem; }
.admin-meta-right { font-size: 0.82rem; text-align: right; }
.admin-meta-row { font-size: 0.82rem; }
.admin-title-small { font-size: 0.6em; font-weight: 400; }
.admin-email-row { font-weight: 500; }
.admin-figure-meta {
    font-size: 0.95rem;
    text-align: right;
}

/* Adminin lokinäkymän rivi. `details/summary` — klikattava avaus.
   Väri viestii tason: keltainen varoitus, punainen virhe. */
.log-row {
    border: 1px solid var(--rule);
    border-radius: 6px;
    padding: 0.4rem 0.6rem;
    background: var(--card-bg, transparent);
}
.log-row + .log-row { margin-top: 0.35rem; }
.log-row summary {
    cursor: pointer;
    display: grid;
    grid-template-columns: 8.5rem 5rem 1fr;
    align-items: baseline;
    gap: 0.6rem;
    list-style: none;
}
.log-row summary::-webkit-details-marker { display: none; }
.log-time { font-size: 0.82rem; color: var(--muted, inherit); }
.log-level {
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    padding: 0.05rem 0.4rem;
    border-radius: 3px;
    text-align: center;
}
.log-level-warning { background: rgba(233, 178, 47, 0.18); color: var(--saffron); }
.log-level-error,
.log-level-critical { background: rgba(196, 74, 60, 0.18); color: #b23a2b; }
.log-msg {
    font-size: 0.9rem;
    overflow-wrap: anywhere;
}
.log-body { margin-top: 0.5rem; padding-left: 0.2rem; }
.log-traceback {
    font-size: 0.78rem;
    background: rgba(0,0,0,0.04);
    padding: 0.5rem 0.7rem;
    border-radius: 4px;
    white-space: pre-wrap;
    overflow-x: auto;
    max-height: 20rem;
}
.dark .log-traceback { background: rgba(255,255,255,0.05); }

/* Dashin valmentaja-kortin "Avaa chat" -linkki tumman taustan päällä:
   katkoviiva-alleviivaus, ei btn-tyyliä jotta kortti pysyy keskiössä. */
.chat-cta-link {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    margin-top: 1.4rem;
    padding: 0 0 0.15rem;
    border: 0;
    border-bottom: 1px dashed rgba(255,255,255,0.4);
    background: transparent;
    color: var(--bg);
    text-decoration: none;
    font-family: inherit;
    font-size: 0.92rem;
    cursor: pointer;
}

/* Onboarding: piilota nav */
body.no-nav .bottom-nav,
body.no-nav .side-rail { display: none !important; }
body.no-nav .app-shell { display: block; }

/* =============================================================
   Valmentaja-chat: kuplapaneeli sivun päällä
   ============================================================= */

/* Nav-painikkeet ulkonäöltään kuin linkit */
.nav-chat-btn {
    all: unset;
    box-sizing: border-box;
    cursor: pointer;
    font-family: inherit;
}
.bottom-nav-chat {
    all: unset;
    box-sizing: border-box;
    cursor: pointer;
    font-family: inherit;
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    padding: 0.45rem 0.25rem;
    font-size: 0.6rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    font-weight: 500;
    color: var(--ink-soft);
    border-radius: 12px;
    text-align: center;
    transition: background 0.2s, color 0.2s;
}
.bottom-nav-chat svg { width: 20px; height: 20px; stroke-width: 1.6; }
.bottom-nav-chat:hover { color: var(--ink); }
body.chat-open .bottom-nav-chat {
    color: var(--ink);
    background: var(--juniper-soft);
}
body.chat-open .bottom-nav-chat svg { color: var(--juniper); }

@media (min-width: 768px) {
    .side-rail nav .nav-chat-btn {
        display: block;
        font-size: 0.98rem;
        padding: 0.55rem 0.85rem;
        border-radius: 12px;
        color: var(--ink-soft);
        position: relative;
        transition: color 0.2s, background 0.2s;
        width: 100%;
        text-align: left;
    }
    .side-rail nav .nav-chat-btn:hover {
        color: var(--ink);
        background: var(--line-soft);
    }
    body.chat-open .side-rail nav .nav-chat-btn {
        color: var(--ink);
        background: var(--juniper-soft);
    }
    body.chat-open .side-rail nav .nav-chat-btn::before {
        content: '';
        position: absolute;
        left: -8px;
        top: 50%;
        transform: translateY(-50%);
        width: 3px;
        height: 60%;
        border-radius: 999px;
        background: var(--juniper);
    }
}

/* Paneeli */
.chat-panel {
    position: fixed;
    inset: 0;
    z-index: 1000;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.18s ease;
}
.chat-panel.is-open {
    pointer-events: auto;
    opacity: 1;
}
.chat-panel-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(14, 20, 17, 0.42);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
}
.chat-panel-sheet {
    position: absolute;
    inset: 0;
    background: var(--raised);
    display: flex;
    flex-direction: column;
    transform: translateY(12px);
    transition: transform 0.22s ease;
    box-shadow: var(--shadow-lifted);
    padding-bottom: env(safe-area-inset-bottom);
}
.chat-panel.is-open .chat-panel-sheet { transform: translateY(0); }

.chat-panel-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1rem 1.2rem;
    border-bottom: 1px solid var(--line);
    background: var(--raised);
}
.chat-panel-title {
    font-size: 0.98rem;
    font-weight: 500;
}
.chat-panel-close {
    all: unset;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    color: var(--ink-soft);
    transition: background 0.15s, color 0.15s;
}
.chat-panel-close:hover {
    background: var(--line-soft);
    color: var(--ink);
}
.chat-header-actions {
    display: flex;
    align-items: center;
    gap: 0.2rem;
}

.chat-panel-stream {
    max-height: none;
    flex: 1;
    min-height: 0;
}

/* AI Act Art. 50 -avoimuusvelvoite: pysyvä merkintä että käyttäjä keskustelee
   tekoälyn kanssa. Pidetään hillittynä mutta lukukelpoisena — ei painike-värejä,
   selvä rajaviiva alapuolelle erottamaan viestivirrasta. */
.chat-ai-notice {
    padding: 0.55rem 1.2rem;
    font-size: 0.78rem;
    line-height: 1.4;
    color: var(--ink-soft);
    background: var(--raised);
    border-bottom: 1px solid var(--line);
}

/* Suunnitelma- ja ohjelma-sivujen AI-merkintä (otsikon alla). Pieni mutta
   selkeä — käyttäjä näkee heti että sisältö on tekoälyn tuottamaa. */
.ai-notice {
    margin: 0.4rem 0 0;
    padding: 0.55rem 0.8rem;
    font-size: 0.78rem;
    line-height: 1.4;
    color: var(--ink-soft);
    background: var(--raised);
    border-left: 3px solid var(--juniper);
    border-radius: 0 6px 6px 0;
}

.chat-panel-form {
    padding: 0.75rem 0.9rem calc(0.9rem + env(safe-area-inset-bottom));
}

/* Valmiit kysymykset: vapaan tekstin sijaan käyttäjä valitsee näistä. */
.chat-presets {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    padding: 0.75rem 0.9rem calc(0.9rem + env(safe-area-inset-bottom));
    background: var(--raised);
    border-top: 1px solid var(--line);
}
.chat-preset-btn {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    width: 100%;
    text-align: left;
    border: 1px solid var(--line);
    border-radius: 14px;
    background: var(--bg);
    color: var(--ink);
    padding: 0.65rem 0.85rem;
    font-size: 0.9rem;
    line-height: 1.3;
    text-transform: none;
    letter-spacing: 0;
    cursor: pointer;
    transition: background 0.15s var(--ease-out), border-color 0.15s var(--ease-out);
}
.chat-preset-btn:hover:not(:disabled) {
    border-color: var(--juniper);
    background: var(--surface);
}
.chat-preset-btn svg {
    flex-shrink: 0;
    color: var(--juniper);
    opacity: 0.7;
}
.chat-presets.is-loading .chat-preset-btn,
.chat-preset-btn:disabled {
    opacity: 0.5;
    cursor: default;
}

/* Striimaava kupla: kursori-pulssi tekstin perässä */
.chat-bubble.is-streaming::after {
    content: '▍';
    display: inline-block;
    margin-left: 2px;
    color: var(--juniper);
    animation: caretBlink 0.9s steps(2, end) infinite;
}
@keyframes caretBlink {
    50% { opacity: 0; }
}

/* Desktop: paneeli ankkuroituu oikealle, ei koko ruutua */
@media (min-width: 768px) {
    .chat-panel-sheet {
        inset: auto 1.5rem 1.5rem auto;
        width: min(440px, 92vw);
        height: min(720px, 88vh);
        border-radius: 18px;
        border: 1px solid var(--line);
        overflow: hidden;
        transform: translateY(20px);
    }
    .chat-panel.is-open .chat-panel-sheet { transform: translateY(0); }
}

/* ---------- Valmentajan puhekuplat ---------- */
/* Lukematta jääneet assistant-viestit kelluvat oikeassa alanurkassa.
   Mobiilissa nostetaan bottom-navin yläpuolelle; desktopissa istuvat
   chat-paneelin tilaa kunnioittaen alemmas. */
.coach-bubbles {
    position: fixed;
    right: 1rem;
    bottom: calc(96px + env(safe-area-inset-bottom));
    z-index: 60;
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
    max-width: min(22rem, calc(100vw - 2rem));
    pointer-events: none;
    transition: opacity 0.2s ease;
}
.coach-bubbles.is-dismissing { opacity: 0; }
@media (min-width: 768px) {
    .coach-bubbles { bottom: 1.5rem; right: 1.5rem; }
}
.coach-bubble {
    pointer-events: auto;
    background: var(--raised, var(--bg));
    border: 1px solid var(--line);
    border-radius: 18px 18px 6px 18px;
    padding: 0.65rem 0.8rem 0.7rem 0.7rem;
    box-shadow: 0 14px 32px -16px rgba(0, 0, 0, 0.35);
    display: flex;
    align-items: flex-start;
    gap: 0.55rem;
    cursor: pointer;
    animation: bubbleIn 0.28s ease-out;
    color: var(--ink);
}
.coach-bubble:focus-visible {
    outline: 2px solid var(--juniper);
    outline-offset: 2px;
}
.coach-bubble.is-dismissing {
    opacity: 0;
    transform: translateX(16px);
    transition: opacity 0.18s ease, transform 0.18s ease;
}
@keyframes bubbleIn {
    from { opacity: 0; transform: translateY(8px) scale(0.98); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
}
.coach-bubble .coach-avatar-soft {
    flex-shrink: 0;
    margin-top: 0.1rem;
}
.coach-bubble-text {
    margin: 0;
    font-family: 'Fraunces', serif;
    font-size: 0.95rem;
    line-height: 1.35;
    color: var(--ink);
    flex: 1 1 auto;
    min-width: 0;
    white-space: pre-wrap;
    display: -webkit-box;
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.coach-bubble-close {
    flex-shrink: 0;
    background: transparent;
    border: none;
    color: var(--ink-soft, var(--ink));
    cursor: pointer;
    padding: 0.2rem;
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    opacity: 0.6;
    transition: opacity 0.15s ease, background-color 0.15s ease;
}
.coach-bubble-close:hover,
.coach-bubble-close:focus-visible {
    opacity: 1;
    background: var(--line);
    outline: none;
}

/* ---------- Latausoverlay ---------- */
.loading-overlay {
    position: fixed;
    inset: 0;
    z-index: 1100;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
    background: rgba(20, 30, 25, 0.45); /* fallback */
    background: color-mix(in srgb, var(--bg) 88%, transparent);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
}
.loading-overlay.is-visible {
    display: flex;
    animation: loadingFadeIn 0.25s ease-out;
}
.loading-overlay-card {
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: 22px;
    padding: 2.4rem 2rem 2rem;
    max-width: 26rem;
    width: 100%;
    text-align: center;
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.18);
}
.loading-spinner {
    color: var(--juniper);
    width: 56px;
    height: 56px;
    margin: 0 auto 1.4rem;
}
.loading-spinner svg {
    width: 100%;
    height: 100%;
    animation: loadingSpin 1.4s linear infinite;
}
.loading-spinner circle {
    stroke-dasharray: 60 100;
}
.loading-overlay-title {
    font-family: 'Fraunces', serif;
    font-variation-settings: 'opsz' 80, 'SOFT' 60;
    font-size: 1.55rem;
    font-weight: 400;
    letter-spacing: -0.02em;
    margin: 0 0 0.5rem;
    color: var(--ink);
}
.loading-overlay-hint {
    color: var(--ink-soft);
    font-size: 0.98rem;
    line-height: 1.45;
    margin: 0 0 1.4rem;
    min-height: 2.9em;
    transition: opacity 0.22s ease;
}
.loading-overlay-time {
    color: var(--ink-faint);
    font-size: 0.78rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    margin: 0;
}
@keyframes loadingSpin { to { transform: rotate(360deg); } }
@keyframes loadingFadeIn { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
    .loading-overlay.is-visible { animation: none; }
    .loading-spinner svg { animation-duration: 2.5s; }
}

/* ----- Ohjeet (help toggles & panel) -----
   Kaksi UI-rakennetta:
   1) .help-toggle — pieni (?)-painike kentän legendin perään. Klikkaus avaa
      lyhyen selityksen kentän sisään, ilman JS:ää (<details>+<summary>).
   2) .help-panel — sivun yläosaan upotettava "Ohjeet"-paneeli, jossa
      luetelmana 3–5 ohjenuoraa. Suljettu oletuksena; ei häiritse vakikäyttäjää
      mutta on aina löydettävissä.
   Molemmat käyttävät natiivia <details>-elementtiä — sama kaava kuin
   DailyCheckin-osiossa, ei uutta JS-riippuvuutta. */

/* Kenttäkohtainen (?)-painike — sijoittuu legendin viereen flexillä.
   .help-toggle käyttää display: contents -temppua: <summary> ja <p>-body
   nousevat .dash-checkin-legend-row:n suoriksi flex-lapsiksi, jolloin
   body voi flex-wrapata uudelle riville (flex-basis: 100%). Tämä on ainoa
   tapa saada natiivi <details> näyttämään body itsenäisenä lohkona ilman
   JS:ää tai absoluuttista sijoittelua. */
.dash-checkin-legend-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.35rem;
}
.help-toggle {
    display: contents;
}
.help-toggle > summary {
    list-style: none;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    -webkit-tap-highlight-color: transparent;
    /* Iso kosketuspinta mobiilissa: ikoni on 18px, mutta summary 28px. */
    width: 1.75rem;
    height: 1.75rem;
    border-radius: 50%;
    transition: background 0.15s ease;
}
.help-toggle > summary::-webkit-details-marker { display: none; }
.help-toggle > summary:hover,
.help-toggle > summary:focus-visible {
    background: var(--juniper-soft);
    outline: none;
}
.help-toggle-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.05rem;
    height: 1.05rem;
    border-radius: 50%;
    background: transparent;
    border: 1px solid var(--ink-faint, var(--ink-soft));
    color: var(--ink-soft);
    font-size: 0.72rem;
    font-weight: 600;
    line-height: 1;
    font-family: 'Instrument Sans', sans-serif;
}
.help-toggle[open] .help-toggle-icon {
    background: var(--juniper);
    border-color: var(--juniper);
    color: #fff;
}
.help-toggle-body {
    /* Selitysteksti virtaa kentän alle koko leveydeltä — flex-container
       rikotaan tällä, joten body näkyy uudella rivillä. */
    flex-basis: 100%;
    margin: 0.4rem 0 0;
    padding: 0.55rem 0.75rem;
    background: var(--juniper-soft);
    border-radius: 10px;
    font-size: 0.78rem;
    line-height: 1.4;
    color: var(--ink);
}
/* Lyhyt asteikkoselite (esim. "1 = jatkuvasti nälkä · 5 = ei nälkää")
   saman (?)-paneelin sisällä, omalla rivillä ja vaaleammalla sävyllä,
   jotta se erottuu pidemmästä ohjetekstistä. */
.help-toggle-hint {
    display: block;
    margin-top: 0.35rem;
    font-size: 0.72rem;
    color: var(--ink-soft);
}

/* Sivun yläosan "Ohjeet"-paneeli. Suljettu oletuksena, klikkauksesta auki. */
.help-panel {
    margin-bottom: 1.5rem;
    border: 1px solid var(--line-soft);
    border-radius: var(--radius-card, 14px);
    background: var(--bg-card, transparent);
    overflow: hidden;
}
.help-panel-summary {
    list-style: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.7rem 1rem;
    -webkit-tap-highlight-color: transparent;
    position: relative;
}
.help-panel-summary::-webkit-details-marker { display: none; }
.help-panel-summary:hover { background: var(--juniper-soft); }
.help-panel-summary-text {
    color: var(--ink-soft);
    font-size: 0.88rem;
    flex: 1;
}
.help-panel-chev {
    color: var(--ink-faint, var(--ink-soft));
    font-size: 1.1rem;
    transition: transform 0.18s ease;
    transform: rotate(90deg);
}
.help-panel[open] .help-panel-chev { transform: rotate(-90deg); }
.help-panel-list {
    list-style: none;
    margin: 0;
    padding: 0.2rem 1rem 0.9rem 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
}
.help-panel-list li {
    position: relative;
    padding-left: 1.1rem;
    font-size: 0.9rem;
    line-height: 1.5;
    color: var(--ink);
}
.help-panel-list li::before {
    content: '·';
    position: absolute;
    left: 0.3rem;
    top: -0.05rem;
    color: var(--saffron);
    font-weight: 700;
    font-size: 1.2rem;
}

@media (prefers-reduced-motion: reduce) {
    .help-panel-chev,
    .help-toggle > summary { transition: none; }
}

/* =============================================================
   Auth (login/register) — two-pane editorial layout
   ============================================================= */

/* a11y utility: hidden visually but readable for screen readers. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* Outer grid. Single column on mobile (cover above panels), splits to
   two columns ≥920px so the value-prop and the form share the viewport
   without forcing scroll on a laptop. */
.auth-shell {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.6rem;
    max-width: 460px;
    margin: 0.4rem auto 2rem;
}
@media (min-width: 920px) {
    .auth-shell {
        grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
        gap: 3.2rem;
        max-width: 1040px;
        margin-top: 2rem;
        align-items: center;
    }
}

.auth-cover { position: relative; }

/* Soft hero glow behind the wordmark. Honors --gradient-hero so it
   automatically picks up the light/dark token. Pointer-events off so the
   form remains the focal interaction. */
.auth-cover::before {
    content: '';
    position: absolute;
    inset: -10% -8% 30% -8%;
    background: var(--gradient-hero);
    border-radius: 40px;
    z-index: -1;
    pointer-events: none;
    opacity: 0.9;
}

.auth-subhead {
    color: var(--ink-soft);
    font-size: 1.02rem;
    line-height: 1.55;
    max-width: 38ch;
    margin: 1.1rem 0 1.8rem;
}

/* Chip strip directly under the hero — keeps the trust signals high in
   the visual hierarchy without screaming. */
.auth-chip-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0 0 1.6rem;
}
.auth-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0.7rem 0.35rem 0.55rem;
    background: var(--juniper-soft);
    color: var(--juniper);
    border-radius: var(--radius-pill);
    font-size: 0.74rem;
    font-weight: 500;
    letter-spacing: 0.02em;
    line-height: 1;
}
.auth-chip svg {
    width: 13px;
    height: 13px;
    stroke: currentColor;
    fill: none;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* Benefits list — light editorial rhythm, each row a small icon + line. */
.benefit-list {
    list-style: none;
    padding: 0;
    margin: 0 0 1.8rem;
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}
.benefit-item {
    display: grid;
    grid-template-columns: 28px 1fr;
    gap: 0.85rem;
    align-items: start;
    font-size: 0.96rem;
    line-height: 1.4;
    color: var(--ink);
}
.benefit-icon {
    width: 28px;
    height: 28px;
    border-radius: 9px;
    background: var(--juniper-soft);
    color: var(--juniper);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.benefit-icon svg {
    width: 16px;
    height: 16px;
    stroke: currentColor;
    fill: none;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* Trust line — single understated row near the bottom of the cover. */
.trust-line {
    display: flex;
    align-items: flex-start;
    gap: 0.55rem;
    color: var(--ink-soft);
    font-size: 0.82rem;
    line-height: 1.45;
    padding-top: 1rem;
    border-top: 1px dashed var(--line);
    max-width: 44ch;
}
.trust-line svg {
    width: 16px;
    height: 16px;
    stroke: var(--juniper);
    fill: none;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
    flex-shrink: 0;
    margin-top: 0.15rem;
}

/* Right column wrapper — vertical stack of language picker + form card. */
.auth-panels {
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
    width: 100%;
}

/* Compact, refined replacement for the inline-styled language card. */
.auth-lang-bar {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.55rem 0.85rem;
    border-radius: 14px;
    background: var(--surface);
    border: 1px solid var(--line);
    font-size: 0.85rem;
    color: var(--ink-soft);
    margin: 0;
}
.auth-lang-bar svg {
    width: 16px;
    height: 16px;
    stroke: var(--ink-faint);
    fill: none;
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
    flex-shrink: 0;
}
.auth-lang-bar .auth-lang-control {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin: 0;
    text-transform: none;
    letter-spacing: 0;
    font-weight: 400;
    font-size: 0.85rem;
    color: var(--ink-soft);
}
.auth-lang-bar select {
    flex: 1;
    padding: 0.35rem 0.5rem;
    font-size: 0.88rem;
    border-radius: 9px;
    background: var(--raised);
}

/* Form card — same .card foundation, but extra padding rhythm and a
   subtle on-load lift so the form reads as the primary surface. */
.auth-card {
    padding: 1.6rem 1.4rem 1.4rem;
    box-shadow: var(--shadow-lifted);
}
@media (min-width: 768px) {
    .auth-card { padding: 2.1rem 2rem 1.8rem; }
}
.auth-card-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.4rem;
}
.auth-card-title {
    font-family: 'Fraunces', serif;
    font-variation-settings: 'opsz' 144, 'SOFT' 40;
    font-size: 1.2rem;
    font-weight: 500;
    letter-spacing: -0.02em;
    color: var(--ink);
    margin: 0;
}
.auth-card-eyebrow {
    font-size: 0.66rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--ink-faint);
    font-weight: 500;
}

/* Input field polish — pair the existing input baseline with a richer
   focus ring + soft label-rest treatment for the email/password block. */
.auth-card .form-grid { gap: 0.95rem; }
.auth-card input[type="email"],
.auth-card input[type="password"],
.auth-card input[type="text"] {
    padding: 0.85rem 1rem;
    border-radius: 14px;
    font-size: 1rem;
    background: var(--raised);
    transition: border-color 0.2s var(--ease-out),
                box-shadow 0.2s var(--ease-out),
                background 0.2s var(--ease-out);
}
.auth-card input:hover { border-color: var(--ink-faint); }
.auth-card input:focus {
    border-color: var(--juniper);
    box-shadow: 0 0 0 4px var(--juniper-soft);
}

/* Primary CTA enlargement for the auth form. */
.auth-cta {
    align-self: stretch;
    justify-content: center;
    padding: 1rem 1.4rem;
    font-size: 0.98rem;
    margin-top: 0.5rem;
    border-radius: 14px;
}
.auth-cta svg {
    transition: transform 0.2s var(--ease-out);
}
.auth-cta:hover svg { transform: translateX(3px); }

.auth-cta-hint {
    margin: 0.2rem 0 0;
    text-align: center;
    color: var(--ink-soft);
}

/* Decorative meta line under the form — small print, soft tone. */
.auth-foot-meta {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    margin-top: 0.4rem;
    color: var(--ink-faint);
    font-size: 0.74rem;
    letter-spacing: 0.04em;
}
.auth-foot-meta svg {
    width: 12px;
    height: 12px;
    stroke: currentColor;
    fill: none;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* Soft on-load fade for the right column once the layout settles. */
@keyframes auth-fade {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: none; }
}
.auth-fade { animation: auth-fade 0.55s var(--ease-out) both; }
.auth-fade-1 { animation-delay: 0.08s; }
.auth-fade-2 { animation-delay: 0.18s; }
.auth-fade-3 { animation-delay: 0.28s; }

@media (prefers-reduced-motion: reduce) {
    .auth-fade, .auth-cta svg { animation: none !important; transition: none !important; }
}

/* =============================================================
   Paletin luokittelu — chip-UI
   ============================================================= */

.palette-cat-list {
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
    margin-top: 0.2rem;
}

.palette-cat-bucket {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    padding: 0.7rem 0.85rem;
    background: var(--surface);
    border: 1px solid var(--line-soft);
    border-radius: 14px;
}

.palette-cat-label {
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--juniper);
}

.palette-cat-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    align-items: center;
    min-height: 1.6rem;
}

.palette-cat-chip {
    appearance: none;
    -webkit-appearance: none;
    display: inline-flex;
    align-items: center;
    padding: 0.32rem 0.7rem;
    font: inherit;
    font-size: 0.88rem;
    line-height: 1;
    color: var(--ink);
    background: var(--juniper-soft);
    border: 1px solid transparent;
    border-radius: var(--radius-pill);
    cursor: pointer;
    transition: background 0.15s var(--ease-out),
                transform 0.15s var(--ease-out);
    touch-action: manipulation;
}
.palette-cat-chip:hover,
.palette-cat-chip:focus-visible {
    background: var(--saffron-soft);
    outline: none;
}
.palette-cat-chip:active { transform: translateY(1px); }

/* ×-poistonappi chipin sisällä — yhden napautuksen poisto. Erottuu chipin
   labelista hover-korostuksella; itse chip avaa yhä popoverin (siirrä/poista). */
.palette-cat-chip-x {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.15rem;
    height: 1.15rem;
    margin-left: 0.35rem;
    margin-right: -0.2rem;
    border-radius: 50%;
    font-size: 1rem;
    line-height: 1;
    color: var(--text-soft);
    transition: background 0.12s var(--ease-out), color 0.12s var(--ease-out);
}
.palette-cat-chip-x:hover {
    background: var(--danger, #b34);
    color: #fff;
}

/* Tuntemattomat tuotteet — pehmeä signaali että kaloritietoa ei ole
   valmiina taulukossa, mutta lisääminen sallitaan. Katkoviiva erottaa
   niput; saffron-vari sitoo visuaalisesti hover-tilaan mutta ei
   näytä virheeltä. */
.palette-cat-chip.is-unknown {
    background: transparent;
    border: 1px dashed var(--saffron);
    color: var(--ink);
}
.palette-cat-chip.is-unknown:hover,
.palette-cat-chip.is-unknown:focus-visible {
    background: var(--saffron-soft);
}

.palette-cat-empty {
    font-style: italic;
    color: var(--ink-faint);
}

.palette-cat-add {
    display: flex;
    gap: 0.4rem;
    margin-top: 0.15rem;
}
.palette-cat-add-input {
    flex: 1;
    min-width: 0;
    padding: 0.45rem 0.7rem;
    font: inherit;
    font-size: 0.9rem;
    color: var(--ink);
    background: var(--raised);
    border: 1px solid var(--line);
    border-radius: 10px;
}
.palette-cat-add-input:focus {
    outline: 2px solid var(--juniper);
    outline-offset: 1px;
    border-color: transparent;
}
.palette-cat-add-btn {
    flex: 0 0 auto;
    width: 2.1rem;
    padding: 0;
    font: inherit;
    font-size: 1.15rem;
    font-weight: 600;
    line-height: 1;
    color: var(--juniper);
    background: var(--raised);
    border: 1px solid var(--line);
    border-radius: 10px;
    cursor: pointer;
    transition: background 0.15s var(--ease-out);
}
.palette-cat-add-btn:hover,
.palette-cat-add-btn:focus-visible {
    background: var(--juniper-soft);
    outline: none;
}

/* Opastus kun käyttäjä yrittää lisätä tuntemattoman (ei Fineli/omat) nimen. */
.palette-cat-add-msg {
    margin-top: 0.3rem;
    font-size: 0.8rem;
    line-height: 1.35;
    color: var(--danger, #b34);
}
.palette-cat-add-msg[hidden] { display: none; }

/* ---- Omat tuotteet: lomake + lisättyjen tuotteiden lista saman kortin
   sisällä. Lomake ja lista ovat pehmeitä sisäpaneeleita erotettuina
   ohuella viivalla; mikään ei jää kortin ulkopuolelle. Yhtenäinen
   pystyrytmi: kortin lohkojen väli 1.25rem, lohkon sisällä 0.5rem. ---- */
#card-user-products.form-grid { gap: 1.25rem; }
.user-products-head {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}
.user-products-head .form-section-title { margin: 0; }
.user-products-head .hint { margin: 0; }
.user-products-subheading {
    margin: 0 0 0.1rem;
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--juniper);
}
.user-products-form-panel {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    padding: 1.1rem;
    background: var(--raised);
    border: 1px solid var(--line-soft);
    border-radius: 14px;
}
.user-products-form-panel .hint { margin: 0; }
.user-products-list {
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--line-soft);
}
.user-products-list .hint { margin: 0; }
.user-products-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
    gap: 0.6rem;
}
.user-product-card {
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
    padding: 0.75rem 0.85rem;
    background: var(--surface);
    border: 1px solid var(--line-soft);
    border-radius: 12px;
}
.user-product-name {
    font-weight: 600;
    color: var(--ink);
    word-break: break-word;
}
.user-product-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.82rem;
    color: var(--text-soft);
    font-variant-numeric: tabular-nums;
}
.user-product-basis,
.user-product-factor {
    padding: 0.05rem 0.4rem;
    background: var(--juniper-soft);
    border-radius: var(--radius-pill);
    white-space: nowrap;
}

/* Popover — mobiili-first pohjapaneelina, desktopilla keskitetty modaali. */
/* Popoveri ankkuroituu tapatetun chipin viereen JS:llä (top/left
   -inline-tyylit viewport-koordinaateissa). `position: fixed` on
   pakollinen — `absolute` sotkeutuisi lähimpään .card-esi-isään
   (jolla on position: relative) ja siirtäisi popoverin väärään
   paikkaan. Reposition-on-scroll JS pitää popoverin chipin vieressä. */
.palette-cat-popover {
    position: fixed;
    z-index: 100;
    opacity: 0;
    transform: translateY(-4px);
    transition: opacity 0.14s var(--ease-out),
                transform 0.14s var(--ease-out);
    pointer-events: none;
}
.palette-cat-popover.is-open {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}
.palette-cat-popover[hidden] { display: none; }

.palette-cat-popover-inner {
    width: 320px;
    max-width: calc(100vw - 1rem);
    max-height: 60vh;
    overflow-y: auto;
    padding: 0.8rem 0.9rem 0.9rem;
    background: var(--raised);
    border: 1px solid var(--line-soft);
    border-radius: 14px;
    box-shadow: var(--shadow-lifted);
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
}

.palette-cat-popover-title {
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--ink);
    word-break: break-word;
}
.palette-cat-popover-label {
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-soft);
}
.palette-cat-popover-cats {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}
.palette-cat-popover-catbtn {
    appearance: none;
    -webkit-appearance: none;
    padding: 0.4rem 0.75rem;
    font: inherit;
    font-size: 0.88rem;
    color: var(--ink);
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    cursor: pointer;
    transition: background 0.15s var(--ease-out);
}
.palette-cat-popover-catbtn:hover,
.palette-cat-popover-catbtn:focus-visible {
    background: var(--juniper-soft);
    border-color: transparent;
    outline: none;
}
.palette-cat-popover-actions {
    display: flex;
    gap: 0.5rem;
    justify-content: flex-end;
    margin-top: 0.3rem;
    padding-top: 0.5rem;
    border-top: 1px solid var(--line-soft);
}

@media (prefers-reduced-motion: reduce) {
    .palette-cat-popover,
    .palette-cat-chip { transition: none; }
}

/* Meal settings card: sluidipohjainen layout. Vasemmalla ateriaotsikko,
   keskellä liukusäädin + pikkuvain %-readout, oikealla kellonaika-
   input. Sluidi on tabbable ja käyttää järjestelmätemaväriä. */
.meal-settings-grid {
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
    margin-top: 0.2rem;
}

/* Kasvirasvarivi: erotettu varsinaisista aterialriveistä pienellä välillä
   ja katkoviivalla — se on osuus koko päivän energiasta, ei aterioiden
   keskinäistä jakoa. */
.meal-settings-extras {
    margin-top: 0.75rem;
    padding-top: 0.85rem;
    border-top: 1px dashed var(--line-soft);
}
.meal-settings-extras .meal-settings-label {
    color: var(--text-soft);
}

.meal-settings-row {
    display: grid;
    grid-template-columns: minmax(5.5rem, 0.9fr) minmax(0, 2.4fr) minmax(5rem, 0.7fr);
    align-items: center;
    gap: 0.8rem;
    padding: 0.7rem 0.85rem;
    background: var(--surface);
    border: 1px solid var(--line-soft);
    border-radius: 12px;
    transition: opacity 160ms ease;
}

.meal-settings-row.is-zero {
    opacity: 0.55;
}

.meal-settings-label {
    font-weight: 600;
    color: var(--juniper);
}

/* Slider + readout column */
.meal-settings-share {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    min-width: 0;
}

.meal-settings-share input[type="range"] {
    width: 100%;
    margin: 0;
    accent-color: var(--juniper);
    cursor: grab;
}
.meal-settings-share input[type="range"]:active { cursor: grabbing; }

.meal-settings-share-readout {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    font-variant-numeric: tabular-nums;
    font-size: 0.9rem;
    color: var(--text-soft);
}

.meal-settings-share-readout input[type="number"] {
    width: 3.6rem;
    max-width: none;
    padding: 0.2rem 0.35rem;
    font-variant-numeric: tabular-nums;
    text-align: right;
    font-size: 0.92rem;
}

.meal-settings-pct {
    color: var(--text-soft);
    margin-left: -0.2rem;
    margin-right: 0.35rem;
}

.meal-settings-kcal {
    margin-left: auto;
}

/* Time column */
.meal-settings-time {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    margin: 0;
}

.meal-settings-time input[type="text"] {
    width: 100%;
    max-width: 5rem;
    text-align: center;
    font-variant-numeric: tabular-nums;
}

.meal-settings-total {
    padding: 0.4rem 0.1rem 0;
    font-variant-numeric: tabular-nums;
}

/* (?) -toggle avustustekstille lomakekenttien vieressä. Käyttää natiivia
   <details>:iä joten JS:ää ei tarvita. Ohjepaneeli virtaa normaalissa
   dokumenttivirrassa avattaessa — pysyy siis aina kortin sisällä eikä
   deborda oikealle laidalle. Details on erillisessä .field-with-help-
   headissa labelin vieressä, jotta form-grid label uppercase-tyyli ei
   valu ohjetekstiin. */
.field-with-help {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}
.field-with-help-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}
.field-with-help-head > label {
    /* Sama typografia kuin .form-grid label:lla — perii isot kirjaimet */
    font-size: 0.72rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ink-soft);
    font-weight: 500;
    margin: 0;
}

.help-toggle {
    display: inline-block;
}

.help-toggle > summary {
    list-style: none;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.35rem;
    height: 1.35rem;
    border-radius: 50%;
    background: var(--surface);
    border: 1px solid var(--line-soft);
    color: var(--text-soft);
    font-size: 0.85rem;
    font-weight: 700;
    line-height: 1;
    user-select: none;
    transition: background 120ms ease, color 120ms ease;
}
.help-toggle > summary::-webkit-details-marker { display: none; }
.help-toggle > summary::marker { display: none; content: ''; }
.help-toggle > summary:hover,
.help-toggle[open] > summary {
    background: var(--juniper);
    color: #fff;
    border-color: var(--juniper);
}

.help-toggle-body {
    /* Virtaa normaalisti details-elementin sisällä, koko leveys.
       Ei absoluuttista positiointia — näin paneeli pysyy kortin sisällä
       eikä ylivuoda mobiilinäytöllä. */
    display: block;
    width: 100%;
    margin: 0.5rem 0 0.2rem;
    padding: 0.75rem 0.9rem;
    background: var(--surface);
    border: 1px solid var(--line-soft);
    border-radius: 12px;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04);
    font-size: 0.88rem;
    line-height: 1.45;
    color: var(--text-soft);
    /* Nollataan .form-grid labelin isot kirjaimet, jos rakenne muuttuu */
    text-transform: none;
    letter-spacing: normal;
    font-weight: 400;
}
.help-toggle-body p { margin: 0 0 0.55rem; text-transform: none; }
.help-toggle-body p:last-child { margin-bottom: 0; }
.help-toggle-body ul {
    margin: 0.25rem 0 0.55rem;
    padding-left: 1.15rem;
}
.help-toggle-body li { margin: 0.15rem 0; text-transform: none; }
.help-toggle-body strong { color: var(--ink); }
.help-toggle-body code {
    background: var(--line-soft);
    padding: 0.05rem 0.3rem;
    border-radius: 4px;
    font-size: 0.85em;
    font-family: var(--font-mono, monospace);
    text-transform: none;
}

@media (max-width: 560px) {
    .meal-settings-row {
        grid-template-columns: minmax(5rem, 1fr) minmax(4.5rem, 0.7fr);
        grid-template-rows: auto auto;
        gap: 0.35rem 0.7rem;
    }
    .meal-settings-label { grid-column: 1; grid-row: 1; }
    .meal-settings-time  { grid-column: 2; grid-row: 1; }
    .meal-settings-share { grid-column: 1 / -1; grid-row: 2; }
}

/* =============================================================
   Design-system komponentit (v2) — lisätty visuaalisen refaktoroinnin
   yhteydessä. Nämä luokat korvaavat inline-tyylit templateissa ja
   yhtenäistävät napit, hälytykset, taulukot ja utility-välit.
   ============================================================= */

/* ---------- Utility-välit: stack (vertikaalinen) & cluster (horisontaalinen) ---------- */
.stack        { display: flex; flex-direction: column; gap: var(--space-md); }
.stack-2xs    { display: flex; flex-direction: column; gap: var(--space-2xs); }
.stack-xs     { display: flex; flex-direction: column; gap: var(--space-xs); }
.stack-sm     { display: flex; flex-direction: column; gap: var(--space-sm); }
.stack-lg     { display: flex; flex-direction: column; gap: var(--space-lg); }
.stack-xl     { display: flex; flex-direction: column; gap: var(--space-xl); }

.cluster      { display: flex; flex-wrap: wrap; gap: var(--space-sm); align-items: center; }
.cluster-xs   { display: flex; flex-wrap: wrap; gap: var(--space-xs); align-items: center; }
.cluster-sm   { display: flex; flex-wrap: wrap; gap: var(--space-sm); align-items: center; }
.cluster-md   { display: flex; flex-wrap: wrap; gap: var(--space-md); align-items: center; }
.cluster-baseline { align-items: baseline; }
.cluster-between  { justify-content: space-between; }
.cluster-end      { justify-content: flex-end; }

/* ---------- Väri- ja teksti-utilityt ---------- */
.text-danger  { color: var(--danger); }
.text-success { color: var(--success); }
.text-warning { color: var(--warning); }
.text-info    { color: var(--info); }
.text-primary { color: var(--primary); }
.text-accent  { color: var(--accent); }
.text-ink     { color: var(--ink); }
.text-muted   { color: var(--ink-soft); }
.text-nowrap  { white-space: nowrap; }
.text-break   { word-break: break-all; }

.bg-surface   { background: var(--surface); }
.bg-bg        { background: var(--bg); }

.no-underline { text-decoration: none; }

/* ---------- Suuret napit (btn-lg) + full-width (btn-block) ----------
   Nämä lisätään .btn-primary / .btn-ghost / .btn-secondary luokkien PÄÄLLE. */
.btn-lg {
    padding: 0.95rem 1.6rem;
    font-size: var(--text-md);
}
.btn-block {
    display: flex;
    width: 100%;
    justify-content: center;
}
.btn-danger {
    background: var(--danger);
    color: #fff;
    border-color: transparent;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.78rem 1.25rem;
    border-radius: var(--radius-pill);
    font-family: inherit;
    font-size: 0.92rem;
    font-weight: 500;
    letter-spacing: -0.01em;
    cursor: pointer;
    text-decoration: none;
    border: 1px solid transparent;
    transition: transform 0.18s var(--ease-out), box-shadow 0.18s var(--ease-out),
                background 0.18s var(--ease-out), border-color 0.18s var(--ease-out);
}
.btn-danger:hover {
    transform: translateY(-1px);
    background: #7f2929;
    box-shadow: 0 10px 24px -8px rgba(155, 56, 56, 0.4);
}
.dark .btn-danger:hover { background: #b85e5e; }
.btn-danger:active { transform: translateY(0); }

/* Muunnetaan .btn-ghost.btn-danger napiksi jonka teksti on danger-värinen
   mutta pohja säilyy ghost-tyylisenä (poisto-nappi taulukoissa). */
.btn-ghost.btn-danger {
    background: transparent;
    color: var(--danger);
    border-color: var(--line);
    padding: 0.45rem 0.85rem;
    font-size: 0.78rem;
}
.btn-ghost.btn-danger:hover {
    background: var(--danger-soft);
    border-color: transparent;
    color: var(--danger);
    transform: none;
    box-shadow: none;
}

/* ---------- Hälytykset (.alert-*) ---------- */
.alert {
    padding: 0.9rem 1.1rem;
    border-radius: var(--radius-md);
    border: 1px solid transparent;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    line-height: var(--leading-body);
    font-size: var(--text-sm);
}
.alert-title {
    font-weight: 600;
    font-size: var(--text-md);
    color: inherit;
    margin: 0;
}
.alert p { margin: 0; }
.alert-info {
    background: var(--info-soft);
    color: var(--info);
    border-color: var(--info);
}
.alert-success {
    background: var(--success-soft);
    color: var(--success);
    border-color: var(--success);
}
.alert-warning {
    background: var(--warning-soft);
    color: var(--warning);
    border-color: var(--warning);
}
.alert-danger {
    background: var(--danger-soft);
    color: var(--danger);
    border-color: var(--danger);
}

/* ---------- Merkit (.badge) ---------- */
.badge {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.15rem 0.55rem;
    border-radius: var(--radius-pill);
    font-size: var(--text-2xs);
    font-weight: 500;
    letter-spacing: 0.04em;
    line-height: 1.4;
    background: var(--line-soft);
    color: var(--ink-soft);
}
.badge-primary { background: var(--juniper-soft); color: var(--juniper); }
.badge-accent  { background: var(--saffron-soft); color: var(--saffron); }
.badge-danger  { background: var(--danger-soft);  color: var(--danger); }
.badge-success { background: var(--success-soft); color: var(--success); }
.badge-warning { background: var(--warning-soft); color: var(--warning); }
.badge-info    { background: var(--info-soft);    color: var(--info); }

/* ---------- Kertakäyttöinen kortti kertakoodille / kertatunnukselle ---------- */
.card-otp {
    border-left: 4px solid var(--saffron);
}
.otp-code {
    padding: 0.7rem 1rem;
    background: var(--bg);
    border-radius: var(--radius-sm);
    user-select: all;
    display: inline-block;
    font-size: var(--text-md);
    letter-spacing: 0.04em;
}

/* ---------- Kopioitava koodi (kutsulinkit yms.) ---------- */
.copy-code {
    padding: 0.5rem 0.7rem;
    background: var(--bg);
    border-radius: var(--radius-xs);
    user-select: all;
    word-break: break-all;
    font-size: var(--text-xs);
}

/* ---------- Admin-taulukkokortit (yhtenäinen ulkoasu users/invites/llm) ---------- */
.admin-row-card {
    display: flex;
    flex-direction: column;
    gap: 0.8rem;
}
.admin-row-head {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
    align-items: baseline;
    justify-content: space-between;
}
.admin-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

/* ---------- Segmentti-nav (aktiivinen/passiivinen valinta, esim. LLM-käyttö pv-suodatin) ---------- */
.seg-nav {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
    margin-bottom: 1.2rem;
}
.seg-nav .btn-ghost.active,
.seg-nav a.active {
    background: var(--ink);
    color: var(--bg);
    border-color: transparent;
}
.dark .seg-nav .btn-ghost.active,
.dark .seg-nav a.active {
    background: var(--ink);
    color: var(--bg);
}

/* Painokuvaajan aikavälivalitsin + AJAX-swapin latausdimm. */
.weight-range-nav {
    margin-top: 1.4rem;
    margin-bottom: 0.8rem;
}
#weight-chart-panel[aria-busy="true"] {
    opacity: 0.55;
    transition: opacity 0.15s ease;
}

/* ---------- LLM-pinottu palkki (korvaa kovakoodatut #6e8db8 -värit) ---------- */
.stacked-bar {
    height: 1.1rem;
    background: var(--bg);
    border-radius: 0.3rem;
    overflow: hidden;
    display: flex;
}
.stacked-bar-has-data { min-width: 2px; }
.stacked-bar-row {
    display: grid;
    grid-template-columns: 5rem 1fr 5rem;
    gap: 0.6rem;
    align-items: center;
}
.stacked-seg-coach     { background: var(--juniper); }
.stacked-seg-meal      { background: var(--saffron); }
.stacked-seg-exercise  { background: var(--info); }
.legend-swatch {
    display: inline-block;
    width: 0.7em;
    height: 0.7em;
    border-radius: 2px;
    vertical-align: middle;
    margin-right: 0.25rem;
}
.legend-swatch-coach    { background: var(--juniper); }
.legend-swatch-meal     { background: var(--saffron); }
.legend-swatch-exercise { background: var(--info); }

/* ---------- Käyttäjärivi LLM-käytössä (yhtenäinen border-top) ---------- */
.usage-user-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    justify-content: space-between;
    align-items: baseline;
    padding: 0.6rem 0;
    border-top: 1px solid var(--bg);
}

/* ---------- Feature-summagridi ---------- */
.feature-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 0.8rem;
    margin-top: 1rem;
}

/* ---------- Tavoite-etuisuudet (edistymispalkki dashboardissa) ---------- */
.journey-milestone-inactive-color { color: var(--line-strong); }

/* ---------- Vaarallinen kortti (tilin poisto, punainen reunus) ---------- */
.card-danger {
    border-color: var(--danger);
}
.card-danger .form-section-title {
    color: var(--danger);
    margin-top: 0;
}

/* ---------- Kaverin GDPR-vientipainike (saffron accent) ---------- */
.btn-accent {
    background: var(--accent);
    color: #fff;
    border: none;
    padding: 0.95rem 1.6rem;
    border-radius: var(--radius-sm);
    font-family: inherit;
    font-weight: 500;
    font-size: 0.95rem;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    transition: transform 0.18s var(--ease-out), background 0.18s var(--ease-out);
}
.btn-accent:hover { transform: translateY(-1px); filter: brightness(1.05); }
.btn-accent:active { transform: translateY(0); }

/* ---------- Ikoninappi juniperilla (dashboardin avaa-nappi) ---------- */
.icon-btn.icon-btn-primary {
    background: var(--juniper);
    color: var(--bg);
    border-color: transparent;
}

/* ---------- Auth/topbar-linkki painostettu-tilaan (LLM-suodatin ym.) ---------- */
.pill-active {
    background: var(--ink) !important;
    color: var(--bg) !important;
    border-color: transparent !important;
}

/* Uudet margin-utilityt (mt-0/mb-0/mb-xs/mb-sm/mb-2xs puuttuivat aiemmin).
   Muita marginaali-luokkia (mt-md, mt-lg, mb-md, mb-lg, mb-xl, mt-3xs, mt-2xs,
   mt-xs, mt-sm, m-0, mt-neg-sm, mt-md-tight) ei tarvitse määritellä
   uudelleen — ne ovat jo olemassa ~riviltä 2492. */
.mt-0 { margin-top: 0 !important; }
.mb-0 { margin-bottom: 0 !important; }
.mb-2xs { margin-bottom: var(--space-2xs); }
.mb-xs  { margin-bottom: var(--space-xs); }
.mb-sm  { margin-bottom: var(--space-sm); }
.my-md  { margin-top: var(--space-md); margin-bottom: var(--space-md); }

/* Meta-vinkkirivi otsikon ("Käyttäjät · N kutsutta") alle */
.section-meta {
    color: var(--ink-soft);
    margin: 0.15rem 0 var(--space-lg);
    font-size: var(--text-sm);
}

/* Palaa-linkki (< Hallinta) yläreunassa */
.back-link {
    display: inline-block;
    margin: 0.6rem 0 0.2rem;
    color: var(--ink-soft);
    text-decoration: none;
    font-size: var(--text-sm);
}
.back-link:hover { color: var(--ink); }

/* Yleiset arvokorttien width-rajoittimet (profiilin GDPR- ja poisto-kortit) */
.card-narrow {
    max-width: 720px;
    margin-left: auto;
    margin-right: auto;
}

/* Sivupohjan yhtenäinen sivutus (edellinen inline "margin: 1rem 0 2.5rem") */
.page-top-gap { margin-top: var(--space-md); }
.page-bottom-gap { margin-bottom: var(--space-2xl); }

/* Otsikkoruudun kanssa käytettävä toiminta-alue (esim. nutrition/exercise
   "Luo uusi suunnitelma" -nappi otsikon vieressä) */
.section-toolbar {
    display: flex;
    justify-content: space-between;
    gap: var(--space-sm);
    flex-wrap: wrap;
    align-items: flex-start;
}

/* Otsikkoväri (italic-display) accent-saffronilla — käytetään esim. exercise
   ja cardio-headline-otsikoissa jotta accent-value on tokenina, ei kovakoodattu */
.italic-accent {
    color: var(--saffron);
    font-style: italic;
    font-variation-settings: 'opsz' 144, 'SOFT' 80;
}

/* Kardio-ohjelaatikko: pinottujen luvun / vihjeen välitys */
.stat-stack {
    display: flex;
    flex-direction: column;
    gap: var(--space-md);
    margin-top: var(--space-lg);
}

/* Cardio-headline hillityllä leveydellä (aikaisemmin inline max-width: 14ch) */
.headline-narrow { max-width: 14ch; }
.headline-wide   { max-width: 18ch; }

/* Levenevä lomakekenttä .row-rakenteessa (aikaisemmin inline flex: 2; min-width: 200px) */
.field-wide {
    flex: 2;
    min-width: 200px;
}

/* Nappi joka jää lomakkeen vasempaan reunaan (ei täytä koko riviä) */
.btn-align-start { align-self: flex-start; }

/* Section-toolbarin oikeanpuoleinen työkalupalkki (napit pinoutuvat) */
.section-toolbar-actions {
    align-items: flex-end;
}

/* Sisällön kohdistus (yleisiä flex-alignment-utilityjä) */
.self-start { align-self: flex-start; }
.self-end   { align-self: flex-end; }

/* Tiivis form-grid (aikaisemmin inline gap: 0.6rem) */
.form-grid.form-grid-tight { gap: 0.6rem; }

/* Levein h1-otsikko (20ch) — nutrition_guidelines, shopping_list */
.headline-x-wide { max-width: 20ch; }

/* Pre-tag jonka pitkät rivit rivittyvät (guideline-teksti) */
.pre-wrap { white-space: pre-wrap; }

/* ---------- Kokeilubanneri ----------
   Näkyy joka sivulla kunnes ensimmäinen maksu on tehty (ks. base.html +
   inject_helpers). Käyttää saffron-muuttujia, jotka vaihtuvat teeman mukana. */
.trial-banner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin-bottom: 1.2rem;
    padding: 0.6rem 0.5rem 0.6rem 0.9rem;
    background: var(--saffron-soft);
    border: 1px solid var(--saffron);
    border-radius: var(--radius-md, 12px);
}
.trial-banner-text {
    font-size: var(--text-sm);
    font-weight: 500;
    color: var(--ink);
}
/* CTA on tavallista btn-primarya kompaktimpi, jotta palkki pysyy ohuena. */
.trial-banner-cta {
    padding: 0.45rem 1rem;
    font-size: var(--text-xs);
    flex-shrink: 0;
}

