/*
 * Design tokens for Pichcio's frontend. Documented in detail in
 * frontend/README.md (palette/spacing/type/iconography/terminology) so a
 * future native app can match this look instead of inventing its own --
 * see docs/FEATURES.md's "Platform & design constraints".
 *
 * Visual language: soft rounded surfaces, gentle shadows instead of hard
 * borders, pill-shaped controls, and small colored icon badges standing in
 * for the photos we don't have -- inspired by justjoin.it/deweloperuch.pl's
 * execution, not their (unrelated-industry) brand colors. The food-warm
 * terracotta/sage palette and the AI-only violet accent are unchanged --
 * see frontend/README.md's "Palette" section.
 *
 * Spacing still reuses Bootstrap's own scale (0/.25/.5/1/1.5/3rem) -- not
 * reinvented -- but radius/shadow/typography are now reconfigured via
 * Bootstrap's own CSS custom properties (see :root below) rather than
 * fighting Bootstrap's defaults component by component.
 */

:root {
  /* Brand palette -- also drives Bootstrap's own --bs-primary so built-in
     components (buttons, links, focus rings) pick it up automatically. */
  --ra-color-primary: #c1440e; /* terracotta -- food/warmth */
  --ra-color-primary-dark: #9a3609;
  --ra-color-primary-light: #fbe9e1; /* soft tint, used behind icon badges */
  --ra-color-accent: #5b7b54; /* sage -- category/tag badges */
  --ra-color-accent-dark: #3e5638; /* accent text on a light tint (contrast) */
  --ra-color-accent-light: #eaf0e8;
  --ra-color-ai: #6f42c1; /* violet -- reserved ONLY for AI-touched surfaces */
  --ra-color-ai-bg: #f3edfb;
  --ra-color-ai-border: #d9c9f2;

  --ra-color-ink: #2a2320; /* body text -- warm near-black, not pure gray */
  --ra-color-muted: #6c645e;
  --ra-color-surface: #ffffff;
  --ra-color-page: #faf7f3;
  --ra-color-border: #ece4da;

  /* Soft, warm-tinted shadows (not flat black) -- the "less crude" part. */
  --ra-shadow-sm: 0 1px 2px rgba(43, 30, 15, 0.06);
  --ra-shadow: 0 6px 20px -6px rgba(43, 30, 15, 0.14);
  --ra-shadow-lg: 0 16px 40px -12px rgba(43, 30, 15, 0.22);

  --ra-font-sans: "Plus Jakarta Sans", -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  /* ---- Bootstrap reconfiguration ----
     Bootstrap 5.3's components (buttons/cards/inputs/modals/...) all read
     their radius/shadow/font from these variables, so overriding them here
     reshapes every built-in component at once instead of overriding each
     component's CSS individually -- the "reconfigure Bootstrap" approach,
     not a parallel design system bolted on top of it. */
  --bs-body-font-family: var(--ra-font-sans);
  --bs-body-color: var(--ra-color-ink);
  --bs-body-bg: var(--ra-color-page);
  --bs-border-color: var(--ra-color-border);
  --bs-border-radius-sm: 0.6rem;
  --bs-border-radius: 0.9rem;
  --bs-border-radius-lg: 1.25rem;
  --bs-border-radius-xl: 1.5rem;
  --bs-box-shadow-sm: var(--ra-shadow-sm);
  --bs-box-shadow: var(--ra-shadow);
  --bs-box-shadow-lg: var(--ra-shadow-lg);

  --bs-primary: var(--ra-color-primary);
  --bs-primary-rgb: 193, 68, 14;
  --bs-link-color: var(--ra-color-primary);
  --bs-link-color-rgb: 193, 68, 14;
  --bs-link-hover-color: var(--ra-color-primary-dark);
}

/* Sticky footer: on a short page (few/no results, the not-found state)
   .site-footer still sits at the bottom of the viewport instead of
   floating awkwardly high up right under the content -- on a normal
   (tall) page this has no visible effect, it's just normal document flow. */
html,
body {
  height: 100%;
}

body {
  display: flex;
  flex-direction: column;
  background-color: var(--ra-color-page);
}

main {
  flex: 1 0 auto;
}

.site-footer {
  flex-shrink: 0;
  margin-top: 3rem;
  border-top: 1px solid var(--ra-color-border);
  background-color: var(--ra-color-surface);
}

.site-footer-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 700;
  color: var(--ra-color-ink);
}

.site-footer-brand .bi {
  color: var(--ra-color-primary);
}

.site-footer a {
  color: var(--ra-color-muted);
}

.site-footer a:hover {
  color: var(--ra-color-primary);
}

/* Bootstrap 5.3's .btn-primary/.btn-outline-primary bake their own
   per-component --bs-btn-* variables at compile time (hardcoded to
   Bootstrap's blue) rather than reading the global --bs-primary this
   file sets above -- overriding --bs-primary alone reskins utilities like
   .text-primary/focus rings but silently leaves every primary BUTTON blue.
   Re-pointing those component-scoped variables here is the documented
   Bootstrap 5.3 way to reskin a component via CSS custom properties
   without recompiling its Sass. */
.btn-primary {
  --bs-btn-bg: var(--ra-color-primary);
  --bs-btn-border-color: var(--ra-color-primary);
  --bs-btn-hover-bg: var(--ra-color-primary-dark);
  --bs-btn-hover-border-color: var(--ra-color-primary-dark);
  --bs-btn-active-bg: var(--ra-color-primary-dark);
  --bs-btn-active-border-color: var(--ra-color-primary-dark);
  --bs-btn-disabled-bg: var(--ra-color-primary);
  --bs-btn-disabled-border-color: var(--ra-color-primary);
  --bs-btn-focus-shadow-rgb: 193, 68, 14;
}

.btn-outline-primary {
  --bs-btn-color: var(--ra-color-primary);
  --bs-btn-border-color: var(--ra-color-primary);
  --bs-btn-hover-bg: var(--ra-color-primary);
  --bs-btn-hover-border-color: var(--ra-color-primary);
  --bs-btn-active-bg: var(--ra-color-primary);
  --bs-btn-active-border-color: var(--ra-color-primary);
  --bs-btn-disabled-color: var(--ra-color-primary);
  --bs-btn-disabled-border-color: var(--ra-color-primary);
  --bs-btn-focus-shadow-rgb: 193, 68, 14;
}

h1,
h2,
h3,
.navbar-brand {
  font-weight: 700;
  letter-spacing: -0.01em;
}

/* ---- Navbar ---- */

.navbar {
  backdrop-filter: saturate(180%) blur(6px);
  background-color: rgba(255, 255, 255, 0.92) !important;
}

.navbar-brand {
  font-size: 1.15rem;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

.brand-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.1rem;
  height: 2.1rem;
  border-radius: 50%;
  background: var(--ra-color-primary-light);
  color: var(--ra-color-primary);
  font-size: 1.05rem;
}

/* ---- Account control in the navbar (js/navbar.js) and login.html ---- */

#navbar-account:empty {
  display: none;
}

.account-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  max-width: 100%;
  background: var(--ra-color-primary-light);
  color: var(--ra-color-primary-dark);
  border: 1px solid transparent;
}

.account-toggle:hover,
.account-toggle:focus-visible,
.account-toggle.show {
  background: var(--ra-color-primary-light);
  color: var(--ra-color-primary-dark);
  border-color: var(--ra-color-primary);
}

/* The address is the only part that can be long: truncated, narrower on a
   phone, where the brand shares the row. */
.account-email {
  max-width: 7rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (min-width: 576px) {
  .account-email {
    max-width: 16rem;
  }
}

.account-menu {
  max-width: min(20rem, calc(100vw - 2rem));
}

.account-email-full {
  overflow-wrap: anywhere;
}

.auth-card {
  border: none;
  box-shadow: var(--ra-shadow);
}

/* The heading takes focus when the view changes (js/login.js), so a screen
   reader reads where it landed; a ring around a heading is only noise. */
.auth-card h1:focus {
  outline: none;
}

/* The second password field while it differs from the first (js/login.js
   sets aria-invalid): the field itself says so, not only the text under it. */
.form-control[aria-invalid="true"] {
  border-color: var(--bs-danger);
}

.auth-links .btn-link {
  font-size: 0.9rem;
  text-decoration: none;
}

.auth-links .btn-link:hover {
  text-decoration: underline;
}

.password-rules {
  color: var(--ra-color-muted);
}

.password-rule i {
  margin-right: 0.15rem;
}

.password-rule.is-met,
.password-rule-parts .is-met {
  color: var(--ra-color-accent-dark);
}

/* ---- Search bar -- a pill-shaped, icon-led control (justjoin.it/
   deweloperuch.pl's segmented search bars) instead of a plain
   Bootstrap input-group. ---- */

/* .search-bar is just a layout container (icon+input pill, then the
   submit button); the pill's actual chrome -- background/border/shadow --
   lives on the inner .search-bar-field so it wraps only the icon+input,
   never the button (see the `md`-and-down override below, where the
   button needs to render as a fully separate element, not a second row
   inside the same bordered box). Above `md` they're visually equivalent to
   one merged pill (button included) since .search-bar-field carries no
   chrome of its own there. */
.search-bar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  background: var(--ra-color-surface);
  border: 1px solid var(--ra-color-border);
  border-radius: 50rem;
  padding: 0.35rem 0.35rem 0.35rem 1.25rem;
  box-shadow: var(--ra-shadow-sm);
  transition: box-shadow 0.15s ease-in-out;
}

.search-bar:focus-within {
  box-shadow: var(--ra-shadow);
  border-color: var(--ra-color-primary);
}

.search-bar-field {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: 1;
  min-width: 0;
}

.search-bar-icon {
  color: var(--ra-color-primary);
  font-size: 1.1rem;
  flex-shrink: 0;
}

.search-bar-input {
  position: relative;
  z-index: 1;
  border: none;
  outline: none;
  background: transparent;
  flex: 1;
  min-width: 0;
  width: 100%;
  font-size: 1rem;
  padding: 0.6rem 0.25rem;
  color: var(--ra-color-ink);
}

.search-bar-input:focus {
  box-shadow: none;
}

/* Below Bootstrap's `md` breakpoint the icon+input pill and the submit
   button don't fit on one row without squeezing the input down to a
   sliver -- on index.html that also clips the animated placeholder text
   (see .search-placeholder below) down to almost nothing. Stack the
   button under the input instead, and move the pill's chrome from
   .search-bar onto .search-bar-field so the button renders as its own
   separate element below the pill, not a second row sharing its border/
   background. Applies to both reuses of .search-bar -- index.html's
   search bar and recipe.html's .chat-input-bar. `md` (not `sm`) to match
   index.html's own #results-grid, which collapses from two columns to one
   at the same breakpoint (`row-cols-md-2`) -- the search bar and the
   results below it go single-column together, one Bootstrap step. */
@media (max-width: 767.98px) {
  .search-bar {
    flex-direction: column;
    align-items: stretch;
    background: transparent;
    border: none;
    border-radius: 0;
    padding: 0;
    box-shadow: none;
  }

  .search-bar:focus-within {
    box-shadow: none;
    border-color: transparent;
  }

  .search-bar-field {
    background: var(--ra-color-surface);
    border: 1px solid var(--ra-color-border);
    border-radius: 50rem;
    padding: 0.35rem 0.35rem 0.35rem 1.25rem;
    box-shadow: var(--ra-shadow-sm);
    transition: box-shadow 0.15s ease-in-out;
  }

  .search-bar-field:focus-within {
    box-shadow: var(--ra-shadow);
    border-color: var(--ra-color-primary);
  }

  .search-bar > button[type="submit"] {
    width: 100%;
  }

  /* Mirrors the no-icon left-padding trim below (.search-bar.chat-input-bar)
     for the mobile layout, where the pill's padding lives on
     .search-bar-field instead of .search-bar. */
  .chat-input-bar .search-bar-field {
    padding-left: 1rem;
  }
}

/* Wraps #q-input (index.html's search only -- not the chat input, which
   reuses .search-bar/.search-bar-input but keeps a plain native
   placeholder) so the animated placeholder overlay below can be
   absolutely positioned right on top of it. */
.search-input-wrap {
  position: relative;
  flex: 1;
  min-width: 0;
}

/* The animated placeholder itself -- see index.html's #search-placeholder
   comment. Sits behind the real input (z-index 0 vs. 1) and is hidden via
   .d-none once there's a value, so it never visually collides with what
   the user actually typed. */
.search-placeholder {
  position: absolute;
  inset: 0;
  z-index: 0;
  display: flex;
  align-items: center;
  gap: 0.3em;
  padding: 0.6rem 0.25rem;
  font-size: 1rem;
  color: var(--ra-color-muted);
  white-space: nowrap;
  pointer-events: none;
}

/* Fixed-height window showing exactly one example line at a time --
   .search-placeholder-track is taller (one line per example, see
   js/search.js) and slides vertically inside it. */
.search-placeholder-rotator {
  position: relative;
  height: 1.3em;
  overflow: hidden;
  flex: 1;
  min-width: 0;
}

.search-placeholder-track {
  display: flex;
  flex-direction: column;
  /* js/search.js only ever sets --placeholder-step (a plain integer via
     CSS.registerProperty-free setProperty) -- the 1.3em line height stays
     defined in exactly one place (the span rule below), not duplicated as
     a pixel value recomputed in JS. */
  --placeholder-step: 0;
  transform: translateY(calc(var(--placeholder-step) * -1.3em));
  transition: transform 0.45s cubic-bezier(0.65, 0, 0.35, 1);
}

.search-placeholder-track span {
  height: 1.3em;
  line-height: 1.3em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---- Filters panel ---- */

.filters-panel {
  background: var(--ra-color-surface);
  border: 1px solid var(--ra-color-border);
  border-radius: var(--bs-border-radius-lg);
  box-shadow: var(--ra-shadow-sm);
  padding: 1.25rem;
}

.filters-toggle-btn {
  border: 1px solid var(--ra-color-border);
  background: var(--ra-color-surface);
  color: var(--ra-color-ink);
  font-weight: 600;
}

.filters-toggle-btn:hover {
  border-color: var(--ra-color-primary);
  color: var(--ra-color-primary);
}

/* Tag filter chips -- Bootstrap's .btn-check + label pattern (a checkbox
   visually presented as a toggle button) restyled as small pill chips,
   rather than hand-rolled checkbox+label CSS. */
.tag-chip-btn {
  border: 1px solid var(--ra-color-border);
  background: var(--ra-color-surface);
  color: var(--ra-color-muted);
  border-radius: 50rem;
  padding: 0.3rem 0.85rem;
  font-size: 0.85rem;
  font-weight: 500;
}

.tag-chip-btn:hover {
  border-color: var(--ra-color-accent);
  color: var(--ra-color-accent-dark);
}

.btn-check:checked + .tag-chip-btn {
  background: var(--ra-color-accent);
  border-color: var(--ra-color-accent);
  color: #fff;
}

.btn-check:focus-visible + .tag-chip-btn {
  outline: 2px solid var(--ra-color-accent);
  outline-offset: 2px;
}

/* ---- Result / similar-recipe cards ---- */

/* A recipe-card's title is a Bootstrap .stretched-link covering the whole
   card (see .recipe-card-link below) -- anything else inside the card that
   needs its own click target (the category label, the source link) sits
   above that overlay via this one shared class, instead of each one
   hand-copying `position: relative; z-index: 2;` inline. */
.above-stretched-link {
  position: relative;
  z-index: 2;
}

.recipe-card {
  border: 1px solid var(--ra-color-border);
  box-shadow: var(--ra-shadow-sm);
  transition:
    box-shadow 0.18s ease-in-out,
    transform 0.18s ease-in-out;
}

.recipe-card:hover {
  box-shadow: var(--ra-shadow);
  transform: translateY(-3px);
}

.recipe-card-link {
  color: inherit;
  text-decoration: none;
}

.recipe-card-link:hover {
  color: var(--ra-color-primary);
}

/* Small colored icon badge standing in for the photo we don't have (see
   render.js's renderCategoryBadge / backend/schemas.py's "No photo" note).
   Shares its background with .active-filter-chip--category and its text
   color with .category-label below (one declaration each, not copied) so
   the "category" identity color pair can't drift out of sync between the
   card badge, the detail-page badge, and the active-filters chip. */
.category-icon,
.active-filter-chip--category {
  background-color: var(--ra-color-primary-light);
}

.category-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 50%;
  font-size: 1.15rem;
  flex-shrink: 0;
}

.category-label,
.active-filter-chip--category {
  color: var(--ra-color-primary-dark);
}

.category-label {
  font-weight: 600;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  text-decoration: none;
}

.category-label:hover {
  color: var(--ra-color-primary);
  text-decoration: underline;
}

/* Shared with .active-filter-chip--tag below (one declaration, not
   copied) so the "tag" identity color pair can't drift out of sync
   between a card's tags and the active-filters chip for the same tag. */
.tag-chip,
.active-filter-chip--tag {
  background-color: var(--ra-color-accent-light);
  color: var(--ra-color-accent-dark);
}

.tag-chip {
  display: inline-block;
  font-weight: 500;
  font-size: 0.78rem;
  border-radius: 50rem;
  padding: 0.3rem 0.7rem;
  margin: 0 0.35rem 0.35rem 0;
}

/* ---- Active-filter chips (search page) -- summarize category/tags above
   the results regardless of whether "Filtry" is collapsed; color-matched
   to the same category (primary) / tag (accent) colors used elsewhere so
   a chip's meaning is recognizable at a glance, not just by its label. ---- */

.active-filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  border-radius: 50rem;
  padding: 0.3rem 0.4rem 0.3rem 0.85rem;
  font-size: 0.82rem;
  font-weight: 500;
}

.active-filter-remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.2rem;
  height: 1.2rem;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: inherit;
  padding: 0;
  line-height: 1;
  opacity: 0.75;
}

.active-filter-remove:hover,
.active-filter-remove:focus-visible {
  opacity: 1;
  background-color: rgba(0, 0, 0, 0.1);
}

.time-line {
  color: var(--ra-color-muted);
}

.time-line .bi {
  color: var(--ra-color-primary);
}

/* Source attribution -- must stay visually present, never disguised as a
   throwaway detail (copyright requirement, see docs/FEATURES.md). Sits
   above card links via z-index since the title itself is a stretched-link. */
.source-link {
  color: var(--ra-color-muted);
  text-decoration: none;
  font-weight: 500;
}

.source-link:hover {
  color: var(--ra-color-primary);
  text-decoration: underline;
}

.source-link--badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  background: var(--ra-color-page);
  border: 1px solid var(--ra-color-border);
  border-radius: 50rem;
  padding: 0.45rem 1rem;
}

/* ---- AI-touched surfaces: ambient summary, Ask-AI panel, chat ----
   Every AI-generated or AI-triggering element uses this one accent color,
   consistently, so it's always visually distinguishable from plain data
   (reinforces the opt-in dial itself -- see frontend/README.md). */

.ai-summary {
  background-color: var(--ra-color-ai-bg);
  border: 1px solid var(--ra-color-ai-border);
  border-radius: var(--bs-border-radius-lg);
  color: #3d2a5c;
  padding: 1rem 1.25rem;
  box-shadow: var(--ra-shadow-sm);
}

.ai-summary-icon,
.chat-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: #fff;
  color: var(--ra-color-ai);
  flex-shrink: 0;
}

.ai-panel-toggle {
  color: var(--ra-color-ai);
  border: 1px solid var(--ra-color-ai-border);
  background-color: var(--ra-color-ai-bg);
  font-weight: 600;
  box-shadow: var(--ra-shadow-sm);
}

.ai-panel-toggle:hover,
.ai-panel-toggle:focus {
  color: #fff;
  background-color: var(--ra-color-ai);
  border-color: var(--ra-color-ai);
}

.ai-panel-body {
  background: var(--ra-color-surface);
  border: 1px solid var(--ra-color-ai-border);
  box-shadow: var(--ra-shadow-sm);
}

.suggested-prompt {
  border: 1px solid var(--ra-color-ai-border);
  color: var(--ra-color-ai);
  background-color: #fff;
  font-weight: 500;
}

.suggested-prompt:hover {
  background-color: var(--ra-color-ai);
  border-color: var(--ra-color-ai);
  color: #fff;
}

.suggested-prompt:disabled {
  opacity: 0.5;
}

/* ---- Chat ---- */

.chat-thread {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  max-height: 24rem;
  overflow-y: auto;
  padding: 0.25rem;
}

.chat-message {
  display: flex;
  align-items: flex-end;
  gap: 0.5rem;
}

.chat-message--user {
  justify-content: flex-end;
}

.chat-message--assistant {
  justify-content: flex-start;
}

.chat-bubble {
  max-width: 80%;
  padding: 0.65rem 1rem;
  border-radius: 1.1rem;
  white-space: pre-wrap;
  box-shadow: var(--ra-shadow-sm);
}

.chat-message--user .chat-bubble {
  background-color: var(--ra-color-primary);
  color: #fff;
  border-bottom-right-radius: 0.25rem;
}

.chat-message--assistant .chat-bubble {
  background-color: var(--ra-color-ai-bg);
  border: 1px solid var(--ra-color-ai-border);
  color: #3d2a5c;
  border-bottom-left-radius: 0.25rem;
}

.chat-message--pending .chat-bubble {
  color: #6c757d;
  font-style: italic;
  box-shadow: none;
}

/* `md`-and-up only (matches the mobile override above) -- below that,
   .search-bar carries no padding of its own and the equivalent no-icon
   left-padding trim is applied to .search-bar-field instead
   (.chat-input-bar .search-bar-field), which needs an unconditional rule
   of equal specificity here to not win the cascade on mobile too. */
@media (min-width: 768px) {
  .search-bar.chat-input-bar {
    padding-left: 1rem;
  }
}

/* ---- Empty / not-found states ---- */

.empty-state-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 4rem;
  height: 4rem;
  border-radius: 50%;
  background: var(--ra-color-primary-light);
  color: var(--ra-color-primary);
  font-size: 1.6rem;
}

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

.recipe-title {
  font-size: clamp(1.75rem, 1.4rem + 1.5vw, 2.5rem);
  font-weight: 800;
  letter-spacing: -0.02em;
}

.recipe-section {
  background: var(--ra-color-surface);
  border: 1px solid var(--ra-color-border);
  border-radius: var(--bs-border-radius-lg);
  box-shadow: var(--ra-shadow-sm);
  padding: 1.5rem;
}

.ingredient-list {
  list-style: none;
  padding-left: 0;
  margin-bottom: 0;
}

.ingredient-list li {
  position: relative;
  padding-left: 1.5rem;
  padding-bottom: 0.5rem;
}

.ingredient-list li::before {
  content: "";
  position: absolute;
  left: 0.15rem;
  top: 0.5rem;
  width: 0.45rem;
  height: 0.45rem;
  border-radius: 50%;
  background: var(--ra-color-accent);
}

.instruction-text {
  white-space: pre-wrap;
  line-height: 1.7;
}
