/*
 * The saved library — the recipe list.
 *
 * This file is new because there was none. Every `library__*` class the panel
 * emitted was a dead hook: a grep for `.library` across `app.css` and `css/`
 * returned nothing, so the surface rendered on inherited primitives and UA
 * defaults alone. What that cost, measured at 375x812 rather than reasoned
 * about:
 *
 *   - `.library__flags` fell back to `display: block`, stacking three 44px icon
 *     buttons into a 44x132 column inside a 58px row. Centred in that row it
 *     overhung 37px above and 37px below, so 14 of the 16 favourite/ban buttons
 *     in an eight-row list took their tap on the NEXT recipe down. Rating and
 *     banning both feed the prompt, so the mis-tap was silent and durable —
 *     exactly the failure mode PRODUCT.md names.
 *   - `.library__list` was a bare block, so the rows were full-bleed white
 *     strips on the field: "a row on the bare field is a row that lost its
 *     group", and the skeleton it replaced was a correct inset card, so every
 *     load and every filter tap visibly un-rounded the list.
 *   - `h2.library__title` inherited the UA's 1.5em and resolved to 25.5px, a
 *     size that appears nowhere in the ramp, flush against x = 0.
 *
 * Loaded alongside tonight.css and recipe.css: the library is a panel inside
 * Tonight, not a screen, so it has no manifest entry of its own to hang a
 * stylesheet on.
 */

/* ─── The heading ─────────────────────────────────────────────────────────── */

/*
 * `--text-xl`, which is what the recipe panel's title takes. These two panels
 * are siblings over the same surface and open from the same screen; a household
 * should not be able to tell they were built at different times.
 *
 * Not the 34px large title — that step belongs to a place, and a panel is not
 * one. The trailing padding is the close button's own 44px, so a long heading
 * can never run under it.
 */
.library__head {
  padding: 0 calc(var(--gutter) + var(--tap)) 0 var(--gutter);
}

.library__title {
  font-size: var(--text-xl);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.1;
}

/*
 * The count, which doubles as the panel's live region.
 *
 * A filter tap swaps eight rows for two and says nothing; that swap IS the
 * result of the interaction, and it was previously announced to no one. Tabular
 * figures because the number changes in place under a fixed label.
 */
.library__count {
  display: block;
  min-height: 1.45em;
  margin-top: 3px;
  font-size: var(--text-sm);
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}

/* ─── The filter ──────────────────────────────────────────────────────────── */

/*
 * The segmented control, which is what four mutually-exclusive options are.
 *
 * They were `.chip--toggle` — the pill `app.css` reserves for a PERSON, "the
 * one thing in this product that is not a measurement". Sized to their own text
 * in a container with no flex and no gap, the four of them touched at 0px and
 * wrapped onto a second line, spending 88px of an 812px viewport on a control
 * the house already builds in 44. `flex: 1` divides the track instead, and the
 * raised white slug says "selected" without a second colour.
 */
/*
 * No `--block`. That modifier is `width: 100%`, which resolves against the
 * containing block and then takes the 16px margins on top of it — 375 + 32, so
 * "Everything" ran off the right edge. A block-level flex container already
 * fills the width its margins leave it.
 */
.library__filters {
  margin: var(--s4) var(--gutter) var(--s5);
}

/*
 * On the narrowest phone the track gives each segment 69.5px and "Never again"
 * asks for 71 at 13px, so it wrapped to two lines and took the whole control
 * with it. A step down in size buys the 6px rather than shortening a label that
 * says exactly what it means. Same breakpoint recipe.css uses for its tiles.
 */
@media (max-width: 360px) {
  .library__filters .segmented__option { font-size: var(--text-xs); }
}

/* ─── The list ────────────────────────────────────────────────────────────── */

/* `.rows` supplies the card, the gutter and the hairlines. This adds only the
   space beneath it, so a short list does not sit hard against the panel's end. */
.library__list {
  margin-bottom: var(--s6);
}

/*
 * A dish name is not an ingredient name.
 *
 * The Kitchen row clamps to one line to hold a measured density floor. This
 * list has no floor — tonight.css says the same of the alternatives — and the
 * title here is the ONLY identifier a row has, because the system has no
 * photography to fall back on and never will. Clamped at 287px it turned
 * "Sheet-pan salmon with fennel and blood orange, finished with dill" into
 * thirty characters and an ellipsis, which is the same string as any other
 * sheet-pan salmon. So it wraps, and the row grows.
 */
.library__row {
  align-items: flex-start;
  gap: var(--s3);
  padding: var(--s3) var(--s4);
}

.library__row .item__name {
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
  text-wrap: pretty;
  overflow-wrap: break-word;
}

/*
 * The Kitchen's single-sentence detail line, made a wrapping cluster — because
 * this one composes measurements AND a state tag, which is `.row__meta`
 * behaviour. Scoped to the library so Kitchen's clamped one-liner, which needs
 * the block behaviour, is untouched.
 */
.library__row .item__detail {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  /* A word space either side of the middot, which is what `.recipe__facts` gets
     from joining on ' · '. The row gap is for the state tag when it wraps. */
  gap: var(--s1) var(--s1);
  margin-top: 3px;
  overflow: visible;
  white-space: normal;
  text-overflow: clip;
}

/*
 * The separator leads its segment rather than trailing the one before it, so a
 * wrap carries "· 3 times" down whole. Joined into one string it read
 * "cooked 3 times, last yesterday ·" at the end of a line and "5/5" alone on
 * the next.
 */
.library__row .item__detail > span + span::before {
  content: '·';
  margin-inline-end: var(--s1);
}
/* A tag is its own object, not another clause of the sentence. No middot, and
   no leading margin either — it has to align on 0 when it wraps to its own
   line, which is where it usually ends up. */
.library__row .item__detail > .chip::before { content: none; }

/*
 * The banned tag needs an OPAQUE fill here, which it does not need anywhere else
 * it is used.
 *
 * `--gone-sunk` is `--gone` at 10%, and every other surface it lands on is a
 * static one — `.recipe__facts` does not hover. A library row does: `.item:has
 * (.item__body:hover)` swaps the card for `--pressed`, and that darker ground
 * shows straight through the translucent fill. Measured: 4.79:1 at rest, and
 * 3.84:1 under a finger, which is below the 4.5 floor for 12px text.
 *
 * Flattening the same two tokens onto the card pins it at 4.79 whatever the row
 * is doing. DESIGN.md: measure against the worst surface, not against white.
 */
.library__row .chip--expired {
  background: color-mix(in srgb, var(--gone) 10%, var(--card));
}

/* ─── The one trailing control ────────────────────────────────────────────── */

/*
 * One, not three.
 *
 * Three 44px buttons need 132px of height or 132px of width; the row offers 58
 * of the first and 311 of the second, and no arrangement of three of them
 * leaves a wrapping dish name room to be read. Rate keeps the row because this
 * is the surface you open after eating — "the library is where you look back
 * over a week of meals" — and favourite and never-again keep the labelled
 * toggles they already have on the recipe itself, one tap away.
 *
 * A word, not a glyph. The three it replaced were the same size, the same
 * stroke and the same tint, one of them destructive, and none of them labelled.
 */
.library__rate {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  /* Right-aligned inside a 44px floor, so "5/5" and "Rate" end on the same
     vertical and the column reads straight down. `min-width` because "5/5" sets
     only 36.6px of its own and 44 is test-enforced, not preferred. */
  justify-content: flex-end;
  min-width: var(--tap);
  min-height: var(--tap);
  padding: 0 var(--s2);
  border-radius: var(--radius-md);
  color: var(--tint);
  font-size: var(--text-sm);
  font-weight: 500;
}
.library__rate:hover { background: var(--sunk); }
.library__rate:active { background: var(--pressed); }
/* A column of ratings reads straight down only if the figures are the same
   width. This is the case `--font-num` survives for; the label is a measurement,
   so it takes the figures rather than the face. */
.library__rate--rated { font-variant-numeric: tabular-nums; }

/* ─── The empty and failed states ─────────────────────────────────────────── */

/* `.empty` centres its own text; it only needs the panel's gutter so a long
   line does not run to the frame edge on the widest phone. */
.library__body .empty {
  padding-inline: var(--gutter);
}
