/* PantryPrep — list, table, toolbar, and form-page styles.
   Loaded after app.css; see fragments/layout.html. */

.pagehead {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 1.5rem;
    flex-wrap: wrap;
    margin-bottom: 1.5rem;
}

.pagehead h1 { margin-bottom: 0.35rem; }

.pagehead__note {
    margin: 0;
    color: var(--ink-soft);
    max-width: 62ch;
    font-size: 0.95rem;
}

.crumb {
    margin: 0 0 0.5rem;
    font-size: 0.88rem;
}

.crumb a { color: var(--ink-soft); }

.flash:empty { display: none; }

/* ---------- toolbar and search ---------- */

.toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
    flex-wrap: nowrap;
    margin: 0 0 1.25rem;
}

.toolbar__actions {
    display: flex;
    align-items: center;
    gap: 0.6rem;
}

.searchbar {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin: 0;
    flex-wrap: nowrap;
    min-width: 0;
}

.searchbar input[type="search"] {
    flex: 0 1 22rem;
    min-width: 8rem;
    padding: 0.55rem 0.8rem;
    font: inherit;
    border: 1px solid var(--rule-strong);
    border-radius: var(--radius);
    background: #FFFFFF;
}

.searchbar input[type="search"]:focus {
    border-color: var(--herb);
    outline: 2px solid var(--herb-wash);
}

.searchbar__clear { font-size: 0.9rem; white-space: nowrap; }

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

/* ---------- tables ----------
   A table is a warm white panel on the page, not loose lines on it: the panel
   says "these belong together" before any heading does. Collapsed borders
   cannot take a radius, so cells carry the rules instead. */

.table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    font-size: 0.94rem;
    background: var(--surface);
    border: 1px solid var(--rule);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    overflow: hidden;
}

.table thead th {
    text-align: left;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--ink-soft);
    padding: 0.7rem 0.8rem 0.6rem;
    background: #FBF7EF;
    border-bottom: 1px solid var(--rule);
}

.table tbody td {
    padding: 0.75rem 0.8rem;
    border-bottom: 1px solid var(--rule);
    vertical-align: baseline;
}

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

.table tbody td a {
    text-decoration: none;
    font-weight: 500;
}

.table tbody tr:hover { background: #FBF6EC; }

/* Rows that navigate or open an editor when clicked. The cursor is the only
   affordance needed; the hover background already exists. */
.table__row--link { cursor: pointer; }

.table__actions {
    text-align: right;
    white-space: nowrap;
}

.table__actions a { margin-left: 0.85rem; font-size: 0.9rem; }

/* Row actions stay quiet until wanted. Red on every row of a list makes the
   whole page feel dangerous; the colour arrives on hover and focus instead,
   and every delete still asks before it acts. */
.table__actions a,
.table__actions .linkbutton {
    color: var(--ink-soft);
    text-decoration: none;
    text-underline-offset: 3px;
}

.table__actions a:hover,
.table__actions .linkbutton:hover { text-decoration: underline; }

.table__actions a:hover,
.table__actions .linkbutton:hover { color: var(--herb-deep); }

.table__actions .linkbutton--danger:hover,
.table__actions .linkbutton--danger:focus-visible,
.table__actions a.danger:hover { color: var(--rust); }

.table caption { text-align: left; }

.danger { color: var(--rust); }
.danger:hover { color: #7C2B1A; }

.muted { color: var(--ink-soft); }

.badge {
    display: inline-block;
    padding: 0.12rem 0.6rem;
    font-size: 0.8rem;
    font-weight: 500;
    background: var(--herb-wash);
    border: 1px solid transparent;
    border-radius: 999px;
    color: var(--herb-deep);
}

/* ---------- empty state ---------- */

.empty {
    padding: 2.5rem 1.5rem;
    background: var(--surface);
    border: 1.5px dashed var(--rule-strong);
    border-radius: var(--radius-lg);
    text-align: center;
    color: var(--ink-soft);
}

.empty p { margin: 0; max-width: 46ch; margin-inline: auto; }

/* ---------- danger button ---------- */

.button--danger {
    background: var(--rust);
    border-color: var(--rust);
    color: #FFFFFF;
}

.button--danger:hover { background: #7C2B1A; color: #FFFFFF; }

/* In a page heading, delete sits beside everyday actions like Edit. It is
   outlined there so it does not shout louder than them; the dialog it opens
   still confirms with the solid red button. */
.pagehead .button--danger {
    background: var(--surface);
    border-color: #E2B9AC;
    color: var(--rust);
}

.pagehead .button--danger:hover {
    background: var(--rust-wash);
    border-color: var(--rust);
    color: #7C2B1A;
}

/* ---------- accessibility ---------- */

.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;
}

/* ---------- responsive ---------- */

@media (max-width: 34rem) {
    .toolbar { flex-wrap: wrap; }
    .searchbar { width: 100%; }
    .searchbar input[type="search"] { flex: 1 1 auto; }
}

@media (max-width: 70rem) {
    .table thead { display: none; }

    .table tbody tr {
        display: block;
        padding: 0.85rem 0;
        border-bottom: 1px solid var(--rule);
    }

    .table tbody td {
        display: flex;
        justify-content: space-between;
        gap: 1rem;
        padding: 0.2rem 0;
        border: 0;
        text-align: left;
    }

    .table__actions { text-align: left; }
    .table__actions a { margin-left: 0; margin-right: 0.85rem; }
}

.pill {
    display: inline-block;
    margin-left: 0.4rem;
    padding: 0.05rem 0.45rem;
    font-size: 0.75rem;
    font-weight: 600;
    border-radius: 999px;
    white-space: nowrap;
}

.pill--warn { background: var(--honey-wash); color: var(--honey-ink); border: 1px solid #EBD3A8; }
.pill--bad  { background: var(--rust-wash); color: #8A2F1C; border: 1px solid #EBC9BE; }

.searchbar__select {
    padding: 0.55rem 0.7rem;
    font: inherit;
    font-size: 0.92rem;
    border: 1px solid var(--rule-strong);
    border-radius: var(--radius);
    background: #FFFFFF;
}

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

.measure input { flex: 1 1 auto; }

.measure__unit {
    font-size: 0.9rem;
    color: var(--ink-soft);
    min-width: 2.5rem;
}/* Append to src/main/resources/static/css/tables.css */

.toolbar__actions {
    display: flex;
    align-items: center;
    gap: 0.6rem;
}

.table__check {
    width: 2.75rem;
    padding-right: 0;
}

.table__check input { vertical-align: middle; }

.bulkbar {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    margin: 0 0 0.9rem;
    padding: 0.6rem 0.9rem;
    background: var(--herb-wash);
    border: 1px solid var(--herb-line);
    border-radius: var(--radius);
}

.bulkbar[hidden] { display: none; }

.bulkbar__count {
    font-size: 0.92rem;
    font-weight: 600;
    color: var(--herb-deep);
}

.button--small {
    padding: 0.35rem 0.75rem;
    font-size: 0.88rem;
}

.bulkbar .linkbutton { margin-left: 0; }

/* ---------- grocery lists ----------
   Same language as the landing page showcase: amber for what still needs
   buying, a green strike-through for what is already in the basket. */

.notice--warn {
    border-color: #EBD3A8;
    border-left-color: var(--amber);
    background: var(--honey-wash);
    max-width: 46rem;
}

/* Each aisle is its own panel, like a section of a paper list. */
.aisle {
    margin-top: 1.25rem;
    max-width: 46rem;
    padding: 0.9rem 1.1rem 0.3rem;
    background: var(--surface);
    border: 1px solid var(--rule);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
}

.aisle__name {
    font-family: var(--serif);
    font-size: 1.15rem;
    margin: 0 0 0.25rem;
    padding-bottom: 0.35rem;
    border-bottom: 1px solid var(--rule);
}

.aisle .shoplist__item:last-child { border-bottom: 0; }

/* Aisles flow into two columns when there is room, filling down the first
   column before the second, and an aisle never splits across them. */
.aisles {
    margin-top: 1.25rem;
    columns: 2 24rem;
    column-gap: 1.25rem;
}

.aisles .aisle {
    max-width: none;
    margin: 0 0 1.25rem;
    break-inside: avoid;
}

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

.shoplist__item {
    display: flex;
    align-items: flex-start;
    gap: 0.85rem;
    padding: 0.6rem 0;
    border-bottom: 1px solid var(--rule);
    scroll-margin-top: 6rem;
}

.shoplist__toggle { margin: 0; }

.tick {
    display: grid;
    place-items: center;
    width: 1.5rem;
    height: 1.5rem;
    margin-top: 0.1rem;
    padding: 0;
    border: 2px solid var(--herb);
    border-radius: 6px;
    background: #FFFFFF;
    color: #FFFFFF;
    font-size: 0.95rem;
    line-height: 1;
    cursor: pointer;
}

.tick:hover { background: var(--herb-wash); }
.tick[aria-pressed="true"] { background: var(--herb); }
.tick[aria-pressed="true"]::after { content: "\2713"; }

.shoplist__body { flex: 1 1 auto; min-width: 0; }
.shoplist__name { font-weight: 600; }

/* The darker amber from the warning pill, since the palette amber is too light
   to meet contrast guidelines as text. */
.shoplist__amount { margin-left: 0.5rem; font-weight: 600; color: var(--honey-ink); }

.shoplist__note {
    margin: 0.15rem 0 0;
    font-size: 0.85rem;
    color: var(--ink-soft);
}

.shoplist__item--bought .shoplist__name,
.shoplist__item--bought .shoplist__amount {
    font-weight: 400;
    color: var(--ink-soft);
    text-decoration: line-through;
    text-decoration-color: var(--herb);
}

.aisle-footnote { margin-top: 1.5rem; }

/* ---------- printable grocery list ----------
   Black on white with plain boxes to tick in pen. Aisles flow into two columns
   when there is room and never split across a column or page. */

.printsheet {
    width: 100%;
    max-width: 46rem;
    margin: 0 auto;
    padding: 2rem 1.5rem;
}

.printsheet__bar {
    display: flex;
    gap: 0.75rem;
    margin-bottom: 1.5rem;
}

.printsheet__title {
    font-family: var(--serif);
    font-size: 1.6rem;
    margin: 0;
}

.printsheet__meta {
    margin: 0.25rem 0 1.25rem;
    font-size: 0.9rem;
    color: var(--ink-soft);
}

.printsheet__aisles { columns: 2 16rem; column-gap: 2.5rem; }

.printsheet__aisle {
    break-inside: avoid;
    margin: 0 0 1.25rem;
}

.printsheet__aisle h2 {
    font-family: var(--serif);
    font-size: 1rem;
    margin: 0 0 0.35rem;
    padding-bottom: 0.2rem;
    border-bottom: 1px solid var(--ink);
}

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

.printsheet__item {
    display: flex;
    align-items: baseline;
    gap: 0.55rem;
    padding: 0.2rem 0;
    font-size: 0.95rem;
}

.printsheet__box {
    flex: 0 0 auto;
    width: 0.8rem;
    height: 0.8rem;
    border: 1.5px solid var(--ink);
    border-radius: 2px;
    transform: translateY(0.1rem);
}

.printsheet__name { min-width: 0; }
.printsheet__flag { font-size: 0.8rem; font-style: italic; }
.printsheet__amount { margin-left: auto; white-space: nowrap; }

@media print {
    body { background: #FFFFFF; }
    .printsheet { max-width: none; padding: 0; }
    .printsheet__bar { display: none; }
}

/* ---------- putting the shopping away ----------
   A wider dialog than the rest: each bought line needs an amount, a shelf, and
   a date side by side, which does not fit the 32rem default. */

.dialog--wide { width: min(46rem, calc(100vw - 2rem)); }

.stockup {
    list-style: none;
    margin: 0.5rem 0 0;
    padding: 0;
    max-height: 26rem;
    overflow-y: auto;
}

.stockup__row {
    padding: 0.75rem 0;
    border-top: 1px solid var(--rule);
}

/* :first-child would still draw a rule when the first row is a hidden one, so
   the border goes on the bottom of each row instead and the last one drops it. */
.stockup__row { border-top: 0; border-bottom: 1px solid var(--rule); }
.stockup__row:last-child { border-bottom: 0; }

.stockup__name {
    margin: 0;
    font-weight: 600;
}

.stockup__asked {
    margin: 0.1rem 0 0.5rem;
    font-size: 0.82rem;
    color: var(--ink-soft);
}

.stockup__fields {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr);
    gap: 0.75rem;
}

.stockup__fields .field { margin-bottom: 0; }

@media (max-width: 40rem) {
    .stockup__fields { grid-template-columns: 1fr; }
    .stockup { max-height: none; }
}

/* ---------- a grocery line that is already on the shelf ----------
   Two figures: what this shop added, and what the pantry now holds of that
   ingredient altogether. They sit side by side whenever the row has the width
   and drop onto their own lines only when it does not. */

.shoplist__stocked {
    flex: 0 1 auto;
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    align-items: baseline;
    gap: 0.1rem 0.7rem;
    padding-left: 1rem;
    font-size: 0.85rem;
    color: var(--ink-soft);
    text-align: right;
}

/* Each figure wraps as a unit, so an amount is never split from its word. */
.shoplist__stocked-line {
    margin: 0;
    white-space: nowrap;
}

.shoplist__stocked-amount {
    font-weight: 600;
    color: var(--herb-deep);
}

.shoplist__stocked-label { color: var(--ink-soft); }

.shoplist__stocked .linkbutton {
    margin: 0;
    font-size: 0.85rem;
}

@media (max-width: 40rem) {
    /* Below the ingredient name rather than beside it, still on one line. */
    .shoplist__item { flex-wrap: wrap; }

    .shoplist__stocked {
        width: 100%;
        justify-content: flex-start;
        padding: 0.35rem 0 0 2.85rem;
    }

    .shoplist__stocked .linkbutton { margin-left: auto; }
}

/* ---------- page headings that stay put ----------
   The heading block holds the page's actions, so it stays at the top of the
   window while a long list scrolls under it. The negative margins let its
   background span the page's padding, and the positive ones put the spacing
   back inside. */

.pagehead {
    position: sticky;
    top: 0;
    z-index: 10;
    margin: 0 -1.5rem 1.5rem;
    padding: 1rem 1.5rem;
    background: var(--paper);
    border-bottom: 1px solid var(--rule);
}

/* Anchored rows and sections land below the heading rather than behind it. */
.shoplist__item, .table tbody tr, .section[id] { scroll-margin-top: 9rem; }

/* A page's main actions sit in the heading, beside the title. */
.pagehead .actions {
    align-items: center;
    flex-wrap: wrap;
}

.pagehead .actions .inline-form { margin: 0; }

/* Grocery lists: the plan to build from sits beside its button. */
.pagehead .actions .searchbar__select {
    min-width: 12rem;
    min-height: 2.5rem;
}

@media (max-width: 40rem) {
    /* A phone screen is short, so the heading is tightened everywhere it can
       be: it has to stay small enough to be worth the space it holds. */
    /* A heading with a grid of buttons is too tall to pin on a phone, so it
       scrolls away with the page there. */
    .pagehead {
        position: static;
        margin: 0 -1rem 1rem;
        padding: 0.2rem 1rem 1rem;
        gap: 0.75rem;
    }

    .pagehead h1 {
        font-size: 1.35rem;
        margin-bottom: 0.15rem;
    }

    .pagehead__note {
        font-size: 0.85rem;
        line-height: 1.4;
    }

    .pagehead .actions .button {
        min-height: 2.6rem;
        padding: 0.45rem 0.4rem;
        font-size: 0.88rem;
        line-height: 1.2;
    }

    .shoplist__item, .table tbody tr, .section[id] { scroll-margin-top: 12rem; }

    /* A heading with one or two actions is short enough to keep pinned, so
       New recipe, Add item and the like stay in reach down a long list. */
    .pagehead:not(:has(> .actions > :nth-child(3))) {
        position: sticky;
        padding-top: 0.7rem;
        padding-bottom: 0.75rem;
    }

    /* With a single action, title and button share a row. */
    .pagehead:has(> .actions > :only-child) {
        flex-direction: row;
        flex-wrap: nowrap;
        align-items: center;
    }

    .pagehead:has(> .actions > :only-child) > div:first-child {
        flex: 1;
        min-width: 0;
    }

    .pagehead:has(> .actions > :only-child) > .actions {
        width: auto;
        flex: none;
    }

    .pagehead:has(> .actions > :only-child) > .actions > .button {
        width: auto;
        flex: none;
        padding: 0.45rem 0.9rem;
    }

    /* The plan picker for a grocery list takes the full row above its button. */
    .pagehead .actions > select { flex: 1 1 100%; min-width: 0; }
}
