:root {
    --surface: #ffffff;
    --surface-sunken: #f2f4f3;
    --border: #dde2e0;
    --text: #16201c;
    --text-muted: #61706a;
    --accent: #1f6f4a;
    --accent-contrast: #ffffff;
    --danger: #a3302a;
    --radius: 10px;
    /* Pinned rather than left to the content, so the docked menu knows how far down
       to start and cannot drift out of step with the bar. */
    --app-bar-height: 3.3rem;
}

@media (prefers-color-scheme: dark) {
    :root {
        --surface: #1a201e;
        --surface-sunken: #111614;
        --border: #2d3835;
        --text: #e6ebe8;
        --text-muted: #93a29c;
        --accent: #4bbd85;
        --accent-contrast: #0d1210;
        --danger: #e0736c;
    }
}

* {
    box-sizing: border-box;
}

body {
    margin: 0;
    background: var(--surface-sunken);
    color: var(--text);
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    font-size: 16px;
    line-height: 1.45;
}

.app-bar {
    position: sticky;
    top: 0;
    z-index: 10;
    display: flex;
    align-items: center;
    gap: 0.9rem;
    min-height: var(--app-bar-height);
    padding: 0.85rem 1rem;
    background: var(--accent);
}

.app-bar__title {
    color: var(--accent-contrast);
    font-size: 1.1rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-decoration: none;
}

/* Menu and page side by side once there is room. Below that the menu leaves the flow
   and lies over the page instead, so opening it does not shove the day's entries down
   the screen. The breakpoint further down sits under the width at which the page could
   still have its full 42rem beside the menu — a somewhat narrower page reads fine, and
   the column is worth more than those last few rem. */
.shell {
    position: relative;
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    max-width: 58rem;
    margin: 0 auto;
    padding: 1rem 1rem 3rem;
}

.page {
    flex: 1 1 20rem;
    min-width: 0;
    max-width: 42rem;
    margin: 0 auto;
}

/* --- add / edit form --- */

.card {
    margin-bottom: 1.5rem;
    padding: 1rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
}

.card__heading {
    margin: 0 0 0.85rem;
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
}

.field-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
}

.field {
    position: relative;
    margin-bottom: 0.75rem;
}

.field--date {
    flex: 1 1 16rem;
}

.field--type {
    flex: 1 1 9rem;
}

/* The input is narrow, but the field is not — the estimate note below it needs
   the full width to stay readable. */
.field--calories {
    flex: 1 1 14rem;
}

.field--calories input {
    max-width: 9rem;
}

.field--quantity {
    flex: 0 1 7rem;
}

.calories-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.calories-row .button {
    flex: none;
}

.estimate-note {
    margin: 0.35rem 0 0;
    color: var(--text-muted);
    font-size: 0.85rem;
}

.estimate-note--error {
    color: var(--danger);
}

.field label {
    display: block;
    margin-bottom: 0.25rem;
    font-size: 0.85rem;
    color: var(--text-muted);
}

.field input,
.field select {
    width: 100%;
    padding: 0.6rem 0.65rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text);
    font: inherit;
}

.field input:focus,
.field select:focus {
    outline: 2px solid var(--accent);
    outline-offset: -1px;
}

.field ul {
    margin: 0.35rem 0 0;
    padding-left: 1.1rem;
    color: var(--danger);
    font-size: 0.85rem;
}

/* --- typeahead --- */

/* Sits inside .field, so it has to out-specify the validation error list above. */
.field .suggestions {
    position: absolute;
    z-index: 20;
    top: 100%;
    right: 0;
    left: 0;
    max-height: 17rem;
    margin: 0.15rem 0 0;
    padding: 0;
    overflow-y: auto;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    box-shadow: 0 6px 20px rgb(0 0 0 / 18%);
    color: var(--text);
    font-size: 1rem;
    list-style: none;
}

.suggestions__option {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.6rem 0.7rem;
    cursor: pointer;
}

.suggestions__option + .suggestions__option {
    border-top: 1px solid var(--border);
}

.suggestions__option.is-highlighted {
    background: var(--surface-sunken);
}

.suggestions__name {
    overflow-wrap: anywhere;
}

.suggestions__calories {
    color: var(--text-muted);
    font-size: 0.85rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* --- buttons --- */

.button {
    display: inline-block;
    padding: 0.6rem 1.1rem;
    border: 1px solid transparent;
    border-radius: var(--radius);
    font: inherit;
    text-decoration: none;
    cursor: pointer;
}

.button--primary {
    background: var(--accent);
    color: var(--accent-contrast);
    font-weight: 600;
}

.button--quiet {
    padding: 0.35rem 0.6rem;
    border-color: var(--border);
    background: transparent;
    color: var(--text-muted);
    font-size: 0.85rem;
}

.button--danger {
    color: var(--danger);
}

.button-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

/* --- day list --- */

.day {
    margin-bottom: 1.25rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    overflow: hidden;
}

.day__header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    margin: 0;
    padding: 0.7rem 1rem;
    border-bottom: 1px solid var(--border);
    background: var(--surface-sunken);
    font-size: 0.95rem;
}

.day__label {
    font-weight: 600;
}

.day__total {
    color: var(--accent);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    white-space: nowrap;
}

.entry-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.entry {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 0.15rem 0.75rem;
    padding: 0.7rem 1rem;
}

.entry + .entry {
    border-top: 1px solid var(--border);
}

.entry__text {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.entry__type {
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
}

.entry__food {
    overflow-wrap: anywhere;
}

.entry__assumption {
    margin-top: 0.15rem;
    color: var(--text-muted);
    font-size: 0.8rem;
    overflow-wrap: anywhere;
}

.entry__amount {
    display: flex;
    align-self: center;
    flex-direction: column;
    align-items: flex-end;
}

.entry__calories {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    white-space: nowrap;
}

/* Same size as the eaten total above it — the quantity is what the eye is looking
   for on a multi-portion entry, so it carries the weight and the full text colour. */
.entry__breakdown,
.entry__units {
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.entry__quantity {
    color: var(--text);
    font-weight: 600;
}

.entry__calories::after,
.entry__breakdown::after {
    content: " kcal";
    font-size: 0.75rem;
    font-weight: 400;
    color: var(--text-muted);
}

.entry__actions {
    display: flex;
    grid-column: 1 / -1;
    gap: 0.5rem;
    margin-top: 0.4rem;
}

.entry__actions form {
    margin: 0;
}

.empty {
    padding: 2rem 0;
    color: var(--text-muted);
    text-align: center;
}

/* --- entry types --- */

.flash {
    margin: 0 0 1rem;
    padding: 0.7rem 0.85rem;
    border: 1px solid var(--danger);
    border-radius: var(--radius);
    color: var(--danger);
}

.day__hint {
    color: var(--text-muted);
    font-size: 0.8rem;
    font-weight: 400;
}

.type-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.type {
    display: flex;
    position: relative;
    z-index: 0;
    align-items: center;
    gap: 0.75rem;
    padding: 0.6rem 1rem;
    background: var(--surface);
}

.type + .type {
    border-top: 1px solid var(--border);
}

.type.is-dragging {
    z-index: 1;
    border-radius: var(--radius);
    box-shadow: 0 8px 22px rgb(0 0 0 / 22%);
    opacity: 0.95;
}

/* touch-action keeps a drag from scrolling the page on a phone */
.type__grip {
    flex: none;
    width: 1.6rem;
    height: 1.9rem;
    background-image: repeating-linear-gradient(
        to bottom,
        var(--text-muted) 0 2px,
        transparent 2px 6px
    );
    background-position: center;
    background-repeat: no-repeat;
    background-size: 0.9rem 1.1rem;
    cursor: grab;
    touch-action: none;
}

.type__grip:active {
    cursor: grabbing;
}

.type__name {
    flex: 1;
    min-width: 0;
    overflow-wrap: anywhere;
}

.type__usage {
    color: var(--text-muted);
    font-size: 0.8rem;
    font-variant-numeric: tabular-nums;
}

.type__actions {
    display: flex;
    flex: none;
    gap: 0.5rem;
}

.type__actions form {
    margin: 0;
}

.type-list.is-out-of-sync::after {
    display: block;
    padding: 0.6rem 1rem;
    color: var(--danger);
    content: "Nie udało się zapisać kolejności — odśwież stronę.";
    font-size: 0.85rem;
}

/* --- accounts --- */

.card--narrow {
    max-width: 20rem;
    margin-inline: auto;
}

/* --- menu --- */

.app-bar__menu-toggle {
    display: block;
    /* padded out to a thumb-sized target, pulled back in so the bar keeps its height */
    flex: none;
    padding: 0.5rem;
    margin: -0.5rem;
    border: 0;
    background: none;
    cursor: pointer;
}

.app-bar__menu-icon,
.app-bar__menu-icon::before,
.app-bar__menu-icon::after {
    display: block;
    width: 22px;
    height: 2px;
    border-radius: 2px;
    background: var(--accent-contrast);
}

.app-bar__menu-icon {
    position: relative;
}

/* the outer two lines; the middle one is the element itself */
.app-bar__menu-icon::before,
.app-bar__menu-icon::after {
    position: absolute;
    content: "";
}

.app-bar__menu-icon::before {
    top: -7px;
}

.app-bar__menu-icon::after {
    top: 7px;
}

/* Two switches read further down, and by the script. Narrow screens keep the menu out
   of the way until it is asked for; the wide-screen rule below flips that default.
   A class appears only where the answer departs from that, and the two layouts never
   write over each other: menu-narrow-shown lasts as long as the page it was opened on,
   while menu-wide-hidden arrives from the server and stays until taken back. */
body {
    --menu-layout: overlay;
    --menu-display: none;
}

body.menu-narrow-shown {
    --menu-display: block;
}

.menu {
    display: var(--menu-display);
    /* Lifted out of the flow and laid over the page; the offsets line it up with where
       the content starts, since absolute positioning ignores the shell's padding. */
    position: absolute;
    top: 1rem;
    left: 1rem;
    z-index: 9;
    width: 13rem;
    padding: 0.35rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    box-shadow: 0 8px 24px rgb(0 0 0 / 0.18);
}

@media (min-width: 52rem) {
    body {
        --menu-layout: column;
        --menu-display: block;
    }

    body.menu-wide-hidden {
        --menu-display: none;
    }

    /* Room for a column of its own here, so it takes one and nothing is covered. */
    .menu {
        position: sticky;
        top: calc(var(--app-bar-height) + 1rem);
        left: auto;
        flex: 0 0 13rem;
        width: auto;
        box-shadow: none;
    }
}

.menu__item {
    display: block;
    width: 100%;
    padding: 0.6rem 0.75rem;
    border: 0;
    border-radius: 6px;
    background: none;
    color: var(--text);
    font: inherit;
    text-align: left;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
}

.menu__item:hover {
    background: var(--surface-sunken);
}

.menu__item--current {
    color: var(--accent);
    font-weight: 600;
}

.menu__item--quiet {
    color: var(--text-muted);
}

.menu__account {
    margin: 0.35rem 0 0;
    padding-top: 0.35rem;
    border-top: 1px solid var(--border);
}

.menu__username {
    display: block;
    padding: 0 0.75rem;
    color: var(--text-muted);
    font-size: 0.8rem;
}

/* --- settings --- */

.help-text {
    margin: 0.3rem 0 0;
    color: var(--text-muted);
    font-size: 0.8rem;
}

/* What the day cost to get through, set against what went in — quieter than the
   total, because it is the same number on every row and only there to measure by. */
.day__burn {
    color: var(--text-muted);
    font-weight: 400;
}

/* --- tabs --- */

/* Pulled out to the card's edges so the rule under them reads as the card's own, and
   set in the same small caps the heading they replace was in. */
.tabs {
    display: flex;
    gap: 0.25rem;
    margin: -1rem -1rem 1rem;
    padding: 0 0.5rem;
    border-bottom: 1px solid var(--border);
}

.tabs__tab {
    padding: 0.7rem 0.75rem;
    margin-bottom: -1px;
    border: 0;
    border-bottom: 2px solid transparent;
    background: none;
    color: var(--text-muted);
    font: inherit;
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    cursor: pointer;
}

.tabs__tab[aria-selected="true"] {
    border-bottom-color: var(--accent);
    color: var(--accent);
}

/* --- activities --- */

.field--amount {
    flex: 1 1 10rem;
}

.field--unit,
.field--rate {
    flex: 1 1 8rem;
}

.amount-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.amount-row__unit {
    color: var(--text-muted);
    font-size: 0.85rem;
    white-space: nowrap;
}

/* Set apart from the meals it sits between by wearing the bar's own colour. Written
   as the accent rather than as the hex, so the two cannot drift apart, and so the
   line turns over with the rest of the palette when the screen goes dark. */
.entry--burn {
    background: var(--accent);
    color: var(--accent-contrast);
}

/* Everything inside carries a colour picked for a plain surface, and none of them
   survive the move — the burned figure worst of all, being the accent itself. */
.entry--burn .entry__calories,
.entry--burn .entry__quantity {
    color: var(--accent-contrast);
}

.entry--burn .entry__type,
.entry--burn .entry__units,
.entry--burn .entry__units::after {
    color: var(--accent-contrast);
    opacity: 0.75;
}

.entry--burn .button--quiet,
.entry--burn .button--danger {
    border-color: color-mix(in srgb, var(--accent-contrast) 40%, transparent);
    color: var(--accent-contrast);
}

/* Two inputs in one control; they should read as one field, not two. */
.datetime-row {
    display: flex;
    gap: 0.4rem;
}

.datetime-row input[type="date"] {
    flex: 1 1 9rem;
    width: auto;
}

.datetime-row input[type="time"] {
    flex: 0 1 6.5rem;
    width: auto;
}

/* --- weight --- */

.field--weight {
    flex: 0 1 8rem;
}

/* Weight and calories travel together at the right end of the header, far enough
   apart not to be read as one figure. */
.day__figures {
    display: flex;
    align-items: baseline;
    gap: 1.25rem;
}

.day__weight {
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    white-space: nowrap;
}
