/* Scraps: same look as the Laravel app (ecru background, white text,
   three columns), set in Casco's typeface, with a few color themes. No build step: served as-is. */

/* --- Font ------------------------------------------------------------------ */

/* ClassifiedCascoBeta2 Regular, the typeface of Casco Art Institute
   (casco.art), used here with their permission for this personal site.
   It only comes in Regular: see font-synthesis on body. */
@font-face {
  font-family: 'Classified Casco';
  src: url('../fonts/ClassifiedCascoBeta2-Regular.woff') format('woff');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

/* --- Colors --------------------------------------------------------------- */

:root {
  /* Text, lines and see-through overlays. A theme can override these
     too, e.g. for a light background with dark text. */
  --fg: #fafafa;
  --dimmed: #e5dfdb;
  --line: #fff;
  --tint-05: rgba(255, 255, 255, .05);
  --tint-10: rgba(255, 255, 255, .1);
  --tint-14: rgba(255, 255, 255, .14);
  --tint-20: rgba(255, 255, 255, .2);
  --tint-40: rgba(255, 255, 255, .4);
  --tint-60: rgba(255, 255, 255, .6);
  --select-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' fill='none' stroke='white' stroke-width='1.5'%3E%3Cpath d='m1 1.5 5 5 5-5'/%3E%3C/svg%3E");
  --radius: .5rem;
  --font: 'Classified Casco', ui-sans-serif, system-ui, sans-serif;
}

/* --- Themes ---------------------------------------------------------------- */

/* Picked with the dots in the footer (snippets/layout/foot.php) and
   remembered per browser (assets/js/main.js). Each theme is checked for
   readable text and a visible selected item (--accent) and missing
   ingredient (--error). Yellow is the default. */

:root,
[data-theme="yellow"] {
  --bg: #b4a983;
  --accent: #574a45;      /* selected item */
  --error: #7e3326;       /* missing ingredients */
}

[data-theme="clay"] {
  --bg: #8f766a;
  --accent: #4a2a1e;
  --error: #4b1630;
}

[data-theme="moss"] {
  --bg: #878653;
  --accent: #363520;
  --error: #5c1a10;
}

/* --- Base ------------------------------------------------------------------ */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font);
  font-size: 1rem;
  line-height: 1.5;
  /* The font has no bold: show bold text in Regular instead of letting
     the browser smear a fake bold. Headings stand out by size. */
  font-synthesis: none;
  /* Thin rendering on macOS, as on casco.art; the default makes this
     font look heavier and more widely spaced. */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  transition: background-color .2s;
}

a { color: inherit; text-decoration: none; }
a:hover { color: var(--accent); }

/* Links turn bold on hover and when selected (aria-current). The font has
   no bold, and a faked one would make the word wider and shift things
   around, so the letters get a thin outline in their own color instead. */
a:hover,
a[aria-current],
.link-button:hover {
  -webkit-text-stroke: .03em currentColor;
}
.nav-logo:hover { -webkit-text-stroke: 0; }

img { max-width: 100%; display: block; }

/* Icons (snippets/icon.php): the SVG's shape, filled with the text color. */
.icon {
  display: inline-block;
  flex-shrink: 0;
  background-color: currentColor;
  -webkit-mask: var(--icon) center / contain no-repeat;
  mask: var(--icon) center / contain no-repeat;
}

h1, h2, h3, p, ul, figure { margin: 0; }

ul { list-style: none; padding: 0; }

button, input, select { font: inherit; color: inherit; }

button { cursor: pointer; background: none; border: 0; padding: 0; }

:focus-visible { outline: 2px solid var(--tint-60); outline-offset: 2px; }

.dimmed { color: var(--dimmed); }

.link-button { text-decoration: underline; text-underline-offset: 3px; }
.link-button:hover { color: var(--accent); }

/* --- Navigation ------------------------------------------------------------ */

.nav {
  display: flex;
  align-items: center;
  gap: 1rem;
  max-width: 80rem;
  width: 100%;
  margin: 0 auto;
  padding: 1rem;
}

.nav-logo { display: flex; align-items: center; gap: .25rem; }
.nav-logo .icon { width: 2.25rem; height: 2.25rem; }
.nav-logo span { font-size: 1.875rem; font-weight: 300; letter-spacing: -.01em; }
.nav-logo:hover { color: inherit; }

.nav-links {
  flex: 1;
  display: flex;
  justify-content: flex-end;
  gap: .25rem;
}

.nav-links a {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .5rem .75rem;
  font-size: 1.125rem;
  font-weight: 600;
}

.nav-links .icon,
.nav-links .nav-icon { flex-shrink: 0; width: 1.5rem; height: 1.5rem; transition: transform .2s; }
/* Same line thickness as the inventory icon (pantry.svg), which measures
   about 2.35px at this size; Lucide's own default is 2. */
.nav-links .nav-icon { stroke-width: 2.35; }
.nav-links a:hover .icon,
.nav-links a:hover .nav-icon { transform: rotate(6deg); }
.nav-links a[aria-current] { color: var(--accent); }

.nav-user { display: flex; align-items: center; gap: .75rem; font-size: .875rem; }
.nav-user form { margin: 0; }
.nav-user-name { color: var(--dimmed); }
.nav-user-action { display: flex; align-items: center; }
.nav-user-icon { display: none; width: 1.375rem; height: 1.375rem; }

/* Phones: everything on one line. Logo, the menu as icons (below), and
   the account as an icon (log in / log out); its words stay readable for
   screen readers. */
@media (max-width: 767px) {
  .nav { flex-wrap: nowrap; gap: .75rem; padding: .75rem 1rem; }
  .nav-logo .icon { width: 1.75rem; height: 1.75rem; }
  .nav-logo span:not(.icon) { font-size: 1.375rem; }
  .nav-links { gap: .75rem; }
  .nav-links a { padding: .25rem; }
  .nav-user-name,
  .nav-user-text {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .nav-user-icon { display: block; }
  .nav-user-action { padding: .25rem; text-decoration: none; }
}

/* Phones and tablets: the menu as icons; its words stay readable for
   screen readers only. */
@media (max-width: 1023px) {
  .nav-links a span:not(.icon) {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}

/* --- Page ------------------------------------------------------------------ */

.main {
  flex: 1;
  width: 100%;
  max-width: 80rem;
  margin: 0 auto;
  padding: 1rem;
}

.footer { display: flex; justify-content: center; padding: 2rem 1rem 1.5rem; }

.themes { display: flex; flex-wrap: wrap; justify-content: center; gap: .5rem; }

/* Each dot carries its own data-theme (snippets/layout/foot.php), so it
   shows that theme's background color. */
.theme-dot {
  width: 1rem;
  height: 1rem;
  border-radius: 50%;
  background: var(--bg);
  box-shadow: 0 0 0 2px var(--tint-20);
  transition: box-shadow .2s, transform .2s;
}
.theme-dot:hover { transform: scale(1.2); }
.theme-dot[aria-pressed="true"] { box-shadow: 0 0 0 2px var(--fg); }

/* --- Three columns (recipes, calculate) ------------------------------------ */

.columns { display: flex; flex-direction: column; gap: 1rem; }

.column { padding-bottom: 1rem; border-bottom: 2px solid var(--line); }
.column-detail { border-bottom: 0; padding: 0 .5rem; }
/* No recipe list (no category picked): no line under it either. */
.column-list:not(:has(> *)) { border-bottom: 0; }

.list-item {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  width: 100%;
  padding: .25rem 1rem;
  font-weight: 600;
  text-transform: lowercase;
}
.list-item[aria-current] { color: var(--accent); }

.column-heading { padding: .5rem; font-size: 1.125rem; font-weight: 500; }

/* "labels" above the label links, under the categories. */
.column-subheading {
  margin-top: 1.25rem;
  padding: .25rem 1rem;
  color: var(--dimmed);
  font-size: .875rem;
}
@media (max-width: 1023px) {
  .column-subheading { flex-basis: 100%; margin-top: .5rem; padding: 0 .5rem; }
}

/* Labels ("easy dinner", "budget", "favorite"): small rectangular tags,
   under the categories and on a recipe. Just a border; the selected ones
   (you can pick several) are filled with the theme's selected color. */
.label-tags { display: flex; flex-wrap: wrap; gap: .375rem; }
/* The filters next to the categories: one under the other. */
.column-categories .label-tags { flex-direction: column; align-items: flex-start; padding: .25rem 1rem; }
.label-tag {
  display: inline-flex;
  align-items: center;
  /* Classified sits its letters low in the line (room for capitals above),
     so the space is moved from the top to the bottom: measured, this puts
     the lowercase letters exactly in the middle. */
  padding: 0 .625rem .25rem;
  border: 1px solid var(--tint-60);
  border-radius: 2px;
  color: var(--fg);
  font-size: .875rem;
  line-height: 1.4;
  white-space: nowrap;
  transition: background-color .2s, border-color .2s;
}
.label-tag:hover { border-color: var(--fg); background: var(--tint-10); color: var(--fg); }
.label-tag[aria-current],
.label-tag[aria-current]:hover { border-color: var(--accent); background: var(--accent); color: var(--fg); }
@media (max-width: 1023px) {
  /* Stacked columns: the filters side by side again, to save height. */
  .column-categories .label-tags { flex-direction: row; flex-wrap: wrap; padding: 0 .5rem; }
}

.empty { padding: 1rem; text-align: center; font-size: .875rem; font-weight: 600; }

/* Small screens: categories as a wrapping row instead of a long list. */
@media (max-width: 1023px) {
  .column-categories { display: flex; flex-wrap: wrap; gap: .25rem .5rem; }
  .column-categories .list-item { width: auto; padding: .25rem .5rem; }
  .column-detail { scroll-margin-top: 1rem; }
}

@media (min-width: 1024px) {
  .columns { flex-direction: row; align-items: flex-start; }
  .column { border-bottom: 0; padding-bottom: 0; }
  .column-categories { position: relative; width: 10rem; flex-shrink: 0; padding-right: 0; }
  .column-list { position: relative; width: 27.5rem; flex-shrink: 0; padding-right: 1rem; }
  /* The two vertical lines, each drawn as one line so it can grow from the
     top down when it appears and shrink back up when it goes (see
     "list-line" / "detail-line" in data-animate and data-leaving, set in
     snippets/layout/head.php and assets/js/main.js):
     - after the categories, always (it grows in when you arrive on the
       page and shrinks when you leave it);
     - after the recipe list, while a category's recipes are showing (it
       grows in with them and shrinks when they go). */
  .column-categories:has(.list-item)::after,
  .column-list:has(> *)::after {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    right: 0;
    width: 2px;
    background: var(--line);
    transform-origin: top;
  }
  .column-list::after { right: 1rem; }

  html[data-animate~="list-line"] [data-animated] .column-categories::after,
  html[data-animate~="detail-line"] [data-animated] .column-list::after {
    animation: grow-line .5s ease-out both;
  }
  html[data-leaving~="list-line"] [data-animated] .column-categories::after,
  html[data-leaving~="detail-line"] [data-animated] .column-list::after {
    animation: grow-line .25s ease-in reverse both;
  }
  .column-detail { flex: 1; min-width: 0; padding: 0 1.5rem; }
}

/* Fades on column pages marked [data-animated] (the recipes overview).
   Only the parts that change take part, each fading as a whole: "list"
   (recipe list) and "detail" (the recipe). The categories never move.
   The list fades its items rather than itself, so the divider line on
   it (below) only grows and shrinks, without fading.

   Fading in: which parts is decided in snippets/layout/head.php
   (data-animate). */
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes fade-out { from { opacity: 1; } to { opacity: 0; } }
/* The dividers grow from the top down; reversed, they shrink back up. */
@keyframes grow-line { from { transform: scaleY(0); } to { transform: scaleY(1); } }

html[data-animate~="list"] [data-animated] .column-list > *,
html[data-animate~="detail"] [data-animated] .column-detail {
  animation: fade-in .5s ease both;
}

/* Fading out before the next view loads: set by assets/js/main.js
   (data-leaving), which waits for it. Keep the duration in sync with
   LEAVE_MS there. */
html[data-leaving~="list"] [data-animated] .column-list > *,
html[data-leaving~="detail"] [data-animated] .column-detail {
  animation: fade-out .25s ease both;
}

/* Missing-count clusters on the calculate page */
.cluster { display: flex; gap: 1rem; }
.cluster + .cluster { margin-top: 1rem; }
.cluster-count { flex-shrink: 0; width: 1.5rem; padding: .25rem .5rem; font-size: 1.125rem; font-weight: 600; }
.cluster-recipes { flex: 1; min-width: 0; }
/* Extra room on the right so the percentages keep clear of the line
   after the list. */
.cluster-recipes .list-item { padding-left: .5rem; padding-right: 1.5rem; }
.coverage { color: var(--dimmed); font-weight: 400; font-size: .875rem; }
.list-item[aria-current] .coverage { color: inherit; }

.coverage-line { margin-bottom: 1rem; color: var(--dimmed); font-size: .875rem; }

/* --- Toolbar: household picker, filters ------------------------------------ */

.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .75rem 2rem;
  margin-bottom: 1.5rem;
}

.household-picker { display: flex; align-items: center; gap: .75rem; margin: 0; }
.household-picker label { font-weight: 600; }

select,
.form input,
.recipe-search input {
  min-height: 2.5rem;
  padding: .375rem 2rem .375rem .75rem;
  border: 1px solid var(--tint-20);
  border-radius: var(--radius);
  background: var(--tint-05);
  transition: border-color .2s, background-color .2s;
}

select {
  appearance: none;
  background-image: var(--select-arrow);
  background-repeat: no-repeat;
  background-position: right .75rem center;
}
select:hover, .form input:hover, .recipe-search input:hover { border-color: var(--tint-40); background-color: var(--tint-10); }
select option { color: #1b1b18; }

/* Recipe search (templates/recipes.php): a field with the search icon
   inside on the left. */
.recipe-search { position: relative; flex: 1; max-width: 26rem; margin: 0; }
.recipe-search input {
  width: 100%;
  padding-left: 2.25rem;
  padding-right: .75rem;
  font-size: 1rem;
  appearance: none;
}
.recipe-search input::placeholder { color: var(--dimmed); opacity: 1; }
.recipe-search input:focus { border-color: var(--tint-40); outline: none; background: var(--tint-10); }
/* The browser's own clear button, as a Lucide "x" in the text color. */
.recipe-search input::-webkit-search-cancel-button {
  -webkit-appearance: none;
  width: 1rem;
  height: 1rem;
  background-color: currentColor;
  -webkit-mask: url('../icons/lucide/x.svg') center / contain no-repeat;
  mask: url('../icons/lucide/x.svg') center / contain no-repeat;
  cursor: pointer;
}
.recipe-search-icon {
  position: absolute;
  top: 50%;
  left: .75rem;
  width: 1rem;
  height: 1rem;
  transform: translateY(-50%);
  pointer-events: none;
  opacity: .8;
}

/* A search result's category, dimmed on the right of its row. */
.list-meta { flex-shrink: 0; color: var(--dimmed); font-size: .875rem; }
.list-item[aria-current] .list-meta { color: inherit; }

.toggle-links { display: flex; gap: 1rem; font-weight: 600; }
.toggle-links a[aria-current] { color: var(--accent); text-decoration: underline; text-underline-offset: 4px; }

.notice { font-size: .875rem; }
.notice a { text-decoration: underline; text-underline-offset: 3px; }

/* --- Recipe ---------------------------------------------------------------- */

.recipe > * + * { margin-top: 1.5rem; }

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

/* Set like the titles on casco.art: normal case, tight lines, and a
   touch of negative tracking at large sizes. */
.recipe-title {
  flex: 1;
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -.01em;
}

@media (min-width: 640px) { .recipe-title { font-size: 2rem; letter-spacing: -.03em; } }

.recipe h3 { font-size: 1.125rem; font-weight: 400; }
/* A heading with a button next to it (Ingredients: + copy). */
.section-header { display: flex; align-items: center; gap: .5rem; }
.recipe-method { margin-top: .5rem; }
.recipe-method p + p { margin-top: .75rem; }

.icon-buttons { display: flex; flex-shrink: 0; gap: .375rem; }

.icon-button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.125rem;
  height: 2.125rem;
  border-radius: 50%;
  font-size: 1rem;
  line-height: 1;
}
.icon-button:hover { background: var(--tint-20); color: inherit; }

/* Lucide icons (snippets/lucide.php) in the round buttons. */
.icon-button svg { width: 1.125rem; height: 1.125rem; }
/* Phones: bigger, easier to tap. */
@media (max-width: 767px) {
  .icon-button { width: 2.75rem; height: 2.75rem; }
  .icon-button svg { width: 1.25rem; height: 1.25rem; }
}
.icon-button .when-copied,
.icon-button.is-copied .when-idle { display: none; }
.icon-button.is-copied .when-copied { display: block; }

.ingredient-lines { margin-top: 1rem; }
.ingredient-lines li { display: flex; align-items: center; gap: .75rem; font-weight: 800; }
.ingredient-lines li + li { margin-top: .5rem; }
.ingredient-name { text-transform: lowercase; }
.ingredient-amount { font-size: .875rem; }
.ingredient-lines .is-in-stock { color: var(--dimmed); font-weight: 500; }
.ingredient-lines .is-missing { color: var(--error); font-weight: 700; }

.dot { width: .75rem; height: .75rem; flex-shrink: 0; border-radius: 50%; }

.recipe-meta { display: grid; gap: 1.5rem; }
.recipe-meta h3 { margin-bottom: .5rem; }

.recipe-photo { margin-top: 3.5rem; }
.recipe-photo img { width: 100%; object-fit: cover; }

@media (min-width: 768px) { .recipe-photo img { width: 40%; } }
@media (min-width: 1024px) { .recipe-photo img { width: 66%; } }

.pill-button {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  margin-top: 1.5rem;
  padding: .25rem 1rem;
  border-radius: var(--radius);
  background: var(--tint-10);
  color: var(--tint-60);
  font-size: .875rem;
  transition: background-color .2s, color .2s;
}
.pill-button:hover { background: var(--tint-20); color: var(--fg); }

/* Single pages (recipe, login, 404) */
.single { max-width: 48rem; }
.single.narrow { max-width: 26rem; }
.single > .recipe-title { margin-bottom: 1rem; }
.back-link { display: inline-block; margin-bottom: 1.5rem; font-weight: 600; text-transform: lowercase; }

/* --- Login form ------------------------------------------------------------ */

.form { display: grid; gap: 1rem; margin-top: 1.5rem; }
.form label { display: grid; gap: .25rem; font-size: .875rem; font-weight: 600; }
.form input { width: 100%; padding-right: .75rem; font-size: 1rem; }
.form input:focus { border-color: var(--tint-40); outline: none; background: var(--tint-10); }
/* Placeholders ("ingredient", "amount", "https://") and dropdowns that
   still show their empty choice ("unit", "pick one") in the dimmed text
   color of the theme, instead of the browser's dark gray. */
.form input::placeholder,
.form textarea::placeholder { color: var(--dimmed); opacity: 1; }
.form select:has(option[value=""]:checked) { color: var(--dimmed); }
.form select option { color: #1b1b18; }
.form .pill-button { justify-self: start; margin-top: .5rem; color: var(--fg); }

.form-links { margin-top: 1.5rem; font-size: .875rem; line-height: 1.8; }
.form-links a, .form-links .link-button { text-decoration: underline; text-underline-offset: 3px; }
/* Sign-up: a field only bots fill in (templates/signup.php). */
.form-trap { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.form-error {
  margin-top: 1rem;
  padding: .5rem .75rem;
  border-radius: var(--radius);
  background: rgba(239, 68, 68, .2);
}

/* --- Submit a recipe (templates/submit.php) ---------------------------------- */

.form select { width: 100%; font-size: 1rem; }
.form textarea {
  width: 100%;
  padding: .5rem .75rem;
  border: 1px solid var(--tint-20);
  border-radius: var(--radius);
  background: var(--tint-05);
  font: inherit;
  font-size: 1rem;
  color: inherit;
  resize: vertical;
  transition: border-color .2s, background-color .2s;
}
.form textarea:hover { border-color: var(--tint-40); background-color: var(--tint-10); }
.form textarea:focus, .form select:focus { border-color: var(--tint-40); outline: none; background-color: var(--tint-10); }
.form input[type="file"] { padding: .375rem .75rem; font-size: .875rem; }
.form input[type="file"]::file-selector-button {
  margin-right: .75rem;
  padding: .25rem .75rem;
  border: 0;
  border-radius: var(--radius);
  background: var(--tint-10);
  color: var(--fg);
  font: inherit;
  cursor: pointer;
}
.form input[type="file"]::file-selector-button:hover { background: var(--tint-20); }
.form fieldset { display: grid; gap: .5rem; min-width: 0; margin: 0; padding: 0; border: 0; }
.form legend { padding: 0; margin-bottom: .25rem; font-size: .875rem; font-weight: 600; }
.form-help { font-size: .875rem; }
.form-notice {
  margin-top: 1rem;
  padding: .5rem .75rem;
  border-radius: var(--radius);
  background: var(--tint-10);
}
.form-error p + p { margin-top: .25rem; }

.form-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; }
@media (min-width: 640px) { .form-row { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

/* Ingredient, amount, unit. */
.ingredient-rows { display: grid; gap: .5rem; }
.ingredient-row { display: grid; grid-template-columns: minmax(0, 1fr) 6rem 7rem; gap: .5rem; }
@media (max-width: 479px) {
  .ingredient-row { grid-template-columns: minmax(0, 1fr) 4.5rem 5.5rem; }
}
/* Under a row with a new ingredient: its category and color. */
.ingredient-new {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem;
  margin-bottom: .5rem;
  padding-left: .75rem;
  border-left: 2px solid var(--tint-40);
}
.ingredient-new[hidden] { display: none; }
.ingredient-new-label { font-size: .875rem; color: var(--dimmed); }
.ingredient-new select { flex: 1; min-width: 7rem; }
.submit-waiting-kind { font-size: .875rem; }
.submit-ingredients .pill-button { margin-top: 0; }
.pill-button svg { width: 1rem; height: 1rem; }

.submit-waiting { margin-top: 3rem; }
.submit-waiting h3 { margin-bottom: .5rem; font-size: 1.125rem; font-weight: 400; }
.submit-waiting li + li { margin-top: .25rem; }

/* "submit a recipe" on the recipes page: floats in the bottom right corner
   (phones: at the bottom of the page, below), styled like the other pill
   buttons. The blur behind it keeps it readable over the list. */
.floating-button {
  position: fixed;
  right: 1.5rem;
  bottom: 1.5rem;
  z-index: 10;
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  padding: .25rem 1rem;
  border-radius: var(--radius);
  background: var(--tint-10);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  color: var(--tint-60);
  font-size: .875rem;
  transition: background-color .2s, color .2s;
}
.floating-button:hover { background: var(--tint-20); color: var(--fg); }
.floating-button svg { width: 1rem; height: 1rem; }
/* Phones: not floating but at the bottom of the page, above the footer. */
@media (max-width: 767px) {
  .floating-button {
    position: static;
    display: flex;
    width: fit-content;
    margin: 2.5rem auto 0;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}

/* --- Inventory ------------------------------------------------------------- */

/* All six categories in one row: sharing the page width on larger
   screens; on narrow ones the row scrolls sideways instead of getting
   unreadably thin columns. */
.inv-grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(6, minmax(9.5rem, 1fr));
  align-items: start;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  padding-bottom: .5rem;
  /* Scrolls sideways without showing a scrollbar. */
  scrollbar-width: none;
}
.inv-grid::-webkit-scrollbar { display: none; }
.inv-card { min-width: 0; scroll-snap-align: start; }

.inv-title {
  display: flex;
  align-items: center;
  gap: .5rem;
  margin-bottom: .75rem;
  font-size: 1.125rem;
  font-weight: 600;
}
.inv-title .icon { width: 1.25rem; height: 1.25rem; transition: transform .2s; }
/* Hovering a column tilts its icon, like the menu icons. */
.inv-card:hover .inv-title .icon { transform: rotate(6deg); }

.inv-stock {
  padding: .875rem;
  border-radius: calc(var(--radius) - 2px);
  background: var(--tint-14);
}

.inv-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
  min-height: 1.5rem;
  font-size: .875rem;
  line-height: 1.25;
}

.inv-name { text-transform: lowercase; }

.inv-toggle {
  position: relative;
  flex-shrink: 0;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  transition: background-color .15s;
}

/* − in the "in stock" list, + in the "add" list; drawn as lines so they
   sit in the middle of the round hover background whatever the font. */
.inv-toggle::before,
.inv-available .inv-toggle::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: .625rem;
  height: 1.5px;
  border-radius: 1px;
  background: currentColor;
  transform: translate(-50%, -50%);
}
.inv-available .inv-toggle::after { transform: translate(-50%, -50%) rotate(90deg); }
.inv-stock .inv-toggle:hover { background: rgba(239, 68, 68, .4); }
.inv-available .inv-toggle:hover { background: rgba(34, 197, 94, .4); }
.inv-item.is-busy { opacity: .5; pointer-events: none; }

/* "..." when the category has nothing in stock */
.inv-empty { display: none; font-size: .875rem; }
.inv-stock:not(:has(.inv-item)) .inv-empty { display: block; }

.inv-open {
  position: relative;
  display: block;
  width: 2rem;
  height: 2rem;
  margin: .75rem auto 0;
  border: 2px solid currentColor;
  border-radius: 50%;
  opacity: .7;
  transition: opacity .2s, transform .2s;
}
.inv-open:hover { opacity: 1; }

/* The plus, drawn as two lines so it's centered in the circle whatever
   the font's own "+" looks like. Turns into a cross when open. */
.inv-open::before,
.inv-open::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: .875rem;
  height: 2px;
  border-radius: 1px;
  background: currentColor;
  transform: translate(-50%, -50%);
}
.inv-open::after { transform: translate(-50%, -50%) rotate(90deg); }
.inv-open[aria-expanded="true"] { transform: rotate(45deg); }

.inv-add { padding: 0 .5rem; }
.inv-add-label { margin: 1rem 0 .75rem; font-size: .875rem; font-weight: 500; }

.inv-colors { display: flex; flex-wrap: wrap; gap: .5rem; }

.inv-color {
  width: 1.25rem;
  height: 1.25rem;
  border-radius: 50%;
  box-shadow: 0 0 0 2px transparent;
  transition: transform .2s, box-shadow .2s;
}
/* The dots pop in one after another each time the add panel opens
   (--i is the dot's position, set in templates/inventory.php). */
.inv-add:not([hidden]) .inv-color {
  animation: inv-pop .3s cubic-bezier(.34, 1.56, .64, 1) both;
  animation-delay: calc(var(--i) * 40ms);
}
/* Uses `scale`, not `transform`, so the hover effect keeps working. */
@keyframes inv-pop {
  from { opacity: 0; scale: .3; }
  to { opacity: 1; scale: 1; }
}
.inv-color:hover { transform: scale(1.25); box-shadow: 0 0 0 2px var(--tint-60); }
.inv-color[aria-pressed="true"] { box-shadow: 0 0 0 2px var(--fg); }

.inv-available { margin-top: 1.25rem; }
.inv-available .inv-item:not(.is-shown) { display: none; }

/* The whole row adds or removes the ingredient (assets/js/inventory.js),
   so hovering it shows the +/− in its hover state. Only rows with a
   button: visitors who can't edit get plain text. */
.inv-item:has(.inv-toggle) { cursor: pointer; }
.inv-available .inv-item:hover .inv-toggle { background: rgba(34, 197, 94, .4); }
.inv-stock .inv-item:hover .inv-toggle { background: rgba(239, 68, 68, .4); }

/* Picking a color fades its ingredients in. */
.inv-available .inv-item.is-shown { animation: fade-in .5s ease both; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}
